def fix_relocs(base_address, relocs_address, relocs_size): cursor = relocs_address end = relocs_address+relocs_size multiplier = 4 * (idaapi.get_dword(cursor) & 1) + 4 cursor += 4 print 'starting to fix relocs...' nb_relocs = 0 delta = idaapi.get_dword(cursor) while delta != 0xFFFFFFFF and cursor < end: current_reloc = base_address + delta while True: decorated_addr = idaapi.get_qword(current_reloc) if decorated_addr & 0x4000000000000000 == 0: if decorated_addr & 0x8000000000000000: #tagged ptr sign_type = (decorated_addr >> 49) & 3 real_addr = base_address + (decorated_addr & 0xFFFFFFFF) modifier = ((decorated_addr >> 32) & 0xFFFF) if decorated_addr & 0x1000000000000: if modifier == 0: modifier = current_reloc modifier_type = 'ptr_addr' else: modifier_type = '0x%X << 48 | ptr_addr & 0xFFFFFFFFFFFF'%(modifier) modifier = (current_reloc & 0xFFFFFFFFFFFF) | (modifier << 48) else: modifier_type = '0x%X'%modifier if sign_type == 0: decorator = 'PACIA %s'%modifier_type if modifier else 'PACIZA' elif sign_type == 1: decorator = 'PACIB %s'%modifier_type if modifier else 'PACIZB' elif sign_type == 2: decorator = 'PACDA %s'%modifier_type if modifier else 'PACDZA' elif sign_type == 3: decorator = 'PACDB %s'%modifier_type if modifier else 'PACDZB' idaapi.set_cmt(current_reloc , decorator, 1) else: real_addr = ((decorated_addr << 13) & 0xFF00000000000000) | (decorated_addr & 0x7ffffffffff) if decorated_addr & 0x40000000000: real_addr |= 0xfffc0000000000 idaapi.patch_qword(current_reloc, real_addr) idaapi.op_offset(current_reloc, 0, idaapi.REF_OFF64) nb_relocs += 1 delta_next_reloc = ((decorated_addr >> 51) & 0x7ff) * multiplier if delta_next_reloc == 0: break current_reloc += delta_next_reloc cursor += 4 delta = idaapi.get_dword(cursor) print '%d relocs fixed!'%nb_relocs
def fixupSysctlSet(): ''' fixupSysctlSet: Fixes up the '__sysctl_set' segment, ensures the targets are actually 'sysctl_oid' structures and adds the correct function type to the handler. ''' segm = idaapi.get_segm_by_name("__DATA:__sysctl_set") if not segm: segm = idaapi.get_segm_by_name("__sysctl_set") if not segm: print "Could not find kernel __sysctl_set section" return segea = segm.startEA segend = segm.endEA sid = get_struc_id("sysctl_oid") ssize = get_struc_size(sid) stru = get_struc(sid) if ssize == 0: print "Could not load information about 'sysctl_oid' struct" return # clear whole range of sysctl_set segment idaapi.do_unknown_range(segea, segend - segea, DOUNK_DELNAMES) # idapython oldschool - we work with the structure offset oid_handler = get_member_by_name(stru, "oid_handler") # loop through sysctl_set segment while segea < segend: # Ensure pointer is a pointer idaapi.op_offset(segea, 0, idaapi.REF_OFF32, 0xffffffff, 0, 0) ptr = idc.Dword(segea) # Mark structure as sysctl_oid structure idaapi.do_unknown_range(ptr, ssize, DOUNK_DELNAMES) x = doStruct(ptr, ssize, sid) handler = idc.Dword(ptr + oid_handler.soff) # We have to support ARM THUMB code addr = handler & 0xFFFFFFFE # Set correct function type for oid_handler idc.SetType( addr, "int *oid_handler(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);" ) segea += 4
def fixupSysctlSet(): ''' fixupSysctlSet: Fixes up the '__sysctl_set' segment, ensures the targets are actually 'sysctl_oid' structures and adds the correct function type to the handler. ''' segm = idaapi.get_segm_by_name("__DATA:__sysctl_set") if not segm: segm = idaapi.get_segm_by_name("__sysctl_set") if not segm: print "Could not find kernel __sysctl_set section" return segea = segm.startEA segend = segm.endEA sid = get_struc_id("sysctl_oid") ssize = get_struc_size(sid) stru = get_struc(sid) if ssize == 0: print "Could not load information about 'sysctl_oid' struct" return # clear whole range of sysctl_set segment idaapi.do_unknown_range(segea, segend-segea, DOUNK_DELNAMES) # idapython oldschool - we work with the structure offset oid_handler = get_member_by_name(stru, "oid_handler") # loop through sysctl_set segment while segea < segend: # Ensure pointer is a pointer idaapi.op_offset(segea, 0, idaapi.REF_OFF32, 0xffffffff, 0, 0) ptr = idc.Dword(segea) # Mark structure as sysctl_oid structure idaapi.do_unknown_range(ptr, ssize, DOUNK_DELNAMES) x = doStruct(ptr, ssize, sid) handler = idc.Dword(ptr + oid_handler.soff) # We have to support ARM THUMB code addr = handler & 0xFFFFFFFE # Set correct function type for oid_handler idc.SetType(addr, "int *oid_handler(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);") segea += 4
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)