Example #1
0
    def define(ea):
        if CompleteObjectLocator.isDefined(ea):
            return
        if not CompleteObjectLocator.isValid(ea):
            raise RttiError(
                "%08X: doesn't look like a correct CompleteObjectLocator" %
                (ea))

        # Ensure referenced structs are defined.
        # An exception will be thrown if something goes wrong.
        tdPtr = idaapi.get_full_long(ea + 12)
        td = TypeDescriptor(tdPtr)
        chdPtr = idaapi.get_full_long(ea + 16)
        chd = ClassHierarchyDescriptor(chdPtr)

        strid = idaapi.get_struc_id('_s__RTTICompleteObjectLocator')
        size = idaapi.get_struc_size(strid)
        idaapi.do_unknown_range(ea, size, idaapi.DOUNK_DELNAMES)
        idaapi.doStruct(ea, size, strid)

        if chd.isMultipleInheritance:
            if chd.isVirtualInheritance:
                print '%08X: Cannot handle virtual inheritance yet.' % (ea)
            else:
                # '??_R4' + td.baseMangledName + '6B' + baseClassTd.baseMangledName + '@'
                # '??_7'  + ...
                print '%08X: Cannot handle multiple inheritance yet.' % (ea)
        else:
            idaapi.set_name(ea, '??_R4' + td.baseMangledName + '6B@', 0)
Example #2
0
def make_xref(from_ea, to_ea, xref_constructor, xref_size):
  """Force the data at `from_ea` to reference the data at `to_ea`."""
  if not idc.GetFlags(to_ea) or is_invalid_ea(to_ea):
    DEBUG("  Not making reference (A) from {:x} to {:x}".format(from_ea, to_ea))
    return

  make_head(from_ea)

  if is_code(from_ea):
    _CREFS_FROM[from_ea].add(to_ea)
    _CREFS_TO[to_ea].add(from_ea)
  else:
    _DREFS_FROM[from_ea].add(to_ea)
    _DREFS_TO[to_ea].add(from_ea)

  # If we can't make a head, then it probably means that we're at the
  # end of the binary, e.g. the last thing in the `.extern` segment.
  if not make_head(from_ea + xref_size):
    assert idc.BADADDR == idc.SegStart(from_ea + xref_size)

  idaapi.do_unknown_range(from_ea, xref_size, idc.DOUNK_EXPAND)
  xref_constructor(from_ea)
  if not is_code_by_flags(from_ea):
    idc.add_dref(from_ea, to_ea, idc.XREF_USER|idc.dr_O)
  else: 
    DEBUG("  Not making reference (B) from {:x} to {:x}".format(from_ea, to_ea))
def chendo(address, end, search, struct):
    
    while address < end:
        address = idaapi.find_binary(address, end, search, 0x10, SEARCH_DOWN)
        idaapi.do_unknown_range(address, 0xB0, 0)
        idaapi.create_struct(address, 0xB0, struct)
        address += 0x8
Example #4
0
 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)
Example #5
0
File: util.py Project: d-ned/mcsema
def make_xref(from_ea, to_ea, xref_constructor, xref_size):
    """Force the data at `from_ea` to reference the data at `to_ea`."""
    if not idc.GetFlags(to_ea) or is_invalid_ea(to_ea):
        DEBUG("  Not making reference (A) from {:x} to {:x}".format(
            from_ea, to_ea))
        return

    make_head(from_ea)

    if is_code(from_ea):
        _CREFS_FROM[from_ea].add(to_ea)
        _CREFS_TO[to_ea].add(from_ea)
    else:
        _DREFS_FROM[from_ea].add(to_ea)
        _DREFS_TO[to_ea].add(from_ea)

    # If we can't make a head, then it probably means that we're at the
    # end of the binary, e.g. the last thing in the `.extern` segment.
    if not make_head(from_ea + xref_size):
        assert idc.BADADDR == idc.SegStart(from_ea + xref_size)

    idaapi.do_unknown_range(from_ea, xref_size, idc.DOUNK_EXPAND)
    xref_constructor(from_ea)
    if not is_code_by_flags(from_ea):
        idc.add_dref(from_ea, to_ea, idc.XREF_USER | idc.dr_O)
    else:
        DEBUG("  Not making reference (B) from {:x} to {:x}".format(
            from_ea, to_ea))
Example #6
0
    def define(ea):
        if BaseClassDescriptor.isDefined(ea):
            return

        td = TypeDescriptor(BaseClassDescriptor.__typeDescriptorPtr(ea))

        attrs = BaseClassDescriptor.__attributes(ea)
        if attrs != 0 and attrs != 0x40:
            print "%08X: Suspicious attributes value: %08X" % (ea, attrs)
            # raise RttiError('%08X: Suspicious attributes value: %08X' % (ea, attrs))
        isV2 = (attrs & 0x40) != 0
        if isV2:
            strid = idaapi.get_struc_id("_s__RTTIBaseClassDescriptor2")
        else:
            strid = idaapi.get_struc_id("_s__RTTIBaseClassDescriptor")
        size = idaapi.get_struc_size(strid)
        idaapi.do_unknown_range(ea, size, idaapi.DOUNK_DELNAMES)
        idaapi.doStruct(ea, size, strid)

        pmd = BaseClassDescriptor.__where(ea)
        name = "??_R1"
        name += mangleNumber(pmd.mdisp)
        name += mangleNumber(pmd.pdisp)
        name += mangleNumber(pmd.vdisp)
        name += mangleNumber(attrs)
        name += td.baseMangledName + "8"
        idaapi.set_name(ea, name, 0)

        if isV2:
            ClassHierarchyDescriptor.define(BaseClassDescriptor.__v2ChdPtr(ea))
Example #7
0
    def define(ea):
        if CompleteObjectLocator.isDefined(ea):
            return
        if not CompleteObjectLocator.isValid(ea):
            raise RttiError("%08X: doesn't look like a correct CompleteObjectLocator" % (ea))

        # Ensure referenced structs are defined.
        # An exception will be thrown if something goes wrong.
        tdPtr = idaapi.get_full_long(ea + 12)
        td = TypeDescriptor(tdPtr)
        chdPtr = idaapi.get_full_long(ea + 16)
        chd = ClassHierarchyDescriptor(chdPtr)

        strid = idaapi.get_struc_id("_s__RTTICompleteObjectLocator")
        size = idaapi.get_struc_size(strid)
        idaapi.do_unknown_range(ea, size, idaapi.DOUNK_DELNAMES)
        idaapi.doStruct(ea, size, strid)

        if chd.isMultipleInheritance:
            if chd.isVirtualInheritance:
                print "%08X: Cannot handle virtual inheritance yet." % (ea)
            else:
                # '??_R4' + td.baseMangledName + '6B' + baseClassTd.baseMangledName + '@'
                # '??_7'  + ...
                print "%08X: Cannot handle multiple inheritance yet." % (ea)
        else:
            idaapi.set_name(ea, "??_R4" + td.baseMangledName + "6B@", 0)
Example #8
0
    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()
Example #9
0
    def define(ea):
        if BaseClassDescriptor.isDefined(ea):
            return

        td = TypeDescriptor(BaseClassDescriptor.__typeDescriptorPtr(ea))

        attrs = BaseClassDescriptor.__attributes(ea)
        if attrs != 0 and attrs != 0x40:
            print '%08X: Suspicious attributes value: %08X' % (ea, attrs)
            # raise RttiError('%08X: Suspicious attributes value: %08X' % (ea, attrs))
        isV2 = (attrs & 0x40) != 0
        if isV2:
            strid = idaapi.get_struc_id('_s__RTTIBaseClassDescriptor2')
        else:
            strid = idaapi.get_struc_id('_s__RTTIBaseClassDescriptor')
        size = idaapi.get_struc_size(strid)
        idaapi.do_unknown_range(ea, size, idaapi.DOUNK_DELNAMES)
        idaapi.doStruct(ea, size, strid)

        pmd = BaseClassDescriptor.__where(ea)
        name = '??_R1'
        name += mangleNumber(pmd.mdisp)
        name += mangleNumber(pmd.pdisp)
        name += mangleNumber(pmd.vdisp)
        name += mangleNumber(attrs)
        name += td.baseMangledName + '8'
        idaapi.set_name(ea, name, 0)

        if isV2:
            ClassHierarchyDescriptor.define(BaseClassDescriptor.__v2ChdPtr(ea))
Example #10
0
def make_code(start, end):
  for i in range((end - start) / 4):
    addr = start + (i * 4)
    if not idc.isCode(idc.GetFlags(addr)):
      idaapi.do_unknown_range(addr, 4, 0)
      idaapi.auto_make_code(addr)
      idc.MakeCode(addr)
  return
Example #11
0
def Chendo(address, members):

    for (size, name) in members:
        flags = idaapi.get_flags_by_size(size)
        idaapi.do_unknown_range(address, size, 0)

        if name == '':
            idc.make_array(address, size)
        else:
            idaapi.create_data(address, flags, size, BADNODE)

        idc.set_cmt(address, name, False)
        address += size
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
Example #13
0
    def define(ea):
        if TypeDescriptor.isDefined(ea):
            return
        if not TypeDescriptor.isValid(ea):
            raise RttiError("%08X: This doesn't look like a TypeDescriptor." % ea)

        # FIXME: 64-bit compatibility
        mangledName = getAsciiz(ea + 8)

        # Define data in DB
        structLength = 8 + len(mangledName) + 1
        idaapi.do_unknown_range(ea, structLength, idaapi.DOUNK_DELNAMES)
        idaapi.doStruct(ea, structLength, idaapi.get_struc_id("_TypeDescriptor"))
        idaapi.set_name(ea, TypeDescriptor.makeName(ea), 0)
Example #14
0
def forceStruct(ea, name):
	"""
	forceStruct: ea, name
	
	Does all the necessary things to force IDA to convert the
	memory starting at address 'ea' into a struct of type 'name'.
	Returns the address after the struct.
	"""

	sid = idaapi.get_struc_id(name)
	ssize = idaapi.get_struc_size(sid)

	idaapi.do_unknown_range(ea, ssize, DOUNK_DELNAMES)
	x = idaapi.doStruct(ea, ssize, sid)
	return ea + ssize
Example #15
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
Example #16
0
    def define(ea):
        if TypeDescriptor.isDefined(ea):
            return
        if not TypeDescriptor.isValid(ea):
            raise RttiError("%08X: This doesn't look like a TypeDescriptor." %
                            ea)

        # FIXME: 64-bit compatibility
        mangledName = getAsciiz(ea + 8)

        # Define data in DB
        structLength = 8 + len(mangledName) + 1
        idaapi.do_unknown_range(ea, structLength, idaapi.DOUNK_DELNAMES)
        idaapi.doStruct(ea, structLength,
                        idaapi.get_struc_id("_TypeDescriptor"))
        idaapi.set_name(ea, TypeDescriptor.makeName(ea), 0)
Example #17
0
    def define(ea, count):
        # TODO: sanity checks

        idaapi.do_unknown_range(ea, count * 4, idaapi.DOUNK_DELNAMES)
        idaapi.doDwrd(ea, 4)
        idaapi.do_data_ex(ea, idaapi.getFlags(ea), count * 4, idaapi.BADADDR)
        # TODO: rewrite into idaapi calls
        idc.SetArrayFormat(ea, idc.AP_INDEX | idc.AP_IDXDEC, 1, 0)

        # Entry 0 describes the class itself => I can find out the class name.
        bcd = BaseClassDescriptor(idaapi.get_full_long(ea))
        idaapi.set_name(ea, "??_R2" + bcd.typeDescriptor.baseMangledName + "8", 0)

        i = 1
        while i < count:
            bcd = BaseClassDescriptor(idaapi.get_full_long(ea + i * 4))
            i += 1
Example #18
0
    def define(ea):
        if ClassHierarchyDescriptor.isDefined(ea):
            return
        if not ClassHierarchyDescriptor.isValid(ea):
            raise RttiError("%08X: Doesn't look like a correct ClassHierarchyDescriptor" % ea)

        strid = idaapi.get_struc_id("_s__RTTIClassHierarchyDescriptor")
        size = idaapi.get_struc_size(strid)
        idaapi.do_unknown_range(ea, size, idaapi.DOUNK_DELNAMES)
        idaapi.doStruct(ea, size, strid)

        bca = BaseClassArray(
            ClassHierarchyDescriptor.__baseClassArrayPtr(ea), ClassHierarchyDescriptor.__baseClassCount(ea)
        )

        # Entry 0 describes the class itself => I can find out the class name.
        idaapi.set_name(ea, "??_R3" + bca[0].typeDescriptor.baseMangledName + "8", 0)
Example #19
0
def znullptr(address, end, search, struct):

    magic = idaapi.find_binary(address, end, search, 0x10, idc.SEARCH_DOWN)
    pattern = '%02X %02X %02X %02X FF FF FF FF' % (magic & 0xFF,
                                                   ((magic >> 0x8) & 0xFF),
                                                   ((magic >> 0x10) & 0xFF),
                                                   ((magic >> 0x18) & 0xFF))

    sysvec = idaapi.find_binary(address, cvar.inf.maxEA, pattern, 0x10,
                                idc.SEARCH_UP) - 0x60
    idaapi.set_name(sysvec, 'sysentvec', SN_NOCHECK | SN_NOWARN | SN_FORCE)

    sysent = idaapi.get_qword(sysvec + 0x8)
    idaapi.set_name(sysent, 'sv_table', SN_NOCHECK | SN_NOWARN | SN_FORCE)

    sysnames = idaapi.get_qword(sysvec + 0xD0)
    idaapi.set_name(sysnames, 'sv_syscallnames',
                    SN_NOCHECK | SN_NOWARN | SN_FORCE)

    # Get the list of syscalls
    offset = idaapi.find_binary(address, cvar.inf.maxEA,
                                '73 79 73 63 61 6C 6C 00 65 78 69 74 00', 0x10,
                                SEARCH_DOWN)

    numsyscalls = idaapi.get_qword(sysvec)
    for entry in xrange(numsyscalls):
        initial = sysnames + (entry * 0x8)
        idc.create_data(initial, FF_QWORD, 0x8, BADNODE)
        offset = idaapi.get_qword(initial)

        length = idaapi.get_max_strlit_length(offset, STRTYPE_C)
        name = idaapi.get_strlit_contents(offset, length, STRTYPE_C)

        sysentoffset = sysent + 0x8 + (entry * 0x30)
        idaapi.do_unknown_range(sysentoffset - 0x8, 0x30, 0)
        idaapi.create_struct(sysentoffset - 0x8, 0x30, struct)
        idc.set_cmt(sysentoffset - 0x8, '#%i' % entry, False)

        if '{' in name:
            continue

        # Rename the functions
        function = idaapi.get_qword(sysentoffset)
        idaapi.set_name(function, name.replace('#', 'sys_'),
                        SN_NOCHECK | SN_NOWARN | SN_FORCE)
Example #20
0
    def define(ea, count):
        # TODO: sanity checks

        idaapi.do_unknown_range(ea, count * 4, idaapi.DOUNK_DELNAMES)
        idaapi.doDwrd(ea, 4)
        idaapi.do_data_ex(ea, idaapi.getFlags(ea), count * 4, idaapi.BADADDR)
        # TODO: rewrite into idaapi calls
        idc.SetArrayFormat(ea, idc.AP_INDEX | idc.AP_IDXDEC, 1, 0)

        # Entry 0 describes the class itself => I can find out the class name.
        bcd = BaseClassDescriptor(idaapi.get_full_long(ea))
        idaapi.set_name(ea, '??_R2' + bcd.typeDescriptor.baseMangledName + '8',
                        0)

        i = 1
        while i < count:
            bcd = BaseClassDescriptor(idaapi.get_full_long(ea + i * 4))
            i += 1
Example #21
0
    def define(ea):
        if ClassHierarchyDescriptor.isDefined(ea):
            return
        if not ClassHierarchyDescriptor.isValid(ea):
            raise RttiError(
                "%08X: Doesn't look like a correct ClassHierarchyDescriptor" %
                ea)

        strid = idaapi.get_struc_id('_s__RTTIClassHierarchyDescriptor')
        size = idaapi.get_struc_size(strid)
        idaapi.do_unknown_range(ea, size, idaapi.DOUNK_DELNAMES)
        idaapi.doStruct(ea, size, strid)

        bca = BaseClassArray(ClassHierarchyDescriptor.__baseClassArrayPtr(ea),
                             ClassHierarchyDescriptor.__baseClassCount(ea))

        # Entry 0 describes the class itself => I can find out the class name.
        idaapi.set_name(ea,
                        '??_R3' + bca[0].typeDescriptor.baseMangledName + '8',
                        0)
Example #22
0
 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
Example #23
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)
Example #24
0
def findAllKEXT():
	"""
	findAllKEXT:
	
	Finds all KEXT contained in the kernelcache file. The mach-o
	headers will be converted into the appropiate structs, the
	new sections will be defined and the name and version number
	of the KEXT are extracted. In the end a window is shown that
	shows all contained KEXT.
	"""
	
	# Ask the user if he wants to add all the KEXT sections
	# to the IDA database. 
	answer = idc.AskYN(0, """Do you want to add all the KEXT sections to the IDA database?
	
If this was already done before or there was already code or data in the same place in the IDA database, IDA might react very slow, crash or just stop to work.""")
	
	# KEXT cache starts behind the __LINKEDIT segment
	# NOTE: IDA calls the segment __LINKEDIT_hidden
	
	linkedit = idaapi.get_segm_by_name("__LINKEDIT_hidden")
	if not linkedit:
		print "[-] cannot find KEXTCACHE: __LINKEDIT segment not found"
		return
	kextcache = idaapi.get_next_seg(linkedit.endEA)
	if not kextcache:
		print "[-] cannot find KEXTCACHE: __LINKEDIT not followed by any segment"
		return
	
	dummyName = idaapi.get_segm_name(kextcache)
	if dummyName != "__text":
		print "[-] cannot find KEXTCACHE: __LINKEDIT not followed by __text segment"
		return
	
	if answer == 1:
		# Destroy everything in the kextcache area
		idaapi.do_unknown_range(kextcache.startEA, kextcache.endEA-kextcache.startEA, DOUNK_DELNAMES)
	
	startEA = kextcache.startEA
	kextlist = []
	while True:
		sig = idc.Dword(startEA)
		if sig != 0xfeedface:
			"[-] expected the next KEXT but did not find correct signature"
			break
		
		seg_lc = None
		
		sections = []
		added = 0
		
		next = forceStruct(startEA, "mach_header")
		ncmds = get_member_from_struct(startEA, "mach_header", "ncmds")
		for i in range(ncmds):
			lc_addr = next
			cmd = get_member_from_struct(next, "load_command", "cmd")
			if cmd == 1:
				seg_lc = next
				next = forceStruct(seg_lc, "segment_command")
				nsecs = get_member_from_struct(seg_lc, "segment_command", "nsects")
				for j in range(nsecs):
					section = next
					next = forceStruct(section, "section")
					
					# Get basic information about segment (needed for ALL the code below)
					secStart = get_member_from_struct(section, "section", "addr")
					secEnd = secStart + get_member_from_struct(section, "section", "size")
					secname = idc.GetString(section)
					
					# We should tell IDA about what this section is
					s = idaapi.segment_t()
					s.startEA	  = secStart
					s.endEA		  = secEnd
					s.sel		  = idaapi.setup_selector(0)
					if secname == "__text":
						s.bitness = 0
					else:
						s.bitness = 1
					s.align		  = get_member_from_struct(section, "section", "align")
					s.comb		  = 0 # ???
					
					if secname == "__text" or secname == "stubs":
						sclass = "CODE"
					elif secname == "__bss":
						sclass = "BSS"
					else:
						sclass = "DATA"
					
					if len(sections) == 0:
						sec = {}
						sec["name"] = "MACH-O HEADER"
						sec["start"] = "%08X" % (startEA)
						sec["end"] = "%08X" % (secStart-1)
						sections.append(sec)
					
					sec = {}
					sec["name"] = secname
					sec["start"] = "%08X" % (secStart)
					sec["end"] = "%08X" % (secEnd-1)
					sections.append(sec)
					
					if answer == 1:
						# Destroy everything inside the segment
						idaapi.do_unknown_range(secStart, secEnd-secStart, DOUNK_DELNAMES)
					
						# Ensure that the whole section is undefined
						idaapi.add_segm_ex(s, secname, sclass, idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_QUIET)
					
					if secname == "__text":
						idc.SetRegEx(secStart, "T", 1, 0)

					# special handling of constructor and destructor
					if secname == "__constructor" or secname == "__destructor":
						for z in range(secStart, secEnd, 4):
							idc.OpOffEx(z, -1, REF_OFF32, 0xFFFFFFFF, 0, 0)
					
					# We have to check for __data section because we want
					# to find the kmod_info structure
					if secname != "__data":
						continue
						
					kextName = None
					for z in range(secStart, secEnd, 4):
						k = z
						# We assume that all KEXT name start with "com."
						kextNameSig = idc.Dword(k)
						if kextNameSig == 0x2e6d6f63:
							forceStruct(k-12, "kmod_info")
							kextName = idc.GetString(k)
							kextVersion = idc.GetString(k+64)
							#print "-> %s - version: %s" % (kextName, kextVersion)
							
							dic = {}
							dic["addr"] = "%08X" % (startEA)
							dic["name"] = kextName
							dic["version"] = kextVersion
							kextlist.append(dic)
							added = 1
							break
					if kextName == None:
						print "ERROR COULD NOT FIND NAME"
					
			elif cmd == 0x1b:
				next = forceStruct(lc_addr, "uuid_command")
			elif cmd == 0x2:
				next = forceStruct(lc_addr, "symtab_command")
				#print "Found symbol table KEXT at %08x" % (startEA)
			else:
				print "Unknown load command %08x" % (cmd)
			
			if added:
				kextlist[len(kextlist)-1]["sections"] = sections
			
			next = lc_addr + get_member_from_struct(lc_addr, "load_command", "cmdsize")
		
		if seg_lc == None:
			startEA += 4
			while idc.Dword(startEA) != 0xfeedface:
				startEA += 4
			continue
		
		startEA = get_member_from_struct(seg_lc, "segment_command", "vmaddr")
		startEA += get_member_from_struct(seg_lc, "segment_command", "vmsize")

	c = MySelectionDialog("Retrieved KEXT", [ ["Address", 10], [ "Name", 65 ], ["Version", 65] ], formatKEXTresults(kextlist))
	selected_row = c.Show(True)
	if selected_row >= 0:
		sel = kextlist[selected_row]
		
		c = MySelectionDialog("Sections inside " + sel["name"], [ ["Name", 16], [ "Start", 10 ], ["End", 10] ], formatSECTIONresults(sel["sections"]))
		selected_row = c.Show(True)
		if selected_row >= 0:
			sel = sel["sections"][selected_row]
			
			idc.Jump(int(sel["start"], 16))
Example #25
0
    pc = triton.getSymbolicRegisterValue(triton.REG.RIP)

rax_ast = triton.buildSymbolicRegister(triton.REG.RAX)
rax_ast = triton.getFullAst(rax_ast)
rax_ast = triton.simplify(rax_ast, True)
start = time.time()
print("[+] computing Arybo representation...")
e = atools.tritonast2arybo(rax_ast, use_exprs=True, use_esf=False)
print("[+] got Arybo expression, evalute it...")
e = aexprs.eval_expr(e, use_esf=False)
end = time.time()
diff = end - start
print("[*] Arybo evaluation computed in %0.4fs" % diff)
app = e.vectorial_decomp([rdi.v])
exp = atools.identify(app, "rdi")
print("[*] Identified expression: rax = %s" % aexprs.prettyprint(exp))
asm = easm.asm_binary(exp, ("rax", 64), {"rdi": ("rdi", 64)},
                      "x86_64-unknown-unknwon")
print("[*] Assembled expression: %s" % asm.encode("hex"))

func_size = func.endEA - 1 - func.startEA
if len(asm) > func_size:
    printf("[-] Final assembly does not fit in the original function!")
asm_nop = asm + "\x90" * (func_size - len(asm))
func_start = int(func.startEA)
func_end = int(func.endEA)
idaapi.patch_many_bytes(func_start, asm_nop)
idaapi.do_unknown_range(func_start, func_end, 0)
idaapi.auto_make_code(func_start)
idaapi.auto_make_proc(func_start)
Example #26
0
    def make_data(self, object_version, address):
        size = 0
        try:
            size = object_version.get_size()
        except KeyError:
            pass
        flags = None
        try:
            flags = object_version.get_object_flags()
        except KeyError:
            pass

        if size == 0:
            idc.MakeUnkn(address, idc.DOUNK_EXPAND)
        else:
            if flags is not None:
                if idc.isASCII(flags):
                    try:
                        str_type = object_version.get_string_type()
                        YaToolIDATools.check_and_set_str_type(str_type)
                    except KeyError:
                        pass
                    idc.MakeStr(address, address + size)
                    idc.SetFlags(address, flags)

                if idc.isStruct(flags):
                    found = False
                    for xref_offset_operand, xref_id_attr in object_version.get_xrefed_id_map(
                    ).iteritems():
                        (xref_offset, xref_operand) = xref_offset_operand
                        for xref_hash, xref_attrs in xref_id_attr:

                            if xref_hash in self.struc_ids:
                                struc_id = self.struc_ids[xref_hash]
                                if DEBUG_EXPORTER:
                                    logger.debug(
                                        "making unknown from 0x%08X to 0x%08X"
                                        % (address, address + size))
                                idaapi.do_unknown_range(
                                    address, size, idc.DOUNK_DELNAMES)

                                #   idc.MakeUnkn(address, DOUNK_SIMPLE | idc.DOUNK_DELNAMES)
                                #   for i in xrange(1, size):
                                #       MakeName(address + i, "")
                                #       idc.MakeUnkn(address + i, DOUNK_SIMPLE | idc.DOUNK_DELNAMES)
                                # idc.MakeStructEx uses idaapi.doStruct (but asks for name while
                                # we already have the struc id)
                                if DEBUG_EXPORTER:
                                    logger.debug(
                                        "Making struc at %s : %s (sizeof(%s)=0x%08X, size=0x%08X, flags=0x%08X"
                                        % (self.yatools.address_to_hex_string(
                                            address),
                                           self.yatools.address_to_hex_string(
                                               struc_id),
                                           idaapi.get_struc_name(struc_id),
                                           idc.GetStrucSize(struc_id), size,
                                           flags))
                                idc.SetCharPrm(idc.INF_AUTO, True)
                                idc.Wait()
                                if idaapi.doStruct(address, size,
                                                   struc_id) == 0:
                                    if DEBUG_EXPORTER:
                                        logger.warning("Making struc failed")
                                idc.SetCharPrm(idc.INF_AUTO, False)
                                #                                     idc.SetFlags(address, flags)
                                found = True
                    else:
                        logger.error(
                            "bad struc flags : idc.isStruct is true but no xref available for object %s"
                            % self.hash_provider.hash_to_string(
                                object_version.get_id()))
                    if not found:
                        logger.error(
                            "bad struc flags : idc.isStruct is true "
                            "but no struc available for object %s (%s)" %
                            (self.hash_provider.hash_to_string(
                                object_version.get_id()),
                             object_version.get_name()))
                else:
                    idc.MakeData(address, flags & (idc.DT_TYPE | idc.MS_0TYPE),
                                 size, 0)

            else:
                idc.MakeData(address, idc.FF_BYTE, size, 0)

        self.make_name(object_version, address, False)

        self.set_type(object_version, address)