def handle_classes(idx, formatter): name = u.vtname(ti_names[idx]) ea = LocByName(name) if ea == BADADDR: # try single underscore name = name[1:] ea = LocByName(name) if ea == BADADDR: print("Could not find vtable for %s" % ti_names[idx]) return idx = 0 handled = set() while ea != BADADDR: print("Looking for refs to vtable %08X" % ea) if idaapi.is_spec_ea(ea): xrefs = u.xref_or_find(ea, True) ea += u.PTR_SIZE * 2 xrefs.extend(u.xref_or_find(ea, True)) else: ea += u.PTR_SIZE * 2 xrefs = u.xref_or_find(ea, True) for x in xrefs: if not u.is_bad_addr(x) and not x in handled: print("found %s at %08X" % (name, x)) ea2 = formatter(x) handled.add(x) ea = LocByName("%s_%d" % (name, idx)) idx += 1
def ForcePtr(self, ea, delta=0): if self.x64: self.ForceQword(ea) else: self.ForceDword(ea) if GetFixupTgtType(ea) != -1 and isOff0(get_full_flags(ea)): # don't touch fixups return pv = self.get_ptr(ea) if pv != 0 and pv != BADADDR: # apply offset again if idaapi.is_spec_ea(pv): delta = 0 OpOffEx(ea, 0, [REF_OFF32, REF_OFF64][self.x64], -1, 0, delta)
def get_typeinfo_refs(name, ea): if ea == idc.BADADDR: return ea2 = ea if idaapi.is_spec_ea(ea2): xrefs = find_xrefs(ea2) ea2 += get_address_size_in_bytes()*2 xrefs.extend(find_xrefs(ea2)) else: ea2 += get_address_size_in_bytes()*2 xrefs = find_xrefs(ea2) for x in xrefs: if not is_invalid_ea(x): value = read_pointer(x) offset = value - ea if value > ea else 0 RTTI_REFERENCE_TABLE[x] = _create_reference_object(name, ea, offset) ea3 = get_si_type_info(x)
def run_gcc(): classes = {} # turn on GCC3 demangling idaapi.cvar.inf.demnames |= idaapi.DEMNAM_GCC3 print("Looking for standard type info classes") find_type_info(TI_TINFO) find_type_info(TI_CTINFO) find_type_info(TI_SICTINFO) find_type_info(TI_VMICTINFO) print("Looking for simple classes") handle_classes(TI_CTINFO, format_type_info) print("Looking for single-inheritance classes") handle_classes(TI_SICTINFO, format_si_type_info) print("Looking for multiple-inheritance classes") handle_classes(TI_VMICTINFO, format_vmi_type_info) for i in range(len(all_classes)): tiaddr = u.num2key(all_classes)[i] klass = all_classes[tiaddr] name = classname(klass.namestr) ti = "%08X" % tiaddr vt = "%08X" % klass.vtable basestr = [] for b in klass.bases: if b.ti in all_classes: bklass = all_classes[b.ti] basename = classname(bklass.namestr) elif idaapi.is_spec_ea(b.ti): nm = Name(b.ti) basename = tinfo2class(nm) else: print("Base %08X not found for class %08X!" % (b.ti, tiaddr)) basename = "ti_%08X" % b.ti basestr.append(basename) classes[name] = basestr print("basestr: \"%s\"" % basestr) return classes
def is_bad_addr(self, ea): return ea == 0 or ea == BADADDR or idaapi.is_spec_ea( ea) or not isLoaded(ea)