def check_before_upload(): reserved_id = idaapi.get_struc_id("reserverd_by_idarling") if reserved_id == ida_idaapi.BADADDR: # First time, create 20 structures for i in range(20): idaapi.add_struc(ida_idaapi.BADADDR, None) idaapi.add_struc(ida_idaapi.BADADDR, "reserverd_by_idarling")
class RTTIBaseClassDescriptor(RTTIStruc): msid = get_struc_id("PMD") if msid != BADADDR: del_struc(msid) msid = add_struc(0xFFFFFFFF, "PMD", False) add_struc_member(msid, "mdisp", BADADDR, FF_DATA | FF_DWRD, -1, 4) add_struc_member(msid, "pdisp", BADADDR, FF_DATA | FF_DWRD, -1, 4) add_struc_member(msid, "vdisp", BADADDR, FF_DATA | FF_DWRD, -1, 4) pmdid = msid pmdstruc = get_struc(pmdid) pmdsize = get_struc_size(pmdid) msid = get_struc_id("RTTIBaseClassDescriptor") if msid != BADADDR: del_struc(msid) msid = add_struc(0xFFFFFFFF, "RTTIBaseClassDescriptor", False) add_struc_member(msid, "pTypeDescriptor", BADADDR, FF_DATA | FF_DWRD | FF_0OFF, 00000000, 4) add_struc_member(msid, "numContainerBases", BADADDR, FF_DWRD | FF_DATA, -1, 4) add_struc_member(msid, "PMD", BADADDR, FF_DATA | FF_DWRD | FF_STRU, pmdid, pmdsize) add_struc_member(msid, "attributes", BADADDR, FF_DWRD | FF_DATA, -1, 4) tid = msid struc = get_struc(tid) size = get_struc_size(tid) print "Completed Registering RTTIBaseClassDescriptor"
def handle_new(self): new_name = self.new_name_w.text().encode('ascii', 'replace').strip().decode() if not itanium_mangler.check_identifier(new_name): ida_kernwin.warning('The name "%s" is invalid' % new_name) return struct_id = idc.get_struc_id(new_name) if struct_id != idc.BADADDR: if util.ask_yes_no( 'The struct "%s" already exists. Do you want to select it anyways?' % new_name): self.struct_id = struct_id self.accept() return return self.struct_id = idaapi.add_struc(idc.BADADDR, new_name, False) if self.struct_id == idc.BADADDR: ida_kernwin.warning('Creating struct with the name "%s" failed' % new_name) return self.accept()
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): 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 __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 get(name): id = idaapi.get_struc_id(name) if id == idaapi.BADADDR: try: raise DeprecationWarning except: logging.warn('%s.get auto-creation is being deprecated' % __name__, exc_info=True) id = idaapi.add_struc(idaapi.BADADDR, name) return instance(id)
def get(name): '''Returns an instance of the structure named ``name``.''' id = idaapi.get_struc_id(name) if id == idaapi.BADADDR: try: raise DeprecationWarning except: logging.warn("{:s}.get auto-creation is being deprecated".format( __name__, exc_info=True)) id = idaapi.add_struc(idaapi.BADADDR, name) return instance(id)
def __setstate__(self, state): ownername, baseoffset, _ = state identifier = idaapi.get_struc_id(ownername) if identifier == idaapi.BADADDR: raise LookupError, 'Failure creating a members_t for structure_t {!r}'.format( ownername) logging.warn( 'members_t : Creating structure %s -- [%x] %d members' % (ownername, baseoffset, len(members))) identifier = idaapi.add_struc(idaapi.BADADDR, ownername) self.baseoffset = baseoffset self.__owner = instance(identifier, offset=baseoffset) return
def __setstate__(self, state): name, (cmtt, cmtf), members = state identifier = idaapi.get_struc_id(name) if identifier == idaapi.BADADDR: logging.warn('Creating structure %s [%d fields]%s' % (name, len(members), ' // %s' % (cmtf or cmtt) if cmtf or cmtt else '')) identifier = idaapi.add_struc(idaapi.BADADDR, name) # FIXME: although set_struc_idx and stuff doesn't seem too important. idaapi.set_struc_cmt(identifier, cmtt, True) idaapi.set_struc_cmt(identifier, cmtf, False) self.__id = identifier self.__members = members return
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) classes[strip(rtd.class_name)] = [strip(b) for b in rchd.bases] MakeNameEx(vtable, "vtable__" + strip(rtd.class_name), 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 __setstate__(self, state): ownername, baseoffset, _ = state identifier = idaapi.get_struc_id(ownername) if identifier == idaapi.BADADDR: raise LookupError( "{:s}.instance({:s}).members.__setstate__ : Failure creating a members_t for structure_t {!r}" .format(__name__, self.owner.name, ownername)) logging.warn( "{:s}.instance({:s}).members.__setstate__ : Creating structure {:s} -- [{:+#x}] {:d} members" .format(__name__, self.owner.name, ownername, baseoffset, len(members))) identifier = idaapi.add_struc(idaapi.BADADDR, ownername) self.baseoffset = baseoffset self.__owner = instance(identifier, offset=baseoffset) return
def __setstate__(self, state): name, (cmtt, cmtf), members = state identifier = idaapi.get_struc_id(name) if identifier == idaapi.BADADDR: logging.warn( "{:s}.structure_t.__setstate__ : Creating structure {:s} [{:d} fields]{:s}" .format( __name__, name, len(members), " // {:s}".format(cmtf or cmtt) if cmtf or cmtt else '')) identifier = idaapi.add_struc(idaapi.BADADDR, name) idaapi.set_struc_cmt(identifier, cmtt, True) idaapi.set_struc_cmt(identifier, cmtf, False) self.__id = identifier self.__members = members return
def create_struct(name, fields, size): struct_id = idaapi.get_struc_id(name) # print struct_id if struct_id != idaapi.BADADDR: i = ida_kernwin.ask_yn( 0, "A class structure for %s already exists. Are you sure you want to remake it?" % name) if i == idaapi.BADADDR: return if i == 1: idaapi.del_struc_members(idaapi.get_struc(struct_id), 0, idaapi.get_struc_size(struct_id)) # struct_id = idc.AddStrucEx(idaapi.BADADDR, name + "_vtbl", 0) else: struct_id = idaapi.add_struc(idaapi.BADADDR, name, 0) if struct_id == idaapi.BADADDR: Warning( "Could not create the class structure!.\nPlease check something.") return sptr = idaapi.get_struc(struct_id) for off in fields: off, type_name, type_kind, field_name = fields[off] print( "Process field. Off = 0x%04X, type_name = %s (%d: %s), field_name = %s" % (off, type_name, type_kind, type_sizes[type_kind][0], field_name)) type_size = type_sizes[type_kind][1] ret = ida_struct.add_struc_member(sptr, field_name.decode(), off, flags_dict[type_size], None, type_size) if ret != 0: ida_kernwin.warning("Unknown error! Err = %d" % ret) return mptr = ida_struct.get_member(sptr, off) ida_struct.set_member_cmt( mptr, " --> %s (%d: %s)" % (type_name.decode(), type_kind, type_sizes[type_kind][0]), False) struct_size = ida_struct.get_struc_size(sptr) if size < struct_size: ida_kernwin.warning( "Struct create error! final size (%d) > instanse size (%d)" % (struct_size, size)) elif size > struct_size: for i in range(size - struct_size): ida_struct.add_struc_member(sptr, "dummy%d" % i, idaapi.BADADDR, idaapi.FF_BYTE, None, 1)
def add_struct(name, size): info = idaapi.get_inf_structure() if info.is_64bit(): step_size = 8 flag = idaapi.FF_DATA | idaapi.FF_QWORD else: step_size = 4 flag = idaapi.FF_DATA | idaapi.FF_DWORD id = idaapi.add_struc(idaapi.BADADDR, name) if id == idaapi.BADADDR: id = idaapi.get_struc_id(name) struc = idaapi.get_struc(id) for off in range(0, size, step_size): idaapi.add_struc_member(struc, f"field_{off:X}", off, flag, None, step_size)
class RTTIBaseClassDescriptor(RTTIStruc): msid = get_struc_id("RTTIBaseClassDescriptor") if msid != BADADDR: del_struc(msid) msid = add_struc(0xFFFFFFFF, "RTTIBaseClassDescriptor", False) add_struc_member(msid, "pTypeDescriptor", BADADDR, FF_DATA | FF_DWORD | FF_0OFF, u.mt_rva().tid, 4) add_struc_member(msid, "numContainerBases", BADADDR, FF_DWORD | FF_DATA, -1, 4) add_struc_member(msid, "PMD", BADADDR, FF_DATA | FF_DWORD | FF_0OFF, u.mt_rva().tid, 4) add_struc_member(msid, "attributes", BADADDR, FF_DWORD | FF_DATA, -1, 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 create_struct(name): """Create a structure. Args: name: The structure's name Returns: The sturct ID Raises: exceptions.SarkStructAlreadyExists: A struct with the same name already exists exceptions.SarkCreationFailed: Struct creation failed """ sid = idaapi.get_struc_id(name) if sid != idaapi.BADADDR: # The struct already exists. raise exceptions.SarkStructAlreadyExists( "A struct names {!r} already exists.".format(name)) sid = idaapi.add_struc(idaapi.BADADDR, name, 0) if sid == idaapi.BADADDR: raise exceptions.SarkStructCreationFailed("Struct creation failed.") return sid
def new(name, offset=0): """Create a new structure ``name`` and return an instance of it""" id = idaapi.add_struc(idaapi.BADADDR, name) assert id != idaapi.BADADDR # FIXME: we should probably move the new structure to the end of the list via set_struc_idx return instance(id, offset=offset)
def new(name, offset): '''Returns a new structure ``name`` using ``offset`` as it's base-offset.''' id = idaapi.add_struc(idaapi.BADADDR, name) assert id != idaapi.BADADDR # FIXME: we should probably move the new structure to the end of the list via set_struc_idx return instance(id, offset=offset)
def get(name): id = idaapi.get_struc_id(name) if id == idaapi.BADADDR: id = idaapi.add_struc(name) return instance(id)
def get(name): id = idaapi.get_struc_id(name) if id == idaapi.BADADDR: id = idaapi.add_struc(name) return instance(id)