From 263149d14b9ba31e2abd239ff2477ec221532d57 Mon Sep 17 00:00:00 2001 From: Stephan Simon Date: Wed, 8 Jan 2020 22:44:06 -0500 Subject: [PATCH] updated IDAPython API usage Starting with IDA 7.4, 6.95 compatibility is disabled by default. Use the updated APIs as listed at https://www.hex-rays.com/products/ida/support/ida74_idapython_no_bc695_porting_guide.shtml --- GO_Utils/Gopclntab.py | 14 +++-- GO_Utils/Types.py | 118 +++++++++++++++++++++--------------------- GO_Utils/Utils.py | 38 +++++++------- GO_Utils/__init__.py | 24 +++++---- 4 files changed, 103 insertions(+), 91 deletions(-) diff --git a/GO_Utils/Gopclntab.py b/GO_Utils/Gopclntab.py index f9e4feb..7499cd3 100644 --- a/GO_Utils/Gopclntab.py +++ b/GO_Utils/Gopclntab.py @@ -1,6 +1,9 @@ import idc import idautils import idaapi +import ida_bytes +import ida_funcs +import ida_search import Utils info = idaapi.get_inf_structure() @@ -25,7 +28,8 @@ def check_is_gopclntab(addr): def findGoPcLn(): pos = idautils.Functions().next() # Get some valid address in .text segment while True: - possible_loc = idc.FindBinary(pos, idc.SEARCH_DOWN, lookup) #header of gopclntab + end_ea = idc.get_segm_end(pos) + possible_loc = ida_search.find_binary(pos, end_ea, lookup, 16, idc.SEARCH_DOWN) #header of gopclntab if possible_loc == idc.BADADDR: break if check_is_gopclntab(possible_loc): @@ -49,9 +53,9 @@ def rename(beg, ptr, make_funcs = True): ptr.maker(base+offset) func_addr = ptr.ptr(base+offset) if make_funcs == True: - idc.MakeUnknown(func_addr, 1, idc.DOUNK_SIMPLE) - idc.MakeFunction(func_addr) - name_offset = idc.Dword(base+offset+ptr.size) - name = idc.GetString(base + name_offset) + ida_bytes.del_items(func_addr, 1, ida_bytes.DELIT_SIMPLE) + ida_funcs.add_func(func_addr) + name_offset = idc.get_wide_dword(base+offset+ptr.size) + name = idc.get_strlit_contents(base + name_offset) name = Utils.relaxName(name) Utils.rename(func_addr, name) \ No newline at end of file diff --git a/GO_Utils/Types.py b/GO_Utils/Types.py index 749b59e..3b99ee0 100644 --- a/GO_Utils/Types.py +++ b/GO_Utils/Types.py @@ -1,4 +1,6 @@ import Utils +import ida_bytes +import ida_struct import idc class GoTypes_BASE(object): @@ -273,11 +275,11 @@ def next(self): return self.handle_offset(value) def getDword(self, sid, addr, name): - name_off = idc.GetMemberOffset(sid, name) - return idc.Dword(addr+name_off) + name_off = idc.get_member_offset(sid, name) + return idc.get_wide_dword(addr+name_off) def getPtr(self, sid, addr, name): - name_off = idc.GetMemberOffset(sid, name) + name_off = idc.get_member_offset(sid, name) return self.stepper.ptr(addr+name_off) def getPtrToThis(self, sid, offset): @@ -287,25 +289,25 @@ def getOffset(self, offset): return offset def make_arr(self, addr, arr_size, struc_size, type): - res = idc.MakeArray(addr, arr_size) + res = idc.make_array(addr, arr_size) if res == False: - idc.MakeUnknown(addr, arr_size*struc_size, idc.DOUNK_SIMPLE) + ida_bytes.del_items(addr, arr_size*struc_size, ida_bytes.DELIT_SIMPLE) idc.SetType(addr, type) - idc.MakeArray(addr, arr_size) + idc.make_array(addr, arr_size) def getName(self, offset): - sid = idc.GetStrucIdByName("type") - string_addr = offset + idc.GetMemberOffset(sid, "string") + sid = ida_struct.get_struc_id("type") + string_addr = offset + idc.get_member_offset(sid, "string") ptr = self.stepper.ptr(string_addr) idc.SetType(ptr, "string") name = self.stepper.ptr(ptr) return idc.GetString(name) def getKindEnumName(self, addr): - struc_id = idc.GetStrucIdByName("type") - offset_kind = idc.GetMemberOffset(struc_id, "kind") - kind = idc.Byte(addr + offset_kind) & 0x1f + struc_id = ida_struct.get_struc_id("type") + offset_kind = idc.get_member_offset(struc_id, "kind") + kind = idc.get_wide_byte(addr + offset_kind) & 0x1f return self.settings.typer.standardEnums[0][1][kind] @@ -319,7 +321,7 @@ def handle_offset(self, offset): #Set type and get name idc.SetType(offset, "type") name = self.getName(offset) - idc.MakeComm(offset, name) + idc.set_cmt(offset, name, 0) #get kind name kind_name = self.getKindEnumName(offset) @@ -329,7 +331,7 @@ def handle_offset(self, offset): name = Utils.relaxName(name) Utils.rename(offset, name) self.betterTypePlease(offset) - sid = idc.GetStrucIdByName("type") + sid = ida_struct.get_struc_id("type") addr = self.getPtrToThis(sid, offset) if addr != 0: addr = self.getOffset(addr) @@ -345,19 +347,19 @@ def betterTypePlease(self, offset): def makeChanType(self, offset): idc.SetType(offset, "chanType") - sid = idc.GetStrucIdByName("chanType") + sid = ida_struct.get_struc_id("chanType") addr = self.getPtr(sid, offset, "elem") self.handle_offset(addr) def makeSliceType(self, offset): idc.SetType(offset, "sliceType") - sid = idc.GetStrucIdByName("sliceType") + sid = ida_struct.get_struc_id("sliceType") addr = self.getPtr(sid, offset, "elem") self.handle_offset(addr) def makeArrType(self, offset): idc.SetType(offset, "arrayType") - sid = idc.GetStrucIdByName("arrayType") + sid = ida_struct.get_struc_id("arrayType") addr = self.getPtr(sid, offset, "elem") self.handle_offset(addr) addr = self.getPtr(sid, offset, "slice") @@ -365,26 +367,26 @@ def makeArrType(self, offset): def makePtrType(self, offset): idc.SetType(offset, "ptrType") - sid = idc.GetStrucIdByName("ptrType") + sid = ida_struct.get_struc_id("ptrType") addr = self.getPtr(sid, offset, "elem") self.handle_offset(addr) def makeStructType(self, offset): idc.SetType(offset, "structType") - sid = idc.GetStrucIdByName("structType") - slice_id = idc.GetStrucIdByName("slice") - offset_elem = idc.GetMemberOffset(sid, "fields") - inner_offset = idc.GetMemberOffset(slice_id, "data") + sid = ida_struct.get_struc_id("structType") + slice_id = ida_struct.get_struc_id("slice") + offset_elem = idc.get_member_offset(sid, "fields") + inner_offset = idc.get_member_offset(slice_id, "data") addr = self.stepper.ptr(offset_elem + offset + inner_offset) - inner_offset = idc.GetMemberOffset(slice_id, "len") + inner_offset = idc.get_member_offset(slice_id, "len") size = self.stepper.ptr(offset+offset_elem+inner_offset) if size == 0: return idc.SetType(addr, "structField") - sz = idc.GetStrucSize(idc.GetStrucIdByName("structField")) + sz = ida_struct.get_struc_size(ida_struct.get_struc_id("structField")) self.make_arr(addr, size, sz, "structField") - sid_type = idc.GetStrucIdByName("type") + sid_type = ida_struct.get_struc_id("type") size_new_struct = self.getPtr(sid_type, offset, "size") for i in xrange(size): self.processStructField(addr, i*sz) @@ -395,7 +397,7 @@ def makeStructType(self, offset): def processStructField(self, addr, index): offset = addr + index - sid = idc.GetStrucIdByName("structField") + sid = ida_struct.get_struc_id("structField") ptr = self.getPtr(sid, offset, "Name") if ptr != 0: idc.SetType(ptr, "string") @@ -410,12 +412,12 @@ def getStructFieldOffset(self, sid, addr): def createUserTypeStruct(self, addr, name, size, self_size): fields = [] - sid = idc.GetStrucIdByName("structField") - sz = idc.GetStrucSize(sid) - sid_type = idc.GetStrucIdByName("type") + sid = ida_struct.get_struc_id("structField") + sz = ida_struct.get_struc_size(sid) + sid_type = ida_struct.get_struc_id("type") fields = [] curr_offset = 0 - idc.MakeComm(addr, name) + idc.set_cmt(addr, name, 0) for i in xrange(size): fieldname = self.nameFromOffset(self.getPtr(sid, addr+i*sz,"Name")) type_addr = self.getPtr(sid, addr+i*sz, "typ") @@ -433,7 +435,7 @@ def createUserTypeStruct(self, addr, name, size, self_size): curr_offset += 1 curr_offset += size if size != 0: - offset_kind = idc.GetMemberOffset(sid_type, "kind") + offset_kind = idc.get_member_offset(sid_type, "kind") kind_of_type = self.getKindEnumName(type_addr) print kind_of_type if kind_of_type == "STRUCT_": #Disabled for now @@ -461,15 +463,15 @@ def createUserTypeStruct(self, addr, name, size, self_size): curr_offset += 1 new_type = [(name, fields)] self.settings.structCreator.createTypes(new_type) - new_type_sid = idc.GetStrucIdByName(name) - sz = idc.GetStrucSize(new_type_sid) + new_type_sid = ida_struct.get_struc_id(name) + sz = ida_struct.get_struc_size(new_type_sid) if sz != self_size: print "%x" % addr raise("Error at creating structure") def getType(self, addr): print "%x" % addr - sid = idc.GetStrucIdByName("type") + sid = ida_struct.get_struc_id("type") name = self.getName(addr) if self.getKindEnumName(addr) != "PTR": while name[0] == "*": @@ -478,15 +480,15 @@ def getType(self, addr): def makeInterface(self, offset): idc.SetType(offset, "interfaceType") - ifaceid = idc.GetStrucIdByName("interfaceType") - meth_offs = idc.GetMemberOffset(ifaceid, "methods") - slice_id = idc.GetStrucIdByName("slice") - size_off = idc.GetMemberOffset(slice_id, "len") + ifaceid = ida_struct.get_struc_id("interfaceType") + meth_offs = idc.get_member_offset(ifaceid, "methods") + slice_id = ida_struct.get_struc_id("slice") + size_off = idc.get_member_offset(slice_id, "len") size = self.stepper.ptr(offset + meth_offs + size_off) if size != 0: addr = self.getPtr(slice_id, offset + meth_offs, "data") idc.SetType(addr, "imethod") - sz = idc.GetStrucSize(idc.GetStrucIdByName("imethod")) + sz = ida_struct.get_struc_size(ida_struct.get_struc_id("imethod")) self.make_arr(addr, size, sz, "imethod") names = self.processIMethods(addr, size) # For now only for go1.7 @@ -528,7 +530,7 @@ def __init__(self, pos, endpos, step, settings, base_type): def next(self): if self.pos >= self.end: raise StopIteration - value = idc.Dword(self.pos) + value = idc.get_wide_dword(self.pos) self.pos += 4 value = self.getOffset(value) return self.handle_offset(value) @@ -540,54 +542,54 @@ def getOffset(self, offset): def get_str(self, pos, len): out = "" for i in xrange(len): - out += chr(idc.Byte(pos+i)) + out += chr(idc.get_wide_byte(pos+i)) return out def getName(self, offset): - sid = idc.GetStrucIdByName("type") + sid = ida_struct.get_struc_id("type") name_off = self.getDword(sid, offset, "string") string_addr = self.getOffset(name_off) + 3 - ln = idc.Byte(string_addr-1) + ln = idc.get_wide_byte(string_addr-1) return self.get_str(string_addr, ln) def nameFromOffset(self, offset): addr = offset - return self.get_str(addr + 3, idc.Byte(addr + 2)) + return self.get_str(addr + 3, idc.get_wide_byte(addr + 2)) def getPtrToThis(self, sid, offset): - memb_offs = idc.GetMemberOffset(sid, "ptrtothis") - return idc.Dword(offset + memb_offs) + memb_offs = idc.get_member_offset(sid, "ptrtothis") + return idc.get_wide_dword(offset + memb_offs) def processStructField(self, addr, index): offset = addr + index - sid = idc.GetStrucIdByName("structField") + sid = ida_struct.get_struc_id("structField") ptr = self.getPtr(sid, offset, "Name") - ln = idc.Byte(ptr + 2) + ln = idc.get_wide_byte(ptr + 2) fieldName = self.get_str(ptr + 3, ln) Utils.rename(ptr, fieldName) ptr = self.getPtr(sid, offset, "typ") self.handle_offset(ptr) def processIMethods(self, offst, size): - sz = idc.GetStrucSize(idc.GetStrucIdByName("imethod")) + sz = ida_struct.get_struc_size(ida_struct.get_struc_id("imethod")) comm = [] for i in xrange(size): comm.append(self.processIMethod(offst + i * sz)) - idc.MakeComm(offst, "\n".join(comm)) + idc.set_cmt(offst, "\n".join(comm), 0) return comm def processIMethod(self, offst): - sid = idc.GetStrucIdByName("imethod") + sid = ida_struct.get_struc_id("imethod") name = self.getDword(sid, offst, "name") name += self.robase - name = self.get_str(name + 3, idc.Byte(name + 2)) + name = self.get_str(name + 3, idc.get_wide_byte(name + 2)) return name def processMethods(self, offst): - sid = idc.GetStrucIdByName("method__") + sid = ida_struct.get_struc_id("method__") name = self.getDword(sid, offst, "name") name += self.robase - name = self.get_str(name + 3, idc.Byte(name + 2)) + name = self.get_str(name + 3, idc.get_wide_byte(name + 2)) type_meth = self.getDword(sid, offst, "mtyp") type_meth_addr1 = self.robase + type_meth func_body1 = self.getDword(sid, offst, "ifn") @@ -598,7 +600,7 @@ def processMethods(self, offst): def makeMap(self, offset): idc.SetType(offset, "mapType") - sid = idc.GetStrucIdByName("mapType") + sid = ida_struct.get_struc_id("mapType") addr = self.getPtr(sid, offset, "key") self.handle_offset(addr) addr = self.getPtr(sid, offset, "elem") @@ -610,10 +612,10 @@ def makeMap(self, offset): def parseFuncType(self, offset): return - sid = idc.GetStrucIdByName("funcType") - in_size = idc.Word(offset + idc.GetMemberOffset(sid, "incount")) - out_size = idc.Word(offset + idc.GetMemberOffset(sid, "outcount")) - sz = idc.GetStrucSize(sid) + sid = ida_struct.get_struc_id("funcType") + in_size = idc.Word(offset + idc.get_member_offset(sid, "incount")) + out_size = idc.Word(offset + idc.get_member_offset(sid, "outcount")) + sz = ida_struct.get_struc_size(sid) for i in xrange(in_size + out_size): idc.SetType(offset + sz + i * self.stepper.size, "type *") diff --git a/GO_Utils/Utils.py b/GO_Utils/Utils.py index d4db54b..aca6ab3 100644 --- a/GO_Utils/Utils.py +++ b/GO_Utils/Utils.py @@ -1,3 +1,5 @@ +import ida_enum +import ida_struct import idc import string import random @@ -9,8 +11,8 @@ def __init__(self, ptr, size, maker): self.maker = maker -bits32 = bitZ(idc.Dword, 4, idc.MakeDword) -bits64 = bitZ(idc.Qword, 8, idc.MakeQword) +bits32 = bitZ(idc.get_wide_dword, 4, idc.create_dword) +bits64 = bitZ(idc.get_qword, 8, idc.create_qword) def id_generator(size=6, chars=string.ascii_uppercase + string.digits): @@ -18,10 +20,10 @@ def id_generator(size=6, chars=string.ascii_uppercase + string.digits): def rename(offset, name): - res = idc.MakeNameEx(offset, name, idc.SN_NOWARN) + res = idc.set_name(offset, name, idc.SN_NOWARN) if res == 0: name = name+"_autogen_"+id_generator() - idc.MakeNameEx(offset, name, idc.SN_NOWARN) + idc.set_name(offset, name, idc.SN_NOWARN) def relaxName(name): @@ -32,7 +34,7 @@ def relaxName(name): def get_bitness(addr): ptr = bits32 - if idc.GetSegmentAttr(addr, idc.SEGATTR_BITNESS) == 2: + if idc.get_segm_attr(addr, idc.SEGATTR_BITNESS) == 2: ptr = bits64 return ptr @@ -54,15 +56,15 @@ class StructCreator(object): def __init__(self, bt_obj): self.types_id = {} if bt_obj.size == 8: - self.uintptr = (idc.FF_QWRD|idc.FF_DATA, -1, bt_obj.size) + self.uintptr = (idc.FF_QWORD|idc.FF_DATA, -1, bt_obj.size) else: - self.uintptr = (idc.FF_DWRD | idc.FF_DATA, -1, bt_obj.size) + self.uintptr = (idc.FF_DWORD | idc.FF_DATA, -1, bt_obj.size) def createStruct(self, name): - sid = idc.GetStrucIdByName(name) + sid = ida_struct.get_struc_id(name) if sid != -1: - idc.DelStruc(sid) - sid = idc.AddStrucEx(-1, name, 0) + idc.del_struc(sid) + sid = idc.add_struc(-1, name, 0) self.types_id['name'] = sid return sid @@ -81,16 +83,16 @@ def fillStruct(self, sid, data): new_type = i[1] else: new_type = name + " *" - res = idc.AddStrucMember(sid, i[0], -1, i1, i2, i3) + res = idc.add_struc_member(sid, i[0], -1, i1, i2, i3) use_name = i[0] if res == -1: #Bad name #print "Bad name %s for struct member" % i[0] use_name = i[0] + "_autogen_"+id_generator() - idc.AddStrucMember(sid, use_name, -1, i1, i2, i3) + idc.add_struc_member(sid, use_name, -1, i1, i2, i3) if new_type is not None: - offset = idc.GetMemberOffset(sid, use_name) + offset = idc.get_member_offset(sid, use_name) #print "Setting %s as %s" % (i[0], new_type) - idc.SetType(idc.GetMemberId(sid, offset), new_type) + idc.SetType(idc.get_member_id(sid, offset), new_type) def makeStruct(self, i): print "Creating structure %s" % (i[0]) @@ -102,13 +104,13 @@ def createTypes(self, types): self.makeStruct(i) def createEnum(self, enum): - eid = idc.AddEnum(-1, enum[0], 0x1100000) #what is this flag? - idc.SetEnumBf(eid, 1) + eid = idc.add_enum(-1, enum[0], 0x1100000) #what is this flag? + ida_enum.set_enum_bf(eid, 1) val = 0 mask = 0x1f - idc.SetEnumWidth(eid, 1) + ida_enum.set_enum_width(eid, 1) for i in enum[1]: - idc.AddConstEx(eid, i, val, mask) + idc.add_enum_member(eid, i, val, mask) val += 1 def createEnums(self, enums): diff --git a/GO_Utils/__init__.py b/GO_Utils/__init__.py index 1cd0231..29af212 100644 --- a/GO_Utils/__init__.py +++ b/GO_Utils/__init__.py @@ -5,13 +5,15 @@ import Types import idc import idautils +import ida_ida +import ida_search class GoSettings(object): def __init__(self): self.storage = {} - self.bt_obj = Utils.get_bitness(idc.BeginEA()) + self.bt_obj = Utils.get_bitness(ida_ida.inf_get_min_ea()) self.structCreator = Utils.StructCreator(self.bt_obj) self.processor = None self.typer = None @@ -54,23 +56,25 @@ def renameFunctions(self): def getVersionByString(self): pos = idautils.Functions().next() - if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 31 30") != idc.BADADDR: + end_ea = idc.get_segm_end(pos) + + if ida_search.find_binary(pos, end_ea, "67 6f 31 2e 31 30", 16, idc.SEARCH_DOWN) != idc.BADADDR: return 'Go 1.10' - if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 39") != idc.BADADDR: + if ida_search.find_binary(pos, end_ea, "67 6f 31 2e 39", 16, idc.SEARCH_DOWN) != idc.BADADDR: return 'Go 1.9' - if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 38") != idc.BADADDR: + if ida_search.find_binary(pos, end_ea, "67 6f 31 2e 38", 16, idc.SEARCH_DOWN) != idc.BADADDR: return 'Go 1.8' - if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 37") != idc.BADADDR: + if ida_search.find_binary(pos, end_ea, "67 6f 31 2e 37", 16, idc.SEARCH_DOWN) != idc.BADADDR: return 'Go 1.7' - if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 36") != idc.BADADDR: + if ida_search.find_binary(pos, end_ea, "67 6f 31 2e 36", 16, idc.SEARCH_DOWN) != idc.BADADDR: return 'Go 1.6' - if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 35") != idc.BADADDR: + if ida_search.find_binary(pos, end_ea, "67 6f 31 2e 35", 16, idc.SEARCH_DOWN) != idc.BADADDR: return 'Go 1.5' - if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 34") != idc.BADADDR: + if ida_search.find_binary(pos, end_ea, "67 6f 31 2e 34", 16, idc.SEARCH_DOWN) != idc.BADADDR: return 'Go 1.4' - if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 33") != idc.BADADDR: + if ida_search.find_binary(pos, end_ea, "67 6f 31 2e 33", 16, idc.SEARCH_DOWN) != idc.BADADDR: return 'Go 1.3' - if idc.FindBinary(pos, idc.SEARCH_DOWN, "67 6f 31 2e 32") != idc.BADADDR: + if ida_search.find_binary(pos, end_ea, "67 6f 31 2e 32", 16, idc.SEARCH_DOWN) != idc.BADADDR: return 'Go 1.2' def createTyper(self, typ):