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 __setstate__(self, state): ownername, index, name, (cmtt, cmtf), ofs, t = state fullname = '.'.join((owername, name)) identifier = idaapi.get_struc_id(ownername) if identifier == idaapi.BADADDR: logging.warn( "{:s}.instance({:s}).member_t : Creating structure {:s} -- [{:#x}] {:s}{:s}" .format( __name__, ownername, ownername, ofs, name, " // {:s}".format(cmtt or cmtf) if cmtt or cmtf else '')) identifier = idaapi.add_struc(idaapi.BADADDR, ownername) self.__owner = owner = instance(identifier, offset=0) flag, mytype, nbytes = t # FIXME: handle .strtype (strings), .ec (enums), .cd (custom) opinfo = idaapi.opinfo_t() opinfo.tid = 0 if mytype is None else mytype.id res = idaapi.add_struc_member(owner.ptr, name, ofs, flag, opinfo, nbytes) # FIXME: handle these errors properly # duplicate name if res == idaapi.STRUC_ERROR_MEMBER_NAME: if idaapi.get_member_by_name(owner.ptr, name).soff != ofs: newname = "{:s}_{:x}".format(name, ofs) logging.warn( "{:s}.instace({:s}).member_t : Duplicate name found for {:s}, renaming to {:s}." .format(__name__, ownername, name, newname)) idaapi.set_member_name(owner.ptr, ofs, newname) else: logging.info( "{:s}.instance({:s}).member_t : Field at {:+#x} contains the same name {:s}." .format(__name__, ownername, ofs, name)) # duplicate field elif res == idaapi.STRUC_ERROR_MEMBER_OFFSET: logging.info( "{:s}.instance({:s}).member_t : Field already found at {:+#x}. Overwriting with {:s}." .format(__name__, ownername, ofs, name)) idaapi.set_member_type(owner.ptr, ofs, flag, opinfo, nbytes) idaapi.set_member_name(owner.ptr, ofs, name) # invalid size elif res == idaapi.STRUC_ERROR_MEMBER_SIZE: logging.warn( "{:s}.instance({:s}).member_t : Issue creating structure member {:s} : {:#x}" .format(__name__, ownername, fullname, res)) # unknown elif res != idaapi.STRUC_ERROR_MEMBER_OK: logging.warn( "{:s}.instance({:s}).member_t : Issue creating structure member {:s} : {:#x}" .format(__name__, ownername, fullname, res)) self.__index = index self.__owner = owner idaapi.set_member_cmt(self.ptr, cmtt, True) idaapi.set_member_cmt(self.ptr, cmtf, False) return
def struct_member_offset(sid, name): """A version of IDA's GetMemberOffset() that also works with unions.""" struct = idaapi.get_struc(sid) if not struct: return None member = idaapi.get_member_by_name(struct, name) if not member: return None return member.soff
def __setstate__(self, state): ownername, index, name, (cmtt, cmtf), ofs, t = state identifier = idaapi.get_struc_id(ownername) if identifier == idaapi.BADADDR: logging.warn('member_t : Creating structure %s -- [%x] %s%s' % (ownername, ofs, name, ' // %s' % (cmtt or cmtf) if cmtt or cmtf else '')) identifier = idaapi.add_struc(idaapi.BADADDR, ownername) self.__owner = owner = instance(identifier, offset=0) flag, mytype, nbytes = t # FIXME: handle .strtype (strings), .ec (enums), .cd (custom) opinfo = idaapi.opinfo_t() opinfo.tid = 0 if mytype is None else mytype.id res = idaapi.add_struc_member(owner.ptr, name, ofs, flag, opinfo, nbytes) # FIXME: handle these errors properly # duplicate name if res == idaapi.STRUC_ERROR_MEMBER_NAME: if idaapi.get_member_by_name(owner.ptr, name).soff != ofs: newname = '%s_%x' % (name, ofs) logging.warn( 'structure_t(%s).member_t : Duplicate name found for %s, renaming to %s' % (ownername, name, newname)) idaapi.set_member_name(owner.ptr, ofs, newname) else: logging.info( 'structure_t(%s).member_t : Field at %x contains the same name %s' % (ownername, ofs, name)) # duplicate field elif res == idaapi.STRUC_ERROR_MEMBER_OFFSET: logging.info( 'structure_t(%s).member_t : Field already found at %x. Overwriting with %s' % (ownername, ofs, name)) idaapi.set_member_type(owner.ptr, ofs, flag, opinfo, nbytes) idaapi.set_member_name(owner.ptr, ofs, name) # invalid size elif res == idaapi.STRUC_ERROR_MEMBER_SIZE: logging.warn( 'member_t : Issue creating structure member %s.%s : %x' % (ownername, name, res)) # unknown elif res != idaapi.STRUC_ERROR_MEMBER_OK: logging.warn( 'member_t : Issue creating structure member %s.%s : %x' % (ownername, name, res)) self.__index = index self.__owner = owner idaapi.set_member_cmt(self.ptr, cmtt, True) idaapi.set_member_cmt(self.ptr, cmtf, False) return
def by_name(self, name): '''Return the member with the specified ``name``.''' mem = idaapi.get_member_by_name(self.owner.ptr, str(name)) if mem is None: raise KeyError( "{:s}.instance({:s}).members.by_name : Unable to find member with requested name : {!r}" .format(__name__, self.owner.name, name)) index = self.index(mem) return self[index]
def __call__(self): sptr = idaapi.get_struc(idc.get_struc_id(self.sname.encode('utf-8'))) if self.smname: mptr = idaapi.get_member_by_name(sptr, self.smname.encode('utf-8')) idaapi.set_member_cmt(mptr, self.cmt.encode('utf-8') if self.cmt else '', self.repeatable_cmt) else: idaapi.set_struc_cmt(sptr.id, self.cmt.encode('utf-8') if self.cmt else '', self.repeatable_cmt)
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 set_struct_member(structname, name, flag_andTypeID, size): id = idc.get_struc_id(str(structname)) offset = -1 flag = flag_andTypeID.get("flag") typeid = flag_andTypeID.get("typeid") nbytes = size try: ok = 0 if not idaapi.get_member_by_name( idaapi.get_struc(idaapi.get_struc_id(str(structname))), str(name)): ok = idc.add_struc_member(id, str(name), offset, flag, typeid, nbytes) if not ok: if not idaapi.get_member_by_name( idaapi.get_struc(idaapi.get_struc_id(str(structname))), str(name)): print("Could not add struct member {name} at {structname}". format(name=name, structname=structname)) except: pass
def get_member_from_struct(ea, sname, mname): """ get_member_from_struct: ea, sname, mname Retrieves a DWORD member named 'mname' from struct 'sname' starting at address 'ea'. """ sid = idaapi.get_struc_id(sname) stru = idaapi.get_struc(sid) member = idaapi.get_member_by_name(stru, mname) # TODO check size return idc.Dword(ea + member.soff)
def __init__(self, ea): name = ea + get_member_by_name(self.struc, "name").soff strlen = u.get_strlen(name) if strlen is None: # not a real vtable return self.size = self.size + strlen mangled = get_ascii_contents(name, strlen, 0) if mangled is None: # not a real function name return print "Mangled: " + mangled demangled = demangle_name('??_R0' + mangled[1:], 0) if demangled: do_unknown_range(ea, self.size, DOUNK_DELNAMES) if doStruct(ea, self.size, self.tid): print " Made td at 0x%x: %s" % (ea, demangled) self.class_name = demangled return print " FAIL :(" return
def __init__(self, ea): name = ea + get_member_by_name(get_struc(self.tid), "name").soff strlen = u.get_strlen(name) if strlen is None: # not a real vtable return self.size = self.size + strlen mangled = get_strlit_contents(name, strlen, 0) if mangled is None: # not a real function name return print("Mangled: " + mangled) demangled = demangle_name('??_R0' + mangled[1:], 0) if demangled: del_items(ea, self.size, DELIT_DELNAMES) if create_struct(ea, self.size, self.tid): print(" Made td at 0x%x: %s" % (ea, demangled)) self.class_name = demangled return print(" FAIL :(") return
def byname(self, name): index = idaapi.get_member_by_name(self.owner.ptr, name) return self[index]
def byName(self, name): mem = idaapi.get_member_by_name(self.owner.ptr, str(name)) if mem is None: raise KeyError, name index = self.index(mem) return self[index]