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
示例#3
0
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
示例#4
0
 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)