def set_ida_struct(struct: Struct, controller) -> bool: # first, delete any struct by the same name if it exists sid = ida_struct.get_struc_id(struct.name) if sid != 0xffffffffffffffff: sptr = ida_struct.get_struc(sid) ida_struct.del_struc(sptr) # now make a struct header ida_struct.add_struc(ida_idaapi.BADADDR, struct.name, False) sid = ida_struct.get_struc_id(struct.name) sptr = ida_struct.get_struc(sid) # expand the struct to the desired size # XXX: do not increment API here, why? Not sure, but you cant do it here. ida_struct.expand_struc(sptr, 0, struct.size) # add every member of the struct for off, member in struct.struct_members.items(): # convert to ida's flag system mflag = convert_size_to_flag(member.size) # create the new member ida_struct.add_struc_member( sptr, member.member_name, member.offset, mflag, None, member.size, ) return True
def defENTENT(): sid = ida_struct.get_struc_id("ENTENT") if sid != ida_idaapi.BADADDR: struc = ida_struct.get_struc(sid) ida_struct.del_struc(struc) sid = ida_struct.add_struc(ida_idaapi.BADADDR, "ENTENT", 0) struc = ida_struct.get_struc(sid) ida_struct.add_struc_member(struc, "flags", ida_idaapi.BADADDR, FF_BYTE, None, 1) ida_struct.add_struc_member(struc, "addr", ida_idaapi.BADADDR, FF_WORD, None, 2) return sid
def update_idb(self): sid = ida_struct.get_struc_id(self._name) if sid != -1: sptr = ida_struct.get_struc(sid) ida_struct.del_struc(sptr) sid = ida_struct.add_struc(idc.BADADDR, self._name, 0) sptr = ida_struct.get_struc(sid) for f in self._fields: ida_struct.add_struc_member(sptr, f.name, idc.BADADDR, (idc.FF_BYTE | idc.FF_DATA) & 0xFFFFFFFF, None, 1) member_name = "{}.{}".format(self._name, f.name) idc.SetType( idaapi.get_member_by_fullname(member_name)[0].id, f.type) ida_auto.auto_wait()
def defSEGENT(): sid = ida_struct.get_struc_id("SEGENT") if sid != ida_idaapi.BADADDR: struc = ida_struct.get_struc(sid) ida_struct.del_struc(struc) sid = ida_struct.add_struc(ida_idaapi.BADADDR, "SEGENT", 0) struc = ida_struct.get_struc(sid) ida_struct.add_struc_member(struc, "flags", ida_idaapi.BADADDR, ida_bytes.FF_WORD, None, 2) ida_struct.add_struc_member(struc, "oSegment", ida_idaapi.BADADDR, ida_bytes.FF_WORD, None, 2) ida_struct.add_struc_member(struc, "nParagraphs", ida_idaapi.BADADDR, ida_bytes.FF_WORD, None, 2) ida_struct.add_struc_member(struc, "nReloc", ida_idaapi.BADADDR, ida_bytes.FF_WORD, None, 2) ida_struct.add_struc_member(struc, "minAlloc", ida_idaapi.BADADDR, ida_bytes.FF_WORD, None, 2) ida_struct.add_struc_member(struc, "unused", ida_idaapi.BADADDR, ida_bytes.FF_WORD, None, 2) return sid
class RTTICompleteObjectLocator(RTTIStruc): # Init class statics msid = get_struc_id("RTTICompleteObjectLocator") if msid != BADADDR: del_struc(get_struc(msid)) msid = add_struc(0xFFFFFFFF, "RTTICompleteObjectLocator", False) add_struc_member(get_struc(msid), "signature", BADADDR, FF_DATA | FF_DWRD, None, 4) add_struc_member(get_struc(msid), "offset", BADADDR, FF_DATA | FF_DWRD, None, 4) add_struc_member(get_struc(msid), "cdOffset", BADADDR, FF_DATA | FF_DWRD, None, 4) add_struc_member(get_struc(msid), "pTypeDescriptor", BADADDR, FF_DATA | FF_DWRD | FF_0OFF, u.mt_rva(), 4) add_struc_member(get_struc(msid), "pClassDescriptor", BADADDR, FF_DATA | FF_DWRD | FF_0OFF, u.mt_rva(), 4) if u.x64: add_struc_member(get_struc(msid), "pSelf", BADADDR, FF_DATA | FF_DWRD | FF_0OFF, u.mt_rva(), 4) tid = msid struc = get_struc(tid) size = get_struc_size(tid) print "Completed Registering RTTICompleteObjectLocator" 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 _prepare_ida_type(self): if hasattr(self, "tid") and self.tid is not None: raise RuntimeError("May not call _prepare_ida_type twice") # Find existing structure self.tid = ida_struct.get_struc_id(self.name) if self.tid != BADADDR: # Grab structure pointer self._get_sptr() # Struct with given name already exists, validate it if self._validate_ida_type(): self.log.info("Found struct '%s' with ID %d", self.name, self.tid) return # Successful # Existing struct not valid, ask user whether to overwrite query = ida_kernwin.ask_yn( ida_kernwin.ASKBTN_NO, "A structure named '{}' already exists but does not match the needed format. Do you wish to overwrite it?" .format(self.name)) if query != ida_kernwin.ASKBTN_YES: raise RuntimeError("User cancelled operation") # Delete existing struct if not ida_struct.del_struc(self.sptr): raise RuntimeError( "Could not delete existing structure '{}'".format( self.name)) self.log.info("Deleted struct '%s' (ID=%d)", self.name, self.tid) self.tid = None self.sptr = None # Create struct self.tid = ida_struct.add_struc(BADADDR, self.name) if self.tid is None or self.tid == BADADDR: raise RuntimeError("Could not create structure '{}'".format( self.name)) # Grab structure pointer self._get_sptr() # Create members for f in self.members_array: f._prepare_ida_type() self.log.info("Created struct '%s' of size %d", self.name, self.size)
class RTTIBaseClassDescriptor(RTTIStruc): msid = get_struc_id("RTTIBaseClassDescriptor") if msid != BADADDR: del_struc(get_struc(msid)) msid = add_struc(0xFFFFFFFF, "RTTIBaseClassDescriptor", False) add_struc_member(get_struc(msid), "pTypeDescriptor", BADADDR, FF_DATA | FF_DWRD | FF_0OFF, u.mt_rva(), 4) add_struc_member(get_struc(msid), "numContainerBases", BADADDR, FF_DWRD | FF_DATA, None, 4) add_struc_member(get_struc(msid), "PMD", BADADDR, FF_DATA | FF_DWRD | FF_0OFF, u.mt_rva(), 4) add_struc_member(get_struc(msid), "attributes", BADADDR, FF_DWRD | FF_DATA, None, 4) tid = msid struc = get_struc(tid) size = get_struc_size(tid) print "Completed Registering RTTIBaseClassDescriptor"
class RTTIClassHierarchyDescriptor(RTTIStruc): bases = None msid = get_struc_id("RTTIClassHierarchyDescriptor") if msid != BADADDR: del_struc(get_struc(msid)) msid = add_struc(0xFFFFFFFF, "RTTIClassHierarchyDescriptor", False) add_struc_member(get_struc(msid), "signature", BADADDR, FF_DWRD | FF_DATA, None, 4) add_struc_member(get_struc(msid), "attribute", BADADDR, FF_DWRD | FF_DATA, None, 4) add_struc_member(get_struc(msid), "numBaseClasses", BADADDR, FF_DWRD | FF_DATA, None, 4) add_struc_member(get_struc(msid), "pBaseClassArray", BADADDR, FF_DATA | FF_DWRD | FF_0OFF, u.mt_rva(), 4) tid = msid struc = get_struc(tid) print "Completed Registering RTTIClassHierarchyDescriptor" 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(get_struc( self.tid), "pBaseClassArray").soff) + u.x64_imagebase() nb_classes = get_32bit( ea + get_member_by_name(get_struc(self.tid), "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)
class RTTITypeDescriptor(RTTIStruc): class_name = None msid = get_struc_id("RTTITypeDescriptor") if msid != BADADDR: del_struc(get_struc(msid)) msid = add_struc(0xFFFFFFFF, "RTTITypeDescriptor", False) add_struc_member(get_struc(msid), "pVFTable", BADADDR, FF_DATA | u.PTR_TYPE | FF_0OFF, u.mt_address(), u.PTR_SIZE) add_struc_member(get_struc(msid), "spare", BADADDR, FF_DATA | u.PTR_TYPE, None, u.PTR_SIZE) add_struc_member(get_struc(msid), "name", BADADDR, FF_DATA | FF_ASCI, u.mt_ascii(), 0) tid = msid struc = get_struc(tid) size = get_struc_size(tid) print "Completed Registering RTTITypeDescriptor" 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_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 __call__(self): ida_struct.del_struc(ida_struct.get_struc_id(Event.encode(self.sname)))
def __call__(self): struc = ida_struct.get_struc_id(self.sname) ida_struct.del_struc(ida_struct.get_struc(struc))
def implement(self): ida_struct.del_struc(ida_struct.get_struc(self._id))
def implement(self): id_of_struct = ida_struct.get_struc_id(str(self._id)) sturct_obj = ida_struct.get_struc(long(id_of_struct)) ida_struct.del_struc(sturct_obj)