Ejemplo n.º 1
0
def kernelcache_find_virtual_method_overrides(classname=None, method=None):
    import idc
    import idaapi
    import ida_kernelcache as kc

    # Define the form to ask for the arguments.
    class MyForm(idaapi.Form):
        def __init__(self):
            swidth = 40
            idaapi.Form.__init__(
                self, r"""STARTITEM 0
Find virtual method overrides

<#The class#Class :{classname}>
<#The virtual method#Method:{method}>""", {
                    'classname':
                    idaapi.Form.StringInput(tp=idaapi.Form.FT_IDENT,
                                            swidth=swidth),
                    'method':
                    idaapi.Form.StringInput(tp=idaapi.Form.FT_IDENT,
                                            swidth=swidth),
                })

        def OnFormChange(self, fid):
            return 1

    kc.collect_class_info()

    if any(arg is None for arg in (classname, method)):
        f = MyForm()
        f.Compile()
        f.classname.value = classname or ''
        f.method.value = method or ''
        ok = f.Execute()
        if ok != 1:
            print 'Cancelled'
            return False
        classname = f.classname.value
        method = f.method.value
        f.Free()

    if classname not in kc.class_info:
        print 'Not a valid class: {}'.format(classname)
        return False

    print 'Subclasses of {} that override {}:'.format(classname, method)
    baseinfo = kc.class_info[classname]
    found = False
    for classinfo in baseinfo.descendants():
        for _, override, _ in kc.vtable.class_vtable_overrides(
                classinfo, superinfo=baseinfo, methods=True):
            name = idc.NameEx(idc.BADADDR, override)
            demangled = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN))
            name = demangled if demangled else name
            if method in name:
                print '{:#x}  {}'.format(override, classinfo.classname)
                found = True
    if not found:
        print 'No subclass of {} overrides {}'.format(classname, method)
    return found
Ejemplo n.º 2
0
def get_ea_name(ea, fromaddr=idc.BADADDR, true=False, user=False):
    """Get the name of an address.

    This function returns the name associated with the byte at the specified address.

    Arguments:
        ea: The linear address whose name to find.

    Options:
        fromaddr: The referring address. Default is BADADDR. Some addresses have a
            location-specific name (for example, labels within a function). If fromaddr is not
            BADADDR, then this function will try to retrieve the name of ea from fromaddr's
            perspective. The global name will be returned if no location-specific name is found.
        true: Retrieve the true name rather than the display name. Default is False.
        user: Return "" if the name is not a user name.

    Returns:
        The name of the address or "".
    """
    if user and not idc.hasUserName(idc.GetFlags(ea)):
        return ""
    if true:
        return idc.GetTrueNameEx(fromaddr, ea)
    else:
        return idc.NameEx(fromaddr, ea)
Ejemplo n.º 3
0
def _get_api(sea):
    calls = 0
    api = []
    flags = idc.GetFunctionFlags(sea)
    # ignore library functions
    if flags & idc.FUNC_LIB or flags & idc.FUNC_THUNK:
        return calls, api
    # list of addresses
    addresses = list(idautils.FuncItems(sea))
    for instr in addresses:
        tmp_api_address = ""
        if idaapi.is_call_insn(instr):
            for xref in idautils.XrefsFrom(instr, idaapi.XREF_FAR):
                if xref.to is None:
                    calls += 1
                    continue
                tmp_api_address = xref.to
                break
            if tmp_api_address == "":
                calls += 1
                continue
            api_flags = idc.GetFunctionFlags(tmp_api_address)
            if api_flags & idaapi.FUNC_LIB is True \
                    or api_flags & idaapi.FUNC_THUNK:
                tmp_api_name = idc.NameEx(0, tmp_api_address)
                if tmp_api_name:
                    api.append(tmp_api_name)
            else:
                calls += 1
    return calls, api
def kernelcache_find_virtual_method_overrides(classname=None, method=None):
    import idc
    import ida_kernelcache as kc

    kc.collect_class_info()

    if not classname:
        classname = idc.AskStr('IOUserClient', 'Enter class name')
    if classname not in kc.class_info:
        print 'Not a valid class: {}'.format(classname)
        return False

    if not method:
        method = idc.AskStr('externalMethod', 'Enter method name')

    print 'Subclasses of {} that override {}:'.format(classname, method)
    baseinfo = kc.class_info[classname]
    found = False
    for classinfo in baseinfo.descendants():
        for _, override, _ in kc.vtable.class_vtable_overrides(
                classinfo, superinfo=baseinfo, methods=True):
            name = idc.NameEx(idc.BADADDR, override)
            demangled = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN))
            name = demangled if demangled else name
            if method in name:
                print '{:#x}  {}'.format(override, classinfo.classname)
                found = True
    if not found:
        print 'No subclass of {} overrides {}'.format(classname, method)
    return found
Ejemplo n.º 5
0
    def _collect_data(self, collect_args):
        func_item = collect_args["func_item"]
        code_refs_from_list = list(idautils.CodeRefsFrom(func_item, False))

        for code_ref in code_refs_from_list:
            is_loaded_dynamically = False
            is_library_function = False
            function_name = ""

            if (idc.GetFunctionFlags(code_ref) == -1):
                # Find code_ref in functions that are imported dynamically
                for imported_module in self._imported_modules:
                    if code_ref in imported_module.get_addresses():
                        is_loaded_dynamically = True
                        break
            else:
                if ((idc.GetFunctionFlags(code_ref) & idaapi.FUNC_LIB) != 0
                        and idaapi.get_func(code_ref) !=
                        idaapi.get_func(func_item)):
                    # code_ref is imported statically
                    is_library_function = True

            if (is_library_function or is_loaded_dynamically):
                # get name
                function_name = idc.NameEx(func_item, code_ref)

                # include in attribute
                if not (function_name in self._lib_calls_counters):
                    self._lib_calls_counters[function_name] = 0
                self._lib_calls_counters[function_name] += 1
Ejemplo n.º 6
0
    def _collect_data(self, collect_args):
        func_item = collect_args["func_item"]
        code_refs_from_list = \
            list(idautils.CodeRefsFrom(func_item, False))

        for code_ref in code_refs_from_list:
            is_loaded_dynamically = False
            is_library_function = False
            called_function_name = ""

            if (idc.GetFunctionFlags(code_ref) == -1):
                # Find code_ref in functions that are imported dynamically
                for imported_module in self._imported_modules:
                    if code_ref in imported_module.get_addresses():
                        is_loaded_dynamically = True
                        break
            else:
                # get_func(code_ref) != get_func(func_item) ->
                # do not include coderefs to self.
                if ((idc.GetFunctionFlags(code_ref) & idaapi.FUNC_LIB) != 0
                        and idaapi.get_func(code_ref) !=
                        idaapi.get_func(func_item)):
                    # code_ref is imported statically
                    is_library_function = True

            # Data is gathered only for library functions or Imports.
            if (is_library_function or is_loaded_dynamically):
                # get name
                called_function_name = idc.NameEx(func_item, code_ref)

                # include in attribute
                self._lib_calls_list.append(called_function_name)
Ejemplo n.º 7
0
    def getText(self, addy):
        #print "Fetching text for %08x" % addy
        color = idaapi.SCOLOR_STRING

        if addy == function.top(addy):
            name = idc.NameEx(addy, addy)
            try:
                name = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN))
            except:
                pass
        else:
            name = idc.NameEx(addy, addy)

        if name:
            return idaapi.COLSTR(" %s " % name, color)
        else:
            return idaapi.COLSTR(" 0x%08x " % addy, color)
Ejemplo n.º 8
0
def generate_data_from_offset(
        offset):  # credits to ferhat, or whoever wrote this
    found_values = {}
    chunks = idautils.Chunks(offset)

    for begin, end in chunks:
        name = ""
        offset = -1
        ea = begin

        while ea != end:
            mnem = idc.GetMnem(ea)
            opnd = idc.GetOpnd(ea, 0)
            stack_value = idc.GetOperandValue(ea, 0)

            if mnem == "jz" or mnem == "jl":
                name = ""
                offset = -1

            if offset == -1 and (mnem == "add" or mnem == "lea"
                                 or mnem == "sub"):
                offset = idc.GetOperandValue(ea, 1)
                if mnem == "sub":
                    offset = 0x100000000 - offset

            if mnem == "push" and "offset" in opnd and "pNodeName" not in opnd:
                name = idc.GetString(stack_value, -1, idc.ASCSTR_C)

            if is_user_name(stack_value):  # this should crash? wtf
                name = idc.NameEx(idc.BADADDR, stack_value)

            if mnem == "call" or mnem == "jmp":
                #print("{} at {}").format(name, dec_to_hex(offset))
                if name:
                    found_values[offset] = name
                    name = ""
                offset = -1

            ea = idc.NextNotTail(ea)

    return found_values
Ejemplo n.º 9
0
	def analyzeFunction(self, funcea):
		# https://reverseengineering.stackexchange.com/questions/9352/finding-all-api-calls-in-a-function
		# Copy + Paste from Stack Overflow - Lika Boss
		n_flags = set() 
		dism_addr = list(idautils.FuncItems(funcea))
		for instr in dism_addr:
			tmp_api_address = ""
			if idaapi.is_call_insn(instr):
				for xref in idautils.XrefsFrom(instr, idaapi.XREF_FAR):
					if xref.to == None:
						continue
					tmp_api_address = xref.to
					break
				# get next instr since api address could not be found
				if tmp_api_address == "":
					continue
				api_flags = idc.GetFunctionFlags(tmp_api_address)
	
				# check for lib code (api)
				if (api_flags & idaapi.FUNC_LIB and api_flags & idaapi.FUNC_STATICDEF):
					tmp_api_name = idc.NameEx(0, tmp_api_address)
					if tmp_api_name:
						t_flags = self.processFunction( funcea, tmp_api_name)
						n_flags = ( t_flags| n_flags )
		# Rename function if flags populated
		# 	Skip of this isn't the first run
		sflags = "".join(set(n_flags))
		if len(n_flags) > 0 and self.rename:
			fn = idc.GetFunctionName(funcea)
			if not fn.startswith(sflags):
				print "Renaming - ", fn, " with - ", sflags
				idc.MakeName(funcea, str(sflags + "_" + fn ))
		tbl = [ funcea, idc.GetFunctionName(funcea), sflags ]
		for f in definitions.PEAPIs.keys():
			if definitions.PEAPIs[f]['flag'] in sflags:
				tbl.append('*')
			else:
				tbl.append('')

		data.append( tbl )
Ejemplo n.º 10
0
        def db_read(cls, address, key=None, repeatable=0):
            result = comment.toDict( idc.GetCommentEx(address, repeatable) )

            name = idc.NameEx(address, address)
            if name:
                result['__name__'] = name

            # defaults
            if '__color__' not in result:
                c = cls.color(address)
                if c is not None:
                    result['__color__'] = c
            if '__address__' not in result:
                result['__address__'] = address

            if '__context__' not in result:
                result['__context__'] = idc.GetFunctionAttr(address, idc.FUNCATTR_START)
            if '__sp__' not in result:
                result['__sp__'] = idc.GetSpd(address)

            if key is not None:
                return result[key]
            return result
Ejemplo n.º 11
0
        break


def is_user_name(ea):
    f = idc.GetFlags(ea)
    return idc.hasUserName(f)


for (startea, endea) in Chunks(myfunc):
    for head in Heads(startea, endea):
        switch_info = idaapi.get_switch_info_ex(head)
        if switch_info != None:
            num_cases = switch_info.get_jtable_size()
            # print(num_cases)
            # print 'good jump table found'
            results = idaapi.calc_switch_cases(head, switch_info)
            for idx in xrange(results.cases.size()):
                cur_case = results.cases[idx]
                ret = is_user_name(results.targets[idx])
                if ret:
                    name = idc.NameEx(BADADDR, results.targets[idx])
                    if "TARGET_" in name or "PRED_" in name:
                        for cidx in xrange(len(cur_case)):
                            number = int(cur_case[cidx])
                            name = name.replace("TARGET_",
                                                "").replace("PRED_", "")
                            if name not in jump_table:
                                jump_table[name] = number

print(jump_table)
Ejemplo n.º 12
0
 def yacheck_function_name(self):
     addr = yaunit.load('function_name')
     self.assertEqual('some_new_function_name',
                      idc.NameEx(idaapi.BADADDR, addr))