Projects STRLCPY IDAGolangHelper Commits 2d1f0066
🤬
  • ■ ■ ■ ■ ■ ■
    .gitignore
     1 +*.pyc
     2 + 
  • ■ ■ ■ ■ ■ ■
    GO_Utils/Firstmoduledata.py
     1 +import Utils
     2 +import idautils
     3 +import struct
     4 + 
     5 +def findFirstModuleData(addr, bt):
     6 + #addr_st = "".join(["%s "% x.encode('hex') for x in ("%x" % addr).decode('hex')[::-1]])
     7 + #print addr_st
     8 + possible_addr = idautils.XrefsTo(addr).next().frm
     9 + if Utils.is_hardcoded_slice(possible_addr, bt):
     10 + return possible_addr
     11 + return None
     12 + 
     13 +def isGo17(addr, bt):
     14 + addr += bt.size * 27
     15 + return Utils.is_hardcoded_slice(addr, bt)
     16 + 
     17 +def getTypeinfo17(addr, bt):
     18 + addr2 = addr + bt.size * 25
     19 + robase = bt.ptr(addr2)
     20 + addr += bt.size * 27
     21 + beg = bt.ptr(addr)
     22 + size = bt.ptr(addr+bt.size)
     23 + return beg, beg+size*4, robase
     24 + 
     25 + 
     26 +def getTypeinfo18(addr, bt):
     27 + addr2 = addr + bt.size * 25
     28 + robase = bt.ptr(addr2)
     29 + addr += bt.size * 30
     30 + beg = bt.ptr(addr)
     31 + size = bt.ptr(addr+bt.size)
     32 + return beg, beg+size*4, robase
     33 + 
     34 + 
     35 +def getTypeinfo(addr, bt):
     36 + addr += bt.size * 25
     37 + beg = bt.ptr(addr)
     38 + size = bt.ptr(addr+bt.size)
     39 + 
     40 + return beg, beg+size*bt.size
     41 + 
     42 +"""
     43 +1.9 - same as 1.8
     44 +1.8
     45 +type moduledata struct {
     46 +3 pclntable []byte
     47 +6 ftab []functab
     48 +9 filetab []uint32
     49 + 
     50 +10 findfunctab uintptr
     51 +12 minpc, maxpc uintptr
     52 +14 text, etext uintptr
     53 +16 noptrdata, enoptrdata uintptr
     54 +18 data, edata uintptr
     55 +20 bss, ebss uintptr
     56 +22 noptrbss, enoptrbss uintptr
     57 +25 end, gcdata, gcbss uintptr
     58 +27 types, etypes uintptr
     59 +30 textsectmap []textsect
     60 + typelinks []int32 // offsets from types
     61 + itablinks []*itab
     62 + ptab []ptabEntry
     63 + pluginpath string
     64 + pkghashes []modulehash
     65 + modulename string
     66 + modulehashes []modulehash
     67 + gcdatamask, gcbssmask bitvector
     68 + typemap map[typeOff]*_type // offset to *_rtype in previous module
     69 + next *moduledata
     70 +}
     71 + 
     72 +1.7
     73 +type moduledata struct {
     74 +3 pclntable []byte
     75 +6 ftab []functab
     76 +9 filetab []uint32
     77 +10 findfunctab uintptr
     78 +12 minpc, maxpc uintptr
     79 + 
     80 +14 text, etext uintptr
     81 +16 noptrdata, enoptrdata uintptr
     82 +18 data, edata uintptr
     83 +20 bss, ebss uintptr
     84 +22 noptrbss, enoptrbss uintptr
     85 +25 end, gcdata, gcbss uintptr
     86 +27 types, etypes uintptr
     87 + 
     88 + typelinks []int32 // offsets from types
     89 + itablinks []*itab
     90 + 
     91 + modulename string
     92 + modulehashes []modulehash
     93 + 
     94 + gcdatamask, gcbssmask bitvector
     95 + 
     96 + typemap map[typeOff]*_type // offset to *_rtype in previous module
     97 + 
     98 + next *moduledata
     99 +}
     100 +"""
     101 + 
     102 +"""1.6
     103 +type moduledata struct {
     104 +3 pclntable []byte
     105 +6 ftab []functab
     106 +9 filetab []uint32
     107 +10 findfunctab uintptr
     108 +12 minpc, maxpc uintptr
     109 + 
     110 +14 text, etext uintptr
     111 +16 noptrdata, enoptrdata uintptr
     112 +18 data, edata uintptr
     113 +20 bss, ebss uintptr
     114 +22 noptrbss, enoptrbss uintptr
     115 +25 end, gcdata, gcbss uintptr
     116 + 
     117 + typelinks []*_type
     118 + 
     119 + modulename string
     120 + modulehashes []modulehash
     121 + 
     122 + gcdatamask, gcbssmask bitvector
     123 + 
     124 + next *moduledata
     125 +}
     126 +"""
     127 +"""1.5
     128 +type moduledata struct {
     129 +3 pclntable []byte
     130 +6 ftab []functab
     131 +9 filetab []uint32
     132 +10 findfunctab uintptr
     133 +12 minpc, maxpc uintptr
     134 + 
     135 +14 text, etext uintptr
     136 +16 noptrdata, enoptrdata uintptr
     137 +18 data, edata uintptr
     138 +20 bss, ebss uintptr
     139 +22 noptrbss, enoptrbss uintptr
     140 +25 end, gcdata, gcbss uintptr
     141 + 
     142 + typelinks []*_type
     143 + 
     144 + modulename string
     145 + modulehashes []modulehash
     146 + 
     147 + gcdatamask, gcbssmask bitvector
     148 + 
     149 + next *moduledata
     150 +}
     151 +"""
  • ■ ■ ■ ■ ■ ■
    GO_Utils/Gopclntab.py
     1 +import idc
     2 +import idautils
     3 +import Utils
     4 + 
     5 +def check_is_gopclntab(addr):
     6 + ptr = Utils.get_bitness(addr)
     7 + first_entry = ptr.ptr(addr+8+ptr.size)
     8 + first_entry_off = ptr.ptr(addr+8+ptr.size*2)
     9 + addr_func = addr+first_entry_off
     10 + func_loc = ptr.ptr(addr_func)
     11 + if func_loc == first_entry:
     12 + return True
     13 + return False
     14 + 
     15 + 
     16 +def findGoPcLn():
     17 + pos = idautils.Functions().next() # Get some valid address in .text segment
     18 + while True:
     19 + possible_loc = idc.FindBinary(pos, idc.SEARCH_DOWN, "FB FF FF FF 00 00") #header of gopclntab
     20 + if possible_loc == idc.BADADDR:
     21 + break
     22 + if check_is_gopclntab(possible_loc):
     23 + return possible_loc
     24 + pos = possible_loc+1
     25 + return None
     26 + 
     27 + 
     28 +def rename(beg, ptr, make_funcs = True):
     29 + base = beg
     30 + pos = beg + 8 #skip header
     31 + size = ptr.ptr(pos)
     32 + pos += ptr.size
     33 + end = pos + (size * ptr.size * 2)
     34 + print "%x" % end
     35 + while pos < end:
     36 + offset = ptr.ptr(pos + ptr.size)
     37 + ptr.maker(pos) #in order to get xrefs
     38 + ptr.maker(pos+ptr.size)
     39 + pos += ptr.size * 2
     40 + ptr.maker(base+offset)
     41 + func_addr = ptr.ptr(base+offset)
     42 + if make_funcs == True:
     43 + idc.MakeUnknown(func_addr, 1, idc.DOUNK_SIMPLE)
     44 + idc.MakeFunction(func_addr)
     45 + name_offset = idc.Dword(base+offset+ptr.size)
     46 + name = idc.GetString(base + name_offset)
     47 + name = Utils.relaxName(name)
     48 + Utils.rename(func_addr, name)
  • ■ ■ ■ ■ ■ ■
    GO_Utils/Types.py
     1 +import Utils
     2 +import idc
     3 + 
     4 +class GoTypes_BASE(object):
     5 + def __init__(self, creator):
     6 + self.standardTypes = [
     7 + ("string",[("ptr","*char"), ("len", "uintptr")]),
     8 + ("slice", [("data","*char"),("len", "uintptr"), ("cap", "uintptr")]),
     9 + ("iface", [("itab","*char"),("ptr","*char")])
     10 + ]
     11 + 
     12 + self.commonTypes = [
     13 + ("arrayType",[
     14 + ("type", "type"),
     15 + ("elem", "*type"),
     16 + ("slice", "*type"),
     17 + ("len", "uintptr")
     18 + ]),
     19 + ("chanType", [
     20 + ("type", "type"),
     21 + ("elem", "*type"),
     22 + ("dir", "uintptr")
     23 + ]),
     24 + ("ptrType", [
     25 + ("type", "type"),
     26 + ("elem", "*type")
     27 + ]),
     28 + ("sliceType", [
     29 + ("type", "type"),
     30 + ("elem", "*type")
     31 + ])
     32 + ]
     33 + self.standardEnums = [
     34 + ("kind",[
     35 + "INVALID", "BOOL","INT","INT8",
     36 + "INT16","INT32","INT64","UINT",
     37 + "UINT8","UINT16","UINT32","UINT64",
     38 + "UINTPTR","FLOAT32","FLOAT64","COMPLEX64",
     39 + "COMPLEX128","ARRAY","CHAN","FUNC","INTERFACE","MAP","PTR","SLICE",
     40 + "STRING","STRUCT","UNSAFE_PTR"
     41 + ])
     42 + ]
     43 + creator.createTypes(self.standardTypes)
     44 + creator.createEnums(self.standardEnums)
     45 + 
     46 + 
     47 +class GoTypes_l7(GoTypes_BASE):
     48 + 
     49 + def __init__(self, creator):
     50 + super(GoTypes_l7, self).__init__(creator)
     51 + self.standardTypes = [
     52 + ("uncommonType", [("name", "*string"), ("pkgPath", "*string"), ("methods", "slice")]),
     53 + ]
     54 + #this types depends on type structure so should be created after
     55 + self.commonTypes += [
     56 + ("method__", [("name", "*string"),("pkgPath","*string"),("mtype","*type"),("typ","*type"),("ifn", "void *"),("tfn","void *")]),
     57 + ("structField",[
     58 + ("Name", "*string"),
     59 + ("PkgPath","*string"),
     60 + ("typ", "*type"),
     61 + ("tag", "*string"),
     62 + ("offset", "uintptr"),
     63 + ]),
     64 + ("structType", [
     65 + ("type","type"),
     66 + ("fields", "slice")
     67 + ]),
     68 + ("imethod", [
     69 + ("name", "*string"),
     70 + ("pkgPath", "*string"),
     71 + ("typ", "*type")
     72 + ]),
     73 + ("interfaceType",[
     74 + ("type", "type"),
     75 + ("methods", "slice")
     76 + ]),
     77 + ("funcType",[("type","type")]), #TODO:fix
     78 + ]
     79 + creator.createTypes(self.standardTypes)
     80 + 
     81 + 
     82 +class Go17Types(GoTypes_BASE):
     83 + def __init__(self, creator):
     84 + super(Go17Types, self).__init__(creator)
     85 + self.standardTypes = [
     86 + ("type", [
     87 + ("size", "uintptr"),
     88 + ("ptrdata", "uintptr"),
     89 + ("hash", "__int32"),
     90 + ("flag", "__int8"),
     91 + ("align", "__int8"),
     92 + ("fieldAlign", "__int8"),
     93 + ("kind", "kind"),
     94 + ("alg", "*void"),
     95 + ("gcdata", "*unsigned char"),
     96 + ("string", "__int32"),
     97 + ("ptrtothis", "__int32"),
     98 + ])
     99 + ]
     100 + 
     101 + #this types depends on type structure so should be created after
     102 + self.commonTypes += [
     103 + ("uncommonType", [("pkgPath", "__int32"), ("mcount", "__int16"), ("unused1", "__int16"),("moff", "__int32"), ("unused2", "__int16")]),
     104 + ("method__", [("name", "__int32"), ("mtyp", "__int32"),("ifn","__int32"), ("tfn", "__int32")]),
     105 + ("structField",[
     106 + ("Name", "void *"),
     107 + ("typ", "*type"),
     108 + ("offset", "uintptr"),
     109 + ]),
     110 + ("structType", [
     111 + ("type","type"),
     112 + ("pkgPath", "void *"),
     113 + ("fields", "slice")
     114 + ]),
     115 + ("imethod", [
     116 + ("name", "__int32"),
     117 + ("pkgPath", "__int32"),
     118 + ]),
     119 + ("interfaceType",[
     120 + ("type", "type"),
     121 + ("pkgPath", "void *"),
     122 + ("methods", "slice")
     123 + ]),
     124 + ("funcType", [
     125 + ("type", "type"),
     126 + ("incount","__int16"),
     127 + ("outcount", "__int16")
     128 + ]),
     129 + ("mapType", [
     130 + ("type", "type"),
     131 + ("key","*type"),
     132 + ("elem","*type"),
     133 + ("bucket", "*type"),
     134 + ("hmap", "*type"),
     135 + ("keysize","__int8"),
     136 + ("indirectkey","__int8"),
     137 + ("valuesize","__int8"),
     138 + ("indirectvalue","__int8"),
     139 + ("bucketsize","__int16"),
     140 + ("reflexivekey","__int8"),
     141 + ("needkeyupdate","__int8"),
     142 + ])
     143 + ]
     144 + 
     145 + creator.createTypes(self.standardTypes)
     146 + creator.createTypes(self.commonTypes)
     147 + 
     148 + 
     149 +class Go12Types(GoTypes_l7):
     150 + 
     151 + def __init__(self, creator):
     152 + super(Go12Types, self).__init__(creator)
     153 + self.types = [
     154 + ("type", [
     155 + ("size", "uintptr"),
     156 + ("hash", "__int32"),
     157 + ("_unused", "__int8"),
     158 + ("align", "__int8"),
     159 + ("fieldAlign", "__int8"),
     160 + ("kind", "kind"),
     161 + ("alg", "*void"),
     162 + ("gc", "void *"),
     163 + ("string", "*string"),
     164 + ("UncommonType","*int"),
     165 + ("ptrtothis", "*type"),
     166 + ]),
     167 + ]
     168 + creator.createTypes(self.types)
     169 + creator.createTypes(self.commonTypes)
     170 + 
     171 + 
     172 +class Go14Types(GoTypes_l7):
     173 + 
     174 + def __init__(self, creator):
     175 + super(Go14Types, self).__init__(creator)
     176 + self.types = [
     177 + ("type", [
     178 + ("size", "uintptr"),
     179 + ("hash", "__int32"),
     180 + ("_unused", "__int8"),
     181 + ("align", "__int8"),
     182 + ("fieldAlign", "__int8"),
     183 + ("kind", "kind"),
     184 + ("alg", "*void"),
     185 + ("gcdata", "void *[2]"),
     186 + ("string", "*string"),
     187 + ("UncommonType","*uncommonType"),
     188 + ("ptrtothis", "*type"),
     189 + ("zero", "void *")
     190 + ]),
     191 + ]
     192 + creator.createTypes(self.types)
     193 + creator.createTypes(self.commonTypes)
     194 + 
     195 + 
     196 +class Go15Types(GoTypes_l7):
     197 + 
     198 + def __init__(self, creator):
     199 + super(Go15Types, self).__init__(creator)
     200 + self.types = [
     201 + ("type", [
     202 + ("size", "uintptr"),
     203 + ("ptrdata", "uintptr"),
     204 + ("hash", "__int32"),
     205 + ("_unused", "__int8"),
     206 + ("align", "__int8"),
     207 + ("fieldAlign", "__int8"),
     208 + ("kind", "kind"),
     209 + ("alg", "*void"),
     210 + ("gcdata", "*unsigned char"),
     211 + ("string", "*string"),
     212 + ("UncommonType","*uncommonType"),
     213 + ("ptrtothis", "*type"),
     214 + ("zero", "void *")
     215 + ])
     216 + ]
     217 + creator.createTypes(self.types)
     218 + creator.createTypes(self.commonTypes)
     219 + 
     220 + 
     221 +class Go16Types(GoTypes_l7):
     222 + 
     223 + def __init__(self, creator):
     224 + super(Go16Types, self).__init__(creator)
     225 + self.types = [
     226 + ("type", [
     227 + ("size", "uintptr"),
     228 + ("ptrdata", "uintptr"),
     229 + ("hash", "__int32"),
     230 + ("_unused", "__int8"),
     231 + ("align", "__int8"),
     232 + ("fieldAlign", "__int8"),
     233 + ("kind", "kind"),
     234 + ("alg", "*void"),
     235 + ("gcdata", "*unsigned char"),
     236 + ("string", "*string"),
     237 + ("UncommonType","*uncommonType"),
     238 + ("ptrtothis", "*type"),
     239 + ])
     240 + ]
     241 + creator.createTypes(self.types)
     242 + creator.createTypes(self.commonTypes)
     243 + 
     244 + 
     245 +class TypeProcessing(object):
     246 + 
     247 + def __init__(self, pos, endpos, step, settings):
     248 + self.pos = pos
     249 + self.end = endpos
     250 + self.stepper = step
     251 + self.type_addr = []
     252 + self.settings = settings
     253 + self.kind_types = {
     254 + "CHAN": self.makeChanType,
     255 + "ARRAY": self.makeArrType,
     256 + "SLICE": self.makeSliceType,
     257 + "STRUCT": self.makeStructType,
     258 + "PTR" : self.makePtrType,
     259 + "INTERFACE": self.makeInterface,
     260 + "FUNC": self.makeFunc,
     261 + "MAP": self.makeMap,
     262 + }
     263 + 
     264 + 
     265 + def __iter__(self):
     266 + return self
     267 + 
     268 + def next(self):
     269 + if self.pos >= self.end:
     270 + raise StopIteration
     271 + value = self.stepper.ptr(self.pos)
     272 + self.pos += self.stepper.size
     273 + return self.handle_offset(value)
     274 + 
     275 + def getDword(self, sid, addr, name):
     276 + name_off = idc.GetMemberOffset(sid, name)
     277 + return idc.Dword(addr+name_off)
     278 + 
     279 + def getPtr(self, sid, addr, name):
     280 + name_off = idc.GetMemberOffset(sid, name)
     281 + return self.stepper.ptr(addr+name_off)
     282 + 
     283 + def getPtrToThis(self, sid, offset):
     284 + return self.getPtr(sid, offset, "ptrtothis")
     285 + 
     286 + def getOffset(self, offset):
     287 + return offset
     288 + 
     289 + def make_arr(self, addr, arr_size, struc_size, type):
     290 + res = idc.MakeArray(addr, arr_size)
     291 + if res == False:
     292 + idc.MakeUnknown(addr, arr_size*struc_size, idc.DOUNK_SIMPLE)
     293 + idc.SetType(addr, type)
     294 + idc.MakeArray(addr, arr_size)
     295 + 
     296 + 
     297 + def getName(self, offset):
     298 + sid = idc.GetStrucIdByName("type")
     299 + string_addr = offset + idc.GetMemberOffset(sid, "string")
     300 + ptr = self.stepper.ptr(string_addr)
     301 + idc.SetType(ptr, "string")
     302 + name = self.stepper.ptr(ptr)
     303 + return idc.GetString(name)
     304 + 
     305 + def getKindEnumName(self, addr):
     306 + struc_id = idc.GetStrucIdByName("type")
     307 + offset_kind = idc.GetMemberOffset(struc_id, "kind")
     308 + kind = idc.Byte(addr + offset_kind) & 0x1f
     309 + print "kind2 %d" % kind
     310 + return self.settings.typer.standardEnums[0][1][kind]
     311 + 
     312 + 
     313 + def handle_offset(self, offset):
     314 + #Check if we already parse this
     315 + if offset in self.type_addr:
     316 + return
     317 + print "Processing: %x" % offset
     318 + self.type_addr.append(offset)
     319 + 
     320 + #Set type and get name
     321 + idc.SetType(offset, "type")
     322 + name = self.getName(offset)
     323 + idc.MakeComm(offset, name)
     324 + 
     325 + #get kind name
     326 + kind_name = self.getKindEnumName(offset)
     327 + print kind_name
     328 + if name[0] == "*" and kind_name != "PTR":
     329 + name = name[1:]
     330 + name = Utils.relaxName(name)
     331 + Utils.rename(offset, name)
     332 + self.betterTypePlease(offset)
     333 + sid = idc.GetStrucIdByName("type")
     334 + addr = self.getPtrToThis(sid, offset)
     335 + if addr != 0:
     336 + addr = self.getOffset(addr)
     337 + self.handle_offset(addr)
     338 + return
     339 + if kind_name != "FUNC":
     340 + self.processUncommon(sid, offset)
     341 + 
     342 + def betterTypePlease(self, offset):
     343 + kind_name = self.getKindEnumName(offset)
     344 + if kind_name in self.kind_types:
     345 + self.kind_types[kind_name](offset)
     346 + 
     347 + def makeChanType(self, offset):
     348 + idc.SetType(offset, "chanType")
     349 + sid = idc.GetStrucIdByName("chanType")
     350 + addr = self.getPtr(sid, offset, "elem")
     351 + self.handle_offset(addr)
     352 + 
     353 + def makeSliceType(self, offset):
     354 + idc.SetType(offset, "sliceType")
     355 + sid = idc.GetStrucIdByName("sliceType")
     356 + addr = self.getPtr(sid, offset, "elem")
     357 + self.handle_offset(addr)
     358 + 
     359 + def makeArrType(self, offset):
     360 + idc.SetType(offset, "arrayType")
     361 + sid = idc.GetStrucIdByName("arrayType")
     362 + addr = self.getPtr(sid, offset, "elem")
     363 + self.handle_offset(addr)
     364 + addr = self.getPtr(sid, offset, "slice")
     365 + self.handle_offset(addr)
     366 + 
     367 + def makePtrType(self, offset):
     368 + idc.SetType(offset, "ptrType")
     369 + sid = idc.GetStrucIdByName("ptrType")
     370 + addr = self.getPtr(sid, offset, "elem")
     371 + self.handle_offset(addr)
     372 + 
     373 + def makeStructType(self, offset):
     374 + idc.SetType(offset, "structType")
     375 + sid = idc.GetStrucIdByName("structType")
     376 + slice_id = idc.GetStrucIdByName("slice")
     377 + offset_elem = idc.GetMemberOffset(sid, "fields")
     378 + inner_offset = idc.GetMemberOffset(slice_id, "data")
     379 + addr = self.stepper.ptr(offset_elem + offset + inner_offset)
     380 + 
     381 + inner_offset = idc.GetMemberOffset(slice_id, "len")
     382 + size = self.stepper.ptr(offset+offset_elem+inner_offset)
     383 + if size == 0:
     384 + return
     385 + idc.SetType(addr, "structField")
     386 + sz = idc.GetStrucSize(idc.GetStrucIdByName("structField"))
     387 + self.make_arr(addr, size, sz, "structField")
     388 + sid_type = idc.GetStrucIdByName("type")
     389 + size_new_struct = self.getPtr(sid_type, offset, "size")
     390 + for i in xrange(size):
     391 + self.processStructField(addr, i*sz)
     392 + name = self.getName(offset)
     393 + if True:
     394 + print "Name is %s" % name
     395 + name = Utils.relaxName(name)
     396 + name = "ut_" + name
     397 + self.createUserTypeStruct(addr, name, size, size_new_struct)
     398 + 
     399 + def processStructField(self, addr, index):
     400 + offset = addr + index
     401 + sid = idc.GetStrucIdByName("structField")
     402 + ptr = self.getPtr(sid, offset, "Name")
     403 + if ptr != 0:
     404 + idc.SetType(ptr, "string")
     405 + fieldName = idc.GetString(self.stepper.ptr(ptr))
     406 + Utils.rename(ptr, fieldName)
     407 + ptr = self.getPtr(sid, offset, "typ")
     408 + self.handle_offset(ptr)
     409 +
     410 + 
     411 + def getStructFieldOffset(self, sid, addr):
     412 + return self.getPtr(sid, addr, "offset")
     413 +
     414 + def createUserTypeStruct(self, addr, name, size, self_size):
     415 + fields = []
     416 + #print name
     417 + sid = idc.GetStrucIdByName("structField")
     418 + sz = idc.GetStrucSize(sid)
     419 + sid_type = idc.GetStrucIdByName("type")
     420 + fields = []
     421 + curr_offset = 0
     422 + idc.MakeComm(addr, name)
     423 + for i in xrange(size):
     424 + fieldname = self.nameFromOffset(self.getPtr(sid, addr+i*sz,"Name"))
     425 + #print fieldname
     426 + type_addr = self.getPtr(sid, addr+i*sz, "typ")
     427 + typename = self.getType(type_addr)
     428 + size = self.getPtr(sid_type, type_addr, "size")
     429 + #print typename
     430 + if fieldname == "" or fieldname is None:
     431 + fieldname = "unused_"+Utils.id_generator()
     432 + offset = self.getStructFieldOffset(sid, addr+i*sz)
     433 + if offset != curr_offset:
     434 + #print name
     435 + #print fieldname
     436 + print "Offset missmatch.Got %d expected %d. Adding padding..." % (curr_offset, offset)
     437 + if offset < curr_offset:
     438 + raise("Too many bytes already")
     439 + while offset != curr_offset:
     440 + fields.append(("padding", "char"))
     441 + curr_offset += 1
     442 + curr_offset += size
     443 + if size != 0:
     444 + offset_kind = idc.GetMemberOffset(sid_type, "kind")
     445 + kind_of_type = self.getKindEnumName(type_addr)
     446 + if kind_of_type == "STRUCT_": #Disabled for now
     447 + name_type = self.getName(type_addr)
     448 + while name_type[0] == "*":
     449 + name_type = name_type[1:]
     450 + name_type = Utils.relaxName(name_type)
     451 + name_type = "ut_" + name_type
     452 + #print "setting type %s" % name_type
     453 + fields.append((fieldname, name_type))
     454 + elif kind_of_type == "STRING":
     455 + fields.append((fieldname, "string"))
     456 + elif kind_of_type == "SLICE":
     457 + fields.append((fieldname, "slice"))
     458 + elif kind_of_type == "INTERFACE":
     459 + fields.append((fieldname, "iface"))
     460 + else:
     461 + fields.append((fieldname, "char [%d]" % size))
     462 + if curr_offset != self_size:
     463 + print "%x: Structure size mismatch: %x" % (addr, curr_offset)
     464 + if self_size < curr_offset:
     465 + raise("Too many bytes already")
     466 + while self_size != curr_offset:
     467 + fields.append(("padding", "char"))
     468 + curr_offset += 1
     469 + new_type = [(name, fields)]
     470 + #print new_type
     471 + self.settings.structCreator.createTypes(new_type)
     472 + #print fields
     473 + new_type_sid = idc.GetStrucIdByName(name)
     474 + sz = idc.GetStrucSize(new_type_sid)
     475 + if sz != self_size:
     476 + print "%x" % addr
     477 + raise("Error at creating structure")
     478 +
     479 + def getType(self, addr):
     480 + print "%x" % addr
     481 + sid = idc.GetStrucIdByName("type")
     482 + name = self.getName(addr)
     483 + if self.getKindEnumName(addr) != "PTR":
     484 + while name[0] == "*":
     485 + name = name[1:]
     486 + return name
     487 + 
     488 + def makeInterface(self, offset):
     489 + idc.SetType(offset, "interfaceType")
     490 + ifaceid = idc.GetStrucIdByName("interfaceType")
     491 + meth_offs = idc.GetMemberOffset(ifaceid, "methods")
     492 + slice_id = idc.GetStrucIdByName("slice")
     493 + size_off = idc.GetMemberOffset(slice_id, "len")
     494 + size = self.stepper.ptr(offset + meth_offs + size_off)
     495 + if size != 0:
     496 + addr = self.getPtr(slice_id, offset + meth_offs, "data")
     497 + idc.SetType(addr, "imethod")
     498 + sz = idc.GetStrucSize(idc.GetStrucIdByName("imethod"))
     499 + self.make_arr(addr, size, sz, "imethod")
     500 + names = self.processIMethods(addr, size)
     501 + # For now only for go1.7
     502 + if names is None:
     503 + return
     504 + name = self.getName(offset)
     505 + while name[0] == "*":
     506 + name = name[1:]
     507 + name = Utils.relaxName(name)
     508 + name = "user_interface_" + name
     509 + # TODO: this is for go1.7 need additional check for other versions
     510 + fields = [("inter", "void *"), ("type", "void *"), ("link", "void *"), ("bad", "__int32"),
     511 + ("unused", "__int32")]
     512 + for i in names:
     513 + fields.append((i, "void *"))
     514 + itype = [(name, fields)]
     515 + self.settings.structCreator.createTypes(itype)
     516 + 
     517 + def processIMethods(self, addr, size):
     518 + return None
     519 + 
     520 + def makeFunc(self, offset):
     521 + idc.SetType(offset, "funcType")
     522 + self.parseFuncType(offset)
     523 + 
     524 + def parseFuncType(self, offset):
     525 + return
     526 + 
     527 + def makeMap(self, offset):
     528 + return # TODO:fix
     529 + 
     530 + 
     531 +class TypeProcessing17(TypeProcessing):
     532 + 
     533 + def __init__(self, pos, endpos, step, settings, base_type):
     534 + super(TypeProcessing17, self).__init__(pos, endpos, step, settings)
     535 + self.robase = base_type
     536 + 
     537 + def next(self):
     538 + #print "next type from typelink"
     539 + if self.pos >= self.end:
     540 + raise StopIteration
     541 + value = idc.Dword(self.pos)
     542 + self.pos += 4
     543 + value = self.getOffset(value)
     544 + return self.handle_offset(value)
     545 + 
     546 + def getOffset(self, offset):
     547 + return self.robase + offset
     548 + 
     549 + 
     550 + def get_str(self, pos, len):
     551 + out = ""
     552 + for i in xrange(len):
     553 + out += chr(idc.Byte(pos+i))
     554 + return out
     555 + 
     556 + def getName(self, offset):
     557 + #print "GetName: %x" % offset
     558 + sid = idc.GetStrucIdByName("type")
     559 + name_off = self.getDword(sid, offset, "string")
     560 + string_addr = self.getOffset(name_off) + 3
     561 + ln = idc.Byte(string_addr-1)
     562 + return self.get_str(string_addr, ln)
     563 + 
     564 + def nameFromOffset(self, offset):
     565 + addr = offset
     566 + return self.get_str(addr + 3, idc.Byte(addr + 2))
     567 + 
     568 + def getPtrToThis(self, sid, offset):
     569 + memb_offs = idc.GetMemberOffset(sid, "ptrtothis")
     570 + return idc.Dword(offset + memb_offs)
     571 + 
     572 + def processStructField(self, addr, index):
     573 + offset = addr + index
     574 + sid = idc.GetStrucIdByName("structField")
     575 + ptr = self.getPtr(sid, offset, "Name")
     576 + ln = idc.Byte(ptr + 2)
     577 + fieldName = self.get_str(ptr + 3, ln)
     578 + Utils.rename(ptr, fieldName)
     579 + ptr = self.getPtr(sid, offset, "typ")
     580 + self.handle_offset(ptr)
     581 + 
     582 + def processIMethods(self, offst, size):
     583 + sz = idc.GetStrucSize(idc.GetStrucIdByName("imethod"))
     584 + comm = []
     585 + for i in xrange(size):
     586 + comm.append(self.processIMethod(offst + i * sz))
     587 + idc.MakeComm(offst, "\n".join(comm))
     588 + return comm
     589 + 
     590 + def processIMethod(self, offst):
     591 + sid = idc.GetStrucIdByName("imethod")
     592 + name = self.getDword(sid, offst, "name")
     593 + name += self.robase
     594 + name = self.get_str(name + 3, idc.Byte(name + 2))
     595 + return name
     596 + 
     597 + def processMethods(self, offst):
     598 + sid = idc.GetStrucIdByName("method__")
     599 + name = self.getDword(sid, offst, "name")
     600 + name += self.robase
     601 + name = self.get_str(name + 3, idc.Byte(name + 2))
     602 + type_meth = self.getDword(sid, offst, "mtyp")
     603 + type_meth_addr1 = self.robase + type_meth
     604 + func_body1 = self.getDword(sid, offst, "ifn")
     605 + func_addr1 = self.text_addr + func_body1
     606 + func_body2 = self.getDword(sid, offst, "tfn")
     607 + func_addr2 = self.text_addr + func_body1
     608 + return "%s %x %x %x" % (name, type_meth_addr1, func_addr1, func_addr2)
     609 + 
     610 + def makeMap(self, offset):
     611 + idc.SetType(offset, "mapType")
     612 + sid = idc.GetStrucIdByName("mapType")
     613 + addr = self.getPtr(sid, offset, "key")
     614 + self.handle_offset(addr)
     615 + addr = self.getPtr(sid, offset, "elem")
     616 + self.handle_offset(addr)
     617 + addr = self.getPtr(sid, offset, "bucket")
     618 + self.handle_offset(addr)
     619 + addr = self.getPtr(sid, offset, "hmap")
     620 + self.handle_offset(addr)
     621 + 
     622 + def parseFuncType(self, offset):
     623 + return
     624 + # print "func off %x" % offset
     625 + sid = idc.GetStrucIdByName("funcType")
     626 + in_size = idc.Word(offset + idc.GetMemberOffset(sid, "incount"))
     627 + out_size = idc.Word(offset + idc.GetMemberOffset(sid, "outcount"))
     628 + sz = idc.GetStrucSize(sid)
     629 + for i in xrange(in_size + out_size):
     630 + idc.SetType(offset + sz + i * self.stepper.size, "type *")
     631 + 
     632 + 
     633 +class TypeProcessing19(TypeProcessing17):
     634 +
     635 + def __init__(self, pos, endpos, step, settings, base_type):
     636 + super(TypeProcessing19, self).__init__(pos, endpos, step, settings, base_type)
     637 + self.robase = base_type
     638 + 
     639 + def getStructFieldOffset(self, sid, addr):
     640 + return (self.getPtr(sid, addr, "offset") >> 1)
  • ■ ■ ■ ■ ■ ■
    GO_Utils/Utils.py
     1 +import idc
     2 +import string
     3 +import random
     4 + 
     5 +class bitZ(object):
     6 + def __init__(self, ptr, size, maker):
     7 + self.ptr = ptr
     8 + self.size = size
     9 + self.maker = maker
     10 + 
     11 + 
     12 +bits32 = bitZ(idc.Dword, 4, idc.MakeDword)
     13 +bits64 = bitZ(idc.Qword, 8, idc.MakeQword)
     14 + 
     15 + 
     16 +def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
     17 + return ''.join(random.choice(chars) for _ in range(size))
     18 + 
     19 + 
     20 +def rename(offset, name):
     21 + res = idc.MakeNameEx(offset, name, idc.SN_NOWARN)
     22 + if res == 0:
     23 + name = name+"_autogen_"+id_generator()
     24 + idc.MakeNameEx(offset, name, idc.SN_NOWARN)
     25 + 
     26 + 
     27 +def relaxName(name):
     28 + name = name.replace('.', '_').replace("<-", '_chan_left_').replace('*', '_ptr_').replace('-', '_').replace(';','').replace('"', '').replace('\\', '')
     29 + name = name.replace('(', '').replace(')', '').replace('/', '_').replace(' ', '_').replace(',', 'comma').replace('{','').replace('}', '').replace('[', '').replace(']', '')
     30 + return name
     31 + 
     32 + 
     33 +def get_bitness(addr):
     34 + ptr = bits32
     35 + if idc.GetSegmentAttr(addr, idc.SEGATTR_BITNESS) == 2:
     36 + ptr = bits64
     37 + return ptr
     38 + 
     39 + 
     40 +def is_hardcoded_slice(addr, bt_obj):
     41 + #compiled slices will have valid ptr
     42 + if bt_obj.ptr(bt_obj.ptr(addr)) == idc.BADADDR:
     43 + return False
     44 + addr = addr + bt_obj.size
     45 + val1 = bt_obj.ptr(addr)
     46 + val2 = bt_obj.ptr(addr + bt_obj.size)
     47 + if val1 != val2:
     48 + return False
     49 + return True
     50 + 
     51 + 
     52 +class StructCreator(object):
     53 + 
     54 + def __init__(self, bt_obj):
     55 + self.types_id = {}
     56 + if bt_obj.size == 8:
     57 + self.uintptr = (idc.FF_QWRD|idc.FF_DATA, -1, bt_obj.size)
     58 + else:
     59 + self.uintptr = (idc.FF_DWRD | idc.FF_DATA, -1, bt_obj.size)
     60 + 
     61 + def createStruct(self, name):
     62 + sid = idc.GetStrucIdByName(name)
     63 + if sid != -1:
     64 + idc.DelStruc(sid)
     65 + sid = idc.AddStrucEx(-1, name, 0)
     66 + self.types_id['name'] = sid
     67 + return sid
     68 + 
     69 + def fillStruct(self, sid, data):
     70 + for i in data:
     71 + new_type = None
     72 + #(i1, i2, i3) = self.stepper.parseField(i[1])
     73 + name = i[1]
     74 + if name[0] == "*":
     75 + name = name[1:]
     76 + if i[1] != "uintptr":
     77 + i1,i2,i3 = (idc.FF_BYTE|idc.FF_DATA, -1, 1)
     78 + else:
     79 + i1, i2, i3 = self.uintptr
     80 + if name == i[1]:
     81 + new_type = i[1]
     82 + else:
     83 + new_type = name + " *"
     84 + res = idc.AddStrucMember(sid, i[0], -1, i1, i2, i3)
     85 + use_name = i[0]
     86 + if res == -1: #Bad name
     87 + #print "Bad name %s for struct member" % i[0]
     88 + use_name = i[0] + "_autogen_"+id_generator()
     89 + idc.AddStrucMember(sid, use_name, -1, i1, i2, i3)
     90 + if new_type is not None:
     91 + offset = idc.GetMemberOffset(sid, use_name)
     92 + #print "Setting %s as %s" % (i[0], new_type)
     93 + idc.SetType(idc.GetMemberId(sid, offset), new_type)
     94 + 
     95 + def makeStruct(self, i):
     96 + print "Creating structure %s" % (i[0])
     97 + sid = self.createStruct(i[0])
     98 + self.fillStruct(sid, i[1])
     99 + 
     100 + def createTypes(self, types):
     101 + for i in types:
     102 + self.makeStruct(i)
     103 + 
     104 + def createEnum(self, enum):
     105 + eid = idc.AddEnum(-1, enum[0], 0x1100000) #what is this flag?
     106 + idc.SetEnumBf(eid, 1)
     107 + val = 0
     108 + mask = 0x1f
     109 + idc.SetEnumWidth(eid, 1)
     110 + for i in enum[1]:
     111 + idc.AddConstEx(eid, i, val, mask)
     112 + val += 1
     113 + 
     114 + def createEnums(self, enums):
     115 + for i in enums:
     116 + self.createEnum(i)
     117 + 
     118 + 
  • ■ ■ ■ ■ ■ ■
    GO_Utils/__init__.py
     1 +import idaapi
     2 +import Gopclntab
     3 +import Utils
     4 +import Firstmoduledata
     5 +import Types
     6 +import idc
     7 +import idautils
     8 + 
     9 +class GoSettings(object):
     10 + 
     11 + 
     12 + 
     13 + def __init__(self):
     14 + self.storage = {}
     15 + #TODO: maybe here() not best option
     16 + self.bt_obj = Utils.get_bitness(idc.here())
     17 + self.structCreator = Utils.StructCreator(self.bt_obj)
     18 + self.processor = None
     19 + self.typer = None
     20 + 
     21 + def getVal(self, key):
     22 + if key in self.storage:
     23 + return self.storage[key]
     24 + return None
     25 + 
     26 + def setVal(self, key, val):
     27 + self.storage[key] = val
     28 + 
     29 + def getGopcln(self):
     30 + gopcln_addr = self.getVal("gopcln")
     31 + if gopcln_addr is None:
     32 + gopcln_addr = Gopclntab.findGoPcLn()
     33 + self.setVal("gopcln", gopcln_addr)
     34 + return gopcln_addr
     35 + 
     36 + def findModuleData(self):
     37 + gopcln_addr = self.getGopcln()
     38 + fmd = Firstmoduledata.findFirstModuleData(gopcln_addr, self.bt_obj)
     39 + self.setVal("firstModData", fmd)
     40 + return
     41 + 
     42 + def tryFindGoVersion(self):
     43 + fmd = self.getVal("firstModData")
     44 + if fmd is None:
     45 + return "This should be go <= 1.4 : No module data found"
     46 + vers = "go1.5 or go1.6"
     47 + if Firstmoduledata.isGo17(fmd, self.bt_obj) is True:
     48 + vers = "go1.7, go1.8 or go1.9"
     49 + return "According to moduleData struct is should be %s" % (vers)
     50 + 
     51 + def renameFunctions(self):
     52 + gopcln_tab = self.getGopcln()
     53 + Gopclntab.rename(gopcln_tab, self.bt_obj)
     54 + 
     55 + def getVersionByString(self):
     56 + pos = idautils.Functions().next()
     57 + if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 39") != idc.BADADDR:
     58 + return 'Go 1.9'
     59 + if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 38") != idc.BADADDR:
     60 + return 'Go 1.8'
     61 + if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 37") != idc.BADADDR:
     62 + return 'Go 1.7'
     63 + if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 36") != idc.BADADDR:
     64 + return 'Go 1.6'
     65 + if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 35") != idc.BADADDR:
     66 + return 'Go 1.5'
     67 + if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 34") != idc.BADADDR:
     68 + return 'Go 1.4'
     69 + if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 33") != idc.BADADDR:
     70 + return 'Go 1.3'
     71 + if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 32") != idc.BADADDR:
     72 + return 'Go 1.2'
     73 + 
     74 + def createTyper(self, typ):
     75 + if typ == 0:
     76 + self.typer = Types.Go12Types(self.structCreator)
     77 + elif typ == 1:
     78 + self.typer = Types.Go14Types(self.structCreator)
     79 + elif typ == 2:
     80 + self.typer = Types.Go15Types(self.structCreator)
     81 + elif typ == 3:
     82 + self.typer = Types.Go16Types(self.structCreator)
     83 + elif typ == 4 or typ == 5:
     84 + self.typer = Types.Go17Types(self.structCreator)
     85 + elif typ == 6:
     86 + self.typer = Types.Go17Types(self.structCreator)
     87 + 
     88 + def typesModuleData(self, typ):
     89 + if typ < 2:
     90 + return
     91 + if self.getVal("firstModData") is None:
     92 + self.findModuleData()
     93 + fmd = self.getVal("firstModData")
     94 + if fmd is None:
     95 + return
     96 + if self.typer is None:
     97 + self.createTyper(typ)
     98 + robase = None
     99 + if typ == 4:
     100 + beg, end, robase = Firstmoduledata.getTypeinfo17(fmd, self.bt_obj)
     101 + self.processor = Types.TypeProcessing17(beg, end, self.bt_obj, self, robase)
     102 + elif typ == 5:
     103 + beg, end, robase = Firstmoduledata.getTypeinfo18(fmd, self.bt_obj)
     104 + self.processor = Types.TypeProcessing17(beg, end, self.bt_obj, self, robase)
     105 + elif typ == 6:
     106 + beg, end, robase = Firstmoduledata.getTypeinfo18(fmd, self.bt_obj)
     107 + self.processor = Types.TypeProcessing19(beg, end, self.bt_obj, self, robase)
     108 + else:
     109 + beg, end = Firstmoduledata.getTypeinfo(fmd, self.bt_obj)
     110 + self.processor = Types.TypeProcessing(beg, end, self.bt_obj, self)
     111 + print "%x %x % x" % (beg, end, robase)
     112 + for i in self.processor:
     113 + pass
     114 + return
  • ■ ■ ■ ■ ■ ■
    go_entry.py
     1 +# -----------------------------------------------------------------------
     2 +# This is an example illustrating how to use the Form class
     3 +# (c) Hex-Rays
     4 +#
     5 +import GO_Utils
     6 +idaapi.require("GO_Utils")
     7 +idaapi.require("GO_Utils.Gopclntab")
     8 +idaapi.require("GO_Utils.Utils")
     9 +idaapi.require("GO_Utils.Firstmoduledata")
     10 +idaapi.require("GO_Utils.Types")
     11 + 
     12 +from idaapi import Form
     13 + 
     14 +GO_SETTINGS = GO_Utils.GoSettings()
     15 + 
     16 +#<pycode(ex_askusingform)>
     17 +# --------------------------------------------------------------------------
     18 +class MyForm(Form):
     19 + def __init__(self):
     20 + self.invert = False
     21 + Form.__init__(self, r"""STARTITEM {id:cGoVers}
     22 +GoLoader
     23 + 
     24 +{FormChangeCb}
     25 +<##Try to detemine go version based on moduledata:{iButton1}>
     26 +<##Try to detemine go version based on version string:{iButton2}>
     27 +<##Rename functions:{iButton3}>
     28 +Go version:
     29 +<Go1.2:{r2}>
     30 +<Go1.4:{r4}>
     31 +<Go1.5:{r5}>
     32 +<Go1.6:{r6}>
     33 +<Go1.7:{r7}>
     34 +<Go1.8:{r8}>
     35 +<Go1.9:{r9}>{cGoVers}>
     36 +<##Add standard go types:{iButton4}>
     37 +<##Parse types by moduledata:{iButton5}>
     38 +""", {
     39 + 'iButton1': Form.ButtonInput(self.OnButton1),
     40 + 'iButton2': Form.ButtonInput(self.OnButton2),
     41 + 'iButton3': Form.ButtonInput(self.OnButton3),
     42 + 'iButton4': Form.ButtonInput(self.OnButton4),
     43 + 'iButton5': Form.ButtonInput(self.OnButton5),
     44 + 'cGoVers': Form.RadGroupControl(("r2", "r3","r4","r5","r6","r7", "r8", "r9")),
     45 + 'FormChangeCb': Form.FormChangeCb(self.OnFormChange),
     46 + })
     47 + 
     48 + 
     49 + def OnButton1(self, code=0):
     50 + GO_SETTINGS.findModuleData()
     51 + print GO_SETTINGS.tryFindGoVersion()
     52 + 
     53 + 
     54 + def OnButton3(self, code=0):
     55 + GO_SETTINGS.renameFunctions()
     56 + 
     57 + def OnButton2(self, code=0):
     58 + print GO_SETTINGS.getVersionByString()
     59 + 
     60 + def OnButton4(self, code=0):
     61 + typ = self.GetControlValue(self.cGoVers)
     62 + GO_SETTINGS.createTyper(typ)
     63 + 
     64 + def OnButton5(self, code=0):
     65 + typ = self.GetControlValue(self.cGoVers)
     66 + GO_SETTINGS.typesModuleData(typ)
     67 + 
     68 + 
     69 + def OnFormChange(self, fid):
     70 + return 1
     71 + 
     72 + 
     73 + 
     74 +# --------------------------------------------------------------------------
     75 + 
     76 +# --------------------------------------------------------------------------
     77 +def ida_main():
     78 + # Create form
     79 + global f
     80 + f = MyForm()
     81 + 
     82 + # Compile (in order to populate the controls)
     83 + f.Compile()
     84 + 
     85 + # Execute the form
     86 + ok = f.Execute()
     87 + 
     88 + # Dispose the form
     89 + f.Free()
     90 + 
     91 +# --------------------------------------------------------------------------
     92 + 
     93 +#</pycode(ex_askusingform)>
     94 + 
     95 + 
     96 +# --------------------------------------------------------------------------
     97 +ida_main()
Please wait...
Page is in error, reload to recover