| skipped 142 lines |
143 | 143 | | creator.createTypes(self.standardTypes) |
144 | 144 | | creator.createTypes(self.commonTypes) |
145 | 145 | | |
| 146 | + | class Go117Types(GoTypes_BASE): |
| 147 | + | def __init__(self, creator): |
| 148 | + | super(Go117Types, self).__init__(creator) |
| 149 | + | self.standardTypes = [ |
| 150 | + | ("type", [ |
| 151 | + | ("size", "uintptr"), |
| 152 | + | ("ptrdata", "uintptr"), |
| 153 | + | ("hash", "__int32"), |
| 154 | + | ("flag", "__int8"), |
| 155 | + | ("align", "__int8"), |
| 156 | + | ("fieldAlign", "__int8"), |
| 157 | + | ("kind", "kind"), |
| 158 | + | ("equal", "*void"), |
| 159 | + | ("gcdata", "*unsigned char"), |
| 160 | + | ("string", "baseptr"), |
| 161 | + | ("ptrtothis", "baseptr"), |
| 162 | + | ]) |
| 163 | + | ] |
| 164 | + | |
| 165 | + | #this types depends on type structure so should be created after |
| 166 | + | self.commonTypes += [ |
| 167 | + | ("uncommonType", [("pkgPath", "__int32"), ("mcount", "__int16"), ("unused1", "__int16"),("moff", "__int32"), ("unused2", "__int16")]), |
| 168 | + | ("method__", [("name", "__int32"), ("mtyp", "__int32"),("ifn","__int32"), ("tfn", "__int32")]), |
| 169 | + | ("structField",[ |
| 170 | + | ("Name", "void *"), |
| 171 | + | ("typ", "*type"), |
| 172 | + | ("offset", "uintptr"), |
| 173 | + | ]), |
| 174 | + | ("structType", [ |
| 175 | + | ("type","type"), |
| 176 | + | ("pkgPath", "void *"), |
| 177 | + | ("fields", "slice") |
| 178 | + | ]), |
| 179 | + | ("imethod", [ |
| 180 | + | ("name", "baseptr"), |
| 181 | + | ("pkgPath", "baseptr"), |
| 182 | + | ]), |
| 183 | + | ("interfaceType",[ |
| 184 | + | ("type", "type"), |
| 185 | + | ("pkgPath", "void *"), |
| 186 | + | ("methods", "slice") |
| 187 | + | ]), |
| 188 | + | ("funcType", [ |
| 189 | + | ("type", "type"), |
| 190 | + | ("incount","__int16"), |
| 191 | + | ("outcount", "__int16") |
| 192 | + | ]), |
| 193 | + | ("mapType", [ |
| 194 | + | ("type", "type"), |
| 195 | + | ("key","*type"), |
| 196 | + | ("elem","*type"), |
| 197 | + | ("bucket", "*type"), |
| 198 | + | ("hasher", "void *"), |
| 199 | + | ("keysize","__int8"), |
| 200 | + | ("elemsize","__int8"), |
| 201 | + | ("bucketsize","__int16"), |
| 202 | + | ("flags","__int32"), |
| 203 | + | ]) |
| 204 | + | ] |
| 205 | + | |
| 206 | + | creator.createTypes(self.standardTypes) |
| 207 | + | creator.createTypes(self.commonTypes) |
| 208 | + | self.creator = creator |
| 209 | + | |
| 210 | + | def update_robase(self, robase): |
| 211 | + | self.creator.configBase(robase) |
| 212 | + | |
146 | 213 | | class Go17Types(GoTypes_BASE): |
147 | 214 | | def __init__(self, creator): |
148 | 215 | | super(Go17Types, self).__init__(creator) |
| skipped 304 lines |
453 | 520 | | for i in range(size): |
454 | 521 | | self.processStructField(addr, i*sz) |
455 | 522 | | name = self.getName(offset) |
| 523 | + | while name[0] == "*": |
| 524 | + | name = name[1:] |
456 | 525 | | name = Utils.relaxName(name) |
| 526 | + | print('Continue parsing of {:x}'.format(offset)) |
457 | 527 | | name = "ut_" + name |
458 | 528 | | self.createUserTypeStruct(addr, name, size, size_new_struct) |
459 | 529 | | |
| skipped 235 lines |
695 | 765 | | class TypeProcessing116(TypeProcessing19): |
696 | 766 | | |
697 | 767 | | def __init__(self, pos, endpos, step, settings, base_type): |
698 | | - | super(TypeProcessing19, self).__init__(pos, endpos, step, settings, base_type) |
| 768 | + | super(TypeProcessing116, self).__init__(pos, endpos, step, settings, base_type) |
699 | 769 | | self.robase = base_type |
700 | 770 | | |
701 | 771 | | def getStructFieldOffset(self, sid, addr): |
| skipped 8 lines |
710 | 780 | | self.handle_offset(addr) |
711 | 781 | | addr = self.getPtr(sid, offset, "bucket") |
712 | 782 | | self.handle_offset(addr) |
| 783 | + | |
| 784 | + | class TypeProcessing117(TypeProcessing116): |
| 785 | + | def __init__(self, pos, endpos, step, settings, base_type): |
| 786 | + | super(TypeProcessing117, self).__init__(pos, endpos, step, settings, base_type) |
| 787 | + | self.robase = base_type |
| 788 | + | self.basetypes = dict() |
| 789 | + | self.basetypes['BOOL'] = 'unsigned __int8' |
| 790 | + | self.basetypes['UINT8'] = 'unsigned __int8' |
| 791 | + | self.basetypes['INT8'] = 'signed __int8' |
| 792 | + | self.basetypes['UINT16'] = 'unsigned __int16' |
| 793 | + | self.basetypes['INT16'] = 'signed __int16' |
| 794 | + | self.basetypes['UINT32'] = 'unsigned __int32' |
| 795 | + | self.basetypes['INT32'] = 'signed __int32' |
| 796 | + | self.basetypes['UINT64'] = 'unsigned __int64' |
| 797 | + | self.basetypes['INT64'] = 'signed __int64' |
| 798 | + | self.basetypes['UINT'] = 'unsigned __int64' |
| 799 | + | self.basetypes['INT'] = 'signed __int64' |
| 800 | + | self.basetypes['UINTPTR'] = 'unsigned __int64 *' |
| 801 | + | self.basetypes['FLOAT32'] = 'float' |
| 802 | + | self.basetypes['FLOAT64'] = 'double' |
| 803 | + | |
| 804 | + | def get_str_from_struct(self, ea): |
| 805 | + | str_sz = idc.get_wide_byte(ea+1) |
| 806 | + | str_ea = ea + 2 |
| 807 | + | |
| 808 | + | sz, ea = self.get_str_sz(ea) |
| 809 | + | return self.get_str(ea, sz) |
| 810 | + | |
| 811 | + | @staticmethod |
| 812 | + | def get_str_sz(ea): |
| 813 | + | print('getting str for {:x}'.format(ea)) |
| 814 | + | ea += 1 |
| 815 | + | c = idc.get_wide_byte(ea) |
| 816 | + | ea += 1 |
| 817 | + | numbits = 0 |
| 818 | + | sz = c & 0x7f |
| 819 | + | numbits += 7 |
| 820 | + | while c & 0x80: |
| 821 | + | c = idc.get_wide_byte(ea) |
| 822 | + | ea += 1 |
| 823 | + | sz |= (c & 0x7f) << numbits |
| 824 | + | numbits += 7 |
| 825 | + | |
| 826 | + | return sz, ea |
| 827 | + | return self.get_str(ea, sz) |
| 828 | + | |
| 829 | + | |
| 830 | + | def makeMap(self, offset): |
| 831 | + | idc.SetType(offset, "mapType") |
| 832 | + | sid = ida_struct.get_struc_id("mapType") |
| 833 | + | addr = self.getPtr(sid, offset, "key") |
| 834 | + | self.handle_offset(addr) |
| 835 | + | addr = self.getPtr(sid, offset, "elem") |
| 836 | + | self.handle_offset(addr) |
| 837 | + | addr = self.getPtr(sid, offset, "bucket") |
| 838 | + | self.handle_offset(addr) |
| 839 | + | |
| 840 | + | def processStructField(self, addr, index): |
| 841 | + | offset = addr + index |
| 842 | + | sid = ida_struct.get_struc_id("structField") |
| 843 | + | ptr = self.getPtr(sid, offset, "Name") |
| 844 | + | ln = idc.get_wide_byte(ptr + 1) |
| 845 | + | fieldName = self.get_str(ptr + 2, ln) |
| 846 | + | Utils.rename(ptr, fieldName) |
| 847 | + | ptr = self.getPtr(sid, offset, "typ") |
| 848 | + | self.handle_offset(ptr) |
| 849 | + | |
| 850 | + | def nameFromOffset(self, offset): |
| 851 | + | return self.get_str_from_struct(offset) |
| 852 | + | |
| 853 | + | def getName(self, offset): |
| 854 | + | sid = ida_struct.get_struc_id("type") |
| 855 | + | name_off = self.getDword(sid, offset, "string") |
| 856 | + | string_addr = self.getOffset(name_off) |
| 857 | + | return self.get_str_from_struct(string_addr) |
| 858 | + | |
| 859 | + | def processIMethod(self, offst): |
| 860 | + | sid = ida_struct.get_struc_id("imethod") |
| 861 | + | name = self.getDword(sid, offst, "name") |
| 862 | + | name += self.robase |
| 863 | + | return self.get_str_from_struct(name) |
| 864 | + | |
| 865 | + | def makeInterface(self, offset): |
| 866 | + | print('creating interface {:x}'.format(offset)) |
| 867 | + | idc.SetType(offset, "interfaceType") |
| 868 | + | ifaceid = ida_struct.get_struc_id("interfaceType") |
| 869 | + | meth_offs = idc.get_member_offset(ifaceid, "methods") |
| 870 | + | slice_id = ida_struct.get_struc_id("slice") |
| 871 | + | size_off = idc.get_member_offset(slice_id, "len") |
| 872 | + | size = self.stepper.ptr(offset + meth_offs + size_off) |
| 873 | + | |
| 874 | + | name = self.getName(offset) |
| 875 | + | while name[0] == "*": |
| 876 | + | name = name[1:] |
| 877 | + | name = Utils.relaxName(name) |
| 878 | + | itab_name = "itab_" + name |
| 879 | + | iface_name = 'iface_' + name |
| 880 | + | |
| 881 | + | names = [] |
| 882 | + | if size > 0: |
| 883 | + | addr = self.getPtr(slice_id, offset + meth_offs, "data") |
| 884 | + | idc.SetType(addr, "imethod") |
| 885 | + | sz = ida_struct.get_struc_size(ida_struct.get_struc_id("imethod")) |
| 886 | + | self.make_arr(addr, size, sz, "imethod") |
| 887 | + | names = self.processIMethods(addr, size) |
| 888 | + | if names is None: |
| 889 | + | return |
| 890 | + | |
| 891 | + | # Reference - #https://github.com/teh-cmc/go-internals/blob/master/chapter2_interfaces/README.md#anatomy-of-an-interface |
| 892 | + | itab_fields = [("inter", "void *"), ("type", "void *"), ("hash", "__int32"), |
| 893 | + | ("unused", "__int32")] |
| 894 | + | for i in names: |
| 895 | + | itab_fields.append((i, "void *")) |
| 896 | + | |
| 897 | + | itype = [(itab_name, itab_fields)] |
| 898 | + | self.settings.structCreator.createTypes(itype) |
| 899 | + | iface_fields = [('tab', f'{itab_name} *'), ('data', 'void *')] |
| 900 | + | itype = [(iface_name, iface_fields)] |
| 901 | + | self.settings.structCreator.createTypes(itype) |
| 902 | + | |
| 903 | + | |
| 904 | + | def createUserTypeStruct(self, addr, name, size, self_size): |
| 905 | + | print('creating struct {}'.format(name)) |
| 906 | + | fields = [] |
| 907 | + | sid = ida_struct.get_struc_id("structField") |
| 908 | + | sz = ida_struct.get_struc_size(sid) |
| 909 | + | sid_type = ida_struct.get_struc_id("type") |
| 910 | + | fields = [] |
| 911 | + | curr_offset = 0 |
| 912 | + | idc.set_cmt(addr, name, 0) |
| 913 | + | for i in range(size): |
| 914 | + | print('field in {:x}'.format(addr+i*sz)) |
| 915 | + | fieldname = self.nameFromOffset(self.getPtr(sid, addr+i*sz,"Name")) |
| 916 | + | type_addr = self.getPtr(sid, addr+i*sz, "typ") |
| 917 | + | typename = self.getType(type_addr) |
| 918 | + | size = self.getPtr(sid_type, type_addr, "size") |
| 919 | + | if fieldname == "" or fieldname is None: |
| 920 | + | fieldname = "unused_"+Utils.id_generator() |
| 921 | + | offset = self.getStructFieldOffset(sid, addr+i*sz) |
| 922 | + | print(f"Get offset: {offset:x}") |
| 923 | + | if offset != curr_offset: |
| 924 | + | print("Offset missmatch.Got %d expected %d. Adding padding..." % (curr_offset, offset)) |
| 925 | + | if offset < curr_offset: |
| 926 | + | raise("Too many bytes already") |
| 927 | + | while offset != curr_offset: |
| 928 | + | fields.append(("padding", "char")) |
| 929 | + | curr_offset += 1 |
| 930 | + | curr_offset += size |
| 931 | + | print('fieldname = {}'.format(fieldname)) |
| 932 | + | if size != 0: |
| 933 | + | fieldtype = None |
| 934 | + | offset_kind = idc.get_member_offset(sid_type, "kind") |
| 935 | + | kind_of_type = self.getKindEnumName(type_addr) |
| 936 | + | print(kind_of_type) |
| 937 | + | if kind_of_type == "STRUCT": |
| 938 | + | name_type = self.getName(type_addr) |
| 939 | + | while name_type[0] == "*": |
| 940 | + | name_type = name_type[1:] |
| 941 | + | name_type = Utils.relaxName(name_type) |
| 942 | + | name_type = "ut_" + name_type |
| 943 | + | |
| 944 | + | if ida_struct.get_struc_id(name_type) != idc.BADADDR: |
| 945 | + | print("setting type %s" % name_type) |
| 946 | + | fieldtype = name_type |
| 947 | + | |
| 948 | + | elif kind_of_type == "STRING": |
| 949 | + | fieldtype = "string" |
| 950 | + | |
| 951 | + | elif kind_of_type == "SLICE": |
| 952 | + | fieldtype = "slice" |
| 953 | + | |
| 954 | + | elif kind_of_type == "INTERFACE": |
| 955 | + | name_type = self.getName(type_addr) |
| 956 | + | while name_type[0] == "*": |
| 957 | + | name_type = name_type[1:] |
| 958 | + | name_type = Utils.relaxName(name_type) |
| 959 | + | name_type = "iface_" + name_type |
| 960 | + | |
| 961 | + | if ida_struct.get_struc_id(name_type) != idc.BADADDR: |
| 962 | + | fieldtype = name_type |
| 963 | + | |
| 964 | + | elif kind_of_type == "CHAN": |
| 965 | + | name_type = 'ut_runtime_hchan' |
| 966 | + | ptr_name_type = f'{name_type} *' |
| 967 | + | |
| 968 | + | if ida_struct.get_struc_id(name_type) != idc.BADADDR: |
| 969 | + | fieldtype = ptr_name_type |
| 970 | + | |
| 971 | + | elif kind_of_type == "MAP": |
| 972 | + | name_type = 'ut_runtime_hmap' |
| 973 | + | ptr_name_type = f'{name_type} *' |
| 974 | + | if ida_struct.get_struc_id(name_type) != idc.BADADDR: |
| 975 | + | fieldtype = ptr_name_type |
| 976 | + | |
| 977 | + | elif kind_of_type == "FUNC": |
| 978 | + | fieldtype = 'void *' |
| 979 | + | |
| 980 | + | elif kind_of_type == "PTR": |
| 981 | + | name_type = self.getName(type_addr) |
| 982 | + | while name_type[0] == "*": |
| 983 | + | name_type = name_type[1:] |
| 984 | + | name_type = Utils.relaxName(name_type) |
| 985 | + | name_type = "ut_" + name_type |
| 986 | + | ptr_name_type = f'{name_type} *' |
| 987 | + | |
| 988 | + | if ida_struct.get_struc_id(name_type) != idc.BADADDR: |
| 989 | + | print("setting ptr type %s" % name_type) |
| 990 | + | fieldtype = ptr_name_type |
| 991 | + | |
| 992 | + | elif kind_of_type in self.basetypes: |
| 993 | + | fieldtype = self.basetypes[kind_of_type] |
| 994 | + | |
| 995 | + | if fieldtype is None: |
| 996 | + | if size == 1: |
| 997 | + | fieldtype = 'char' |
| 998 | + | else: |
| 999 | + | fieldtype = "char [%d]" % size |
| 1000 | + | |
| 1001 | + | fields.append((fieldname, fieldtype)) |
| 1002 | + | |
| 1003 | + | if curr_offset != self_size: |
| 1004 | + | print("%x: Structure size mismatch: %x" % (addr, curr_offset)) |
| 1005 | + | if self_size < curr_offset: |
| 1006 | + | raise("Too many bytes already") |
| 1007 | + | while self_size != curr_offset: |
| 1008 | + | fields.append(("padding", "char")) |
| 1009 | + | curr_offset += 1 |
| 1010 | + | new_type = [(name, fields)] |
| 1011 | + | self.settings.structCreator.createTypes(new_type) |
| 1012 | + | new_type_sid = ida_struct.get_struc_id(name) |
| 1013 | + | sz = ida_struct.get_struc_size(new_type_sid) |
| 1014 | + | if sz != self_size: |
| 1015 | + | print("%x" % addr ) |
| 1016 | + | raise Exception("Error at creating structure {}. {:x}!={:x}, fields={}".format(name, sz, self_size, fields)) |
| 1017 | + | |