def __init__(self, ea, vtable): do_unknown_range(ea, self.size, DOUNK_DELNAMES) if doStruct(ea, self.size, self.tid): # Get adress of type descriptor from CompleteLocator print "Complete Object Locator at: 0x%x" % ea offset = get_member_by_name(self.struc, "pTypeDescriptor").soff typeDescriptor = get_32bit(ea + offset) + u.x64_imagebase() print "Looking for type Descriptor at: 0x%x" % typeDescriptor rtd = RTTITypeDescriptor(typeDescriptor) if rtd.class_name: print "Type Descriptor at: 0x%x" % typeDescriptor offset = get_member_by_name(self.struc, "pClassDescriptor").soff classHierarchyDes = get_32bit(ea + offset) + u.x64_imagebase() rchd = RTTIClassHierarchyDescriptor(classHierarchyDes) # filter out None entries rchd.bases = filter(lambda x: x, rchd.bases) className = strip(rtd.class_name) classes[className] = [strip(b) for b in rchd.bases] vtables[className] = vtable MakeNameEx(vtable, "vtable__" + className, SN_NOWARN) else: # if the RTTITypeDescriptor doesn't have a valid name for us to # read, then this wasn't a valid RTTICompleteObjectLocator MakeUnknown(ea, self.size, DOUNK_SIMPLE)
def __init__(self, ea, vtable): filepath = GetIdbPath()[:-4] fp = open(r"{filepath}.txt".format(filepath=filepath), 'a') # fp.write(filepath) print "Create file" do_unknown_range(ea, self.size, DOUNK_DELNAMES) if doStruct(ea, self.size, self.tid): # Get adress of type descriptor from CompleteLocator # print "Complete Object Locator at: 0x%x" % ea offset = get_member_by_name(self.struc, "pTypeDescriptor").soff typeDescriptor = get_32bit(ea + offset) + u.x64_imagebase() # print "Looking for type Descriptor at: 0x%x" % typeDescriptor rtd = RTTITypeDescriptor(typeDescriptor) if rtd.class_name: # print "Type Descriptor at: 0x%x" % typeDescriptor offset = get_member_by_name(self.struc, "pClassDescriptor").soff classHierarchyDes = get_32bit(ea + offset) + u.x64_imagebase() rchd = RTTIClassHierarchyDescriptor(classHierarchyDes) # filter out None entries rchd.bases = filter(lambda x: x, rchd.bases) classes[strip(rtd.class_name)] = [strip(b) for b in rchd.bases] MakeNameEx(vtable, "vtable__" + strip(rtd.class_name), SN_NOWARN) tempStr = hex(vtable).rstrip('L') + '\t' + strip( rtd.class_name) + '\t' + str(GuessType( Dword(vtable + 4))) + '\n' if ('std' not in tempStr[:15] and 'ATL' not in tempStr[:15]): fp.write(tempStr) else: # if the RTTITypeDescriptor doesn't have a valid name for us to # read, then this wasn't a valid RTTICompleteObjectLocator MakeUnknown(ea, self.size, DOUNK_SIMPLE) fp.close()
def check_address(address): # Checks if given address contains virtual table. Returns True if more than 2 function pointers found # Also if table's addresses point to code in executable section, than tries to make functions at that addresses if helper.is_code_ea(address): return False if not idaapi.get_name(address): return False functions_count = 0 while True: func_address = idaapi.get_64bit( address) if const.EA64 else idaapi.get_32bit(address) # print "[INFO] Address 0x{0:08X}".format(func_address) if helper.is_code_ea(func_address) or helper.is_imported_ea( func_address): functions_count += 1 address += const.EA_SIZE else: segment = idaapi.getseg(func_address) if segment and segment.perm & idaapi.SEGPERM_EXEC: idc.MakeUnknown(func_address, 1, idaapi.DOUNK_SIMPLE) if idc.MakeFunction(func_address): functions_count += 1 address += const.EA_SIZE continue break idaapi.autoWait() return functions_count
def get_word(ea): info = idaapi.get_inf_structure() if info.is_32bit(): return idaapi.get_32bit(ea) elif info.is_64bit(): return idaapi.get_64bit(ea) return BADADDR
def get_address(ea): if TARGET_ADDRESS_SIZE == 8: res = idaapi.get_64bit(ea) elif TARGET_ADDRESS_SIZE == 4: res = idaapi.get_32bit(ea) else: raise RuntimeError("Platform is not 64 or 32 bit") return (ea + TARGET_ADDRESS_SIZE, res)
def get_ptr(ea): """ Reads ptr at specified address. """ if const.EA64: return idaapi.get_64bit(ea) ptr = idaapi.get_32bit(ea) if idaapi.cvar.inf.procname == "ARM": ptr &= -2 # Clear thumb bit return ptr
def __init__(self, ea): #: The address of the start of this RTTI object self.ea = ea #: A list (in inheritance order) of the parent RTTI objects self.parents = [] # first entry is the vptr for the typeinfo ea, _ = get_address(ea) ea, self.nameptr = get_address(ea) #: The name present in this RTTI entry self.name = idc.GetString(self.nameptr) # After the name is either the base class typeinfo pointer # (in the case of single inheritance), or an array of # typeinfos for each base (in multiple inheritance) _, baseaddr = get_address(ea) # Crude test for whether the address seems like a # plausible location for the baseclass typeinfo if in_same_segment(baseaddr, ea): self.parents = [ItaniumTypeInfo(baseaddr)] return # Either this is multiple inheritance or no inheritance flags = idaapi.get_32bit(ea) count = idaapi.get_32bit(ea + 4) ea += 8 # Only valid '__flags' are 0, 1, and 2 if flags not in [0, 1, 2]: return self.flags = flags for i in range(count): ea, baseaddr = get_address(ea) self.parents.append(ItaniumTypeInfo(baseaddr)) # For now ignore the '__offset_flags' ea += TARGET_ADDRESS_SIZE
def parse_vmi_typeinfo(cls, typeinfo_ea): base_classes_num = idaapi.get_32bit(typeinfo_ea + cls.VMI_TYPEINFO_BASE_CLASSES_NUM_OFFSET) parents = [] for i in range(base_classes_num): base_class_desc_ea = ( typeinfo_ea + cls.VMI_TYPEINFO_BASE_CLASSES_OFFSET + i * cls.BASE_CLASS_SIZE ) parent_typeinfo_ea = utils.get_ptr(base_class_desc_ea + cls.BASE_CLASS_TYPEINFO_OFFSET) parent_attrs = utils.get_word(base_class_desc_ea + cls.BASE_CLASS_ATTRS_OFFSET) parent_offset_in_cls = parent_attrs >> 8 parents.append((parent_typeinfo_ea, parent_offset_in_cls)) return parents
def __init__(self, ea): print "Processing Class Hierarchy Descriptor at 0x%x" % ea do_unknown_range(ea, get_struc_size(self.tid), DOUNK_DELNAMES) if doStruct(ea, get_struc_size(self.tid), self.tid): baseClasses = get_32bit(ea + get_member_by_name( self.struc, "pBaseClassArray").soff) + u.x64_imagebase() nb_classes = get_32bit( ea + get_member_by_name(self.struc, "numBaseClasses").soff) print "Baseclasses array at 0x%x" % baseClasses # Skip the first base class as it is itself (could check) self.bases = [] for i in range(1, nb_classes): baseClass = get_32bit(baseClasses + i * 4) + u.x64_imagebase() print "base class 0x%x" % baseClass doDwrd(baseClasses + i * 4, 4) op_offset(baseClasses + i * 4, -1, u.REF_OFF | REFINFO_RVA, -1, 0, 0) doStruct(baseClass, RTTIBaseClassDescriptor.size, RTTIBaseClassDescriptor.tid) typeDescriptor = get_32bit(baseClass) + u.x64_imagebase() self.bases.append( RTTITypeDescriptor(typeDescriptor).class_name)
def populate(self): address = self.address while True: if Const.EA64: func_address = idaapi.get_64bit(address) else: func_address = idaapi.get_32bit(address) flags = idaapi.getFlags(func_address) # flags_t if idaapi.isCode(flags): self.virtual_functions.append(VirtualFunction(func_address, address - self.address)) address += Const.EA_SIZE else: break
def populate(self): address = self.address while True: if Const.EA64: func_address = idaapi.get_64bit(address) else: func_address = idaapi.get_32bit(address) if Helper.is_code_ea(func_address): self.virtual_functions.append(VirtualFunction(func_address, address - self.address)) elif Helper.is_imported_ea(func_address): self.virtual_functions.append(ImportedVirtualFunction(func_address, address - self.address)) else: break address += Const.EA_SIZE if idaapi.get_first_dref_to(address) != idaapi.BADADDR: break
def check_address(address): # Checks if given address contains virtual table. Returns True if more than 2 function pointers found # Also if table's addresses point to code in executable section, than tries to make functions at that addresses functions_count = 0 while True: func_address = idaapi.get_64bit( address) if Const.EA64 else idaapi.get_32bit(address) # print "[INFO] Address 0x{0:08X}".format(func_address) if Helper.is_code_ea(func_address) or Helper.is_imported_ea( func_address): functions_count += 1 address += Const.EA_SIZE else: segment = idaapi.getseg(func_address) if segment and segment.perm & idaapi.SEGPERM_EXEC: idc.del_items(func_address, 1, idaapi.DELIT_SIMPLE) if idc.add_func(func_address): functions_count += 1 address += Const.EA_SIZE continue break idaapi.autowait() return functions_count
def get_word(ea): if WORD_LEN == 4: return idaapi.get_32bit(ea) elif WORD_LEN == 8: return idaapi.get_64bit(ea) return None
def read_signed_32bit(ea): return (ea + 4, idaapi.as_signed(idaapi.get_32bit(ea), 32))
def read_ea(ea): return (ea + 4, idaapi.get_32bit(ea))