Beispiel #1
0
def get_or_guess_tinfo(ea):
    '''ea_t -> tinfo_t'''
    # XXX mutates (blah_tinfo2, unavoidable)
    ti = idaapi.tinfo_t()
    idaapi.get_tinfo2(ea, ti) or idaapi.guess_tinfo2(ea, ti)

    return ti
Beispiel #2
0
def get_or_guess_tinfo(ea):
    '''ea_t -> tinfo_t'''
    # XXX mutates (blah_tinfo2, unavoidable)
    ti = idaapi.tinfo_t()
    idaapi.get_tinfo2(ea, ti) or idaapi.guess_tinfo2(ea, ti)

    return ti
Beispiel #3
0
 def get_func_type(f_start):
     tif = ida_typeinf.tinfo_t()
     idaapi.get_tinfo2(f_start, tif)
     funcdata = idaapi.func_type_data_t()
     got_data = tif.get_func_details(funcdata)
     if got_data:
         return funcdata
     else:
         return None
Beispiel #4
0
def get_type(addr):
    tif = idaapi.tinfo_t()
    idaapi.get_tinfo2(addr, tif)
    funcdata = idaapi.func_type_data_t()
    tif.get_func_details(funcdata)
    func_type = idaapi.print_tinfo("", 0, 0, PRTYPE_1LINE, tif, "", "")
    ret_type = idaapi.print_tinfo("", 0, 0, PRTYPE_1LINE, funcdata.rettype, "", "")
    args = []
    for i in xrange(funcdata.size()):
        arg_type = idaapi.print_tinfo("", 0, 0, PRTYPE_1LINE, funcdata[i].type, "", "")
        args.append([i, funcdata[i].name, arg_type, funcdata[i].argloc.atype()])
    return [func_type, ret_type, args]
Beispiel #5
0
    def scan_functions(self):
        from mybase import function
        self.logger.info("For function %s:" % idc.GetFunctionName(self.ea))
        for ea in function.iterate(self.ea):
            for xref in idautils.XrefsFrom(ea, 0):
                if idautils.XrefTypeName(xref.type) == 'Code_Near_Call' or\
                    idautils.XrefTypeName(xref.type) == 'Code_Far_Call':
                    self.logger.info("found call at %s --> %s" %
                                     (hex(ea), idc.GetFunctionName(xref.to)))

                    #skip constructors
                    fn = FunctionName(idc.GetFunctionName(xref.to))
                    if fn.namespace == fn.basename:
                        continue

                    tif = idaapi.tinfo_t()
                    if idaapi.get_tinfo2(xref.to, tif):
                        funcdata = idaapi.func_type_data_t()
                        tif.get_func_details(funcdata)
                        #funcdata.get_call_method()
                        if funcdata.size() >= 1 and funcdata[0].name == "this":
                            self.funcs.add(
                                FunctionName(idc.GetFunctionName(xref.to)))
                            self.logger.info("Call to %s found" %
                                             idc.GetFunctionName(xref.to))
                    else:
                        self.logger.info("idaapi.get_tinfo2 failed")

        self.logger.info("%d subcalls found" % len(self.funcs))
Beispiel #6
0
    def resolve_objc_self_to_class(self, ea):
        '''
        Get the objective c class for the current function RDI value
        based on the class of the first argument to the current function
        '''
        f_start = idc.get_func_attr(ea, idc.FUNCATTR_START)

        tif = ida_typeinf.tinfo_t()
        idaapi.get_tinfo2(f_start, tif)
        funcdata = idaapi.func_type_data_t()
        tif.get_func_details(funcdata)

        # not happy about casting to a string and then regex replacing... but that's the best I could come up with
        replace_reg = re.compile(' \*', re.IGNORECASE)
        objc_self_type = funcdata[0].type
        return objc_self_type
Beispiel #7
0
    def _rename_function(self, function_ea, class_name, instance_ptr_ea): # type: (int, str, int) -> None
        i = 0
        function_name = "%s::__auto%d" % (class_name, i)
        while not idc.MakeNameEx(function_ea, function_name, idaapi.SN_NOWARN):
            i += 1
            function_name = "%s::__auto%d" % (class_name, i)

        func_tinfo = idaapi.tinfo_t()
        if not idaapi.get_tinfo2(function_ea, func_tinfo):
            return

        arg_tinfo = idaapi.tinfo_t()
        idaapi.get_tinfo2(instance_ptr_ea, arg_tinfo)

        func_data = idaapi.func_type_data_t()
        func_tinfo.get_func_details(func_data)
        func_data[0].type = arg_tinfo

        new_func_tinfo = idaapi.tinfo_t()
        new_func_tinfo.create_func(func_data)
        idaapi.apply_tinfo2(function_ea, new_func_tinfo, idaapi.TINFO_DEFINITE)
Beispiel #8
0
    def getArguments(self):
        """
        Retrieve function arguments and populate the object`s args list.
        """
        isGuessed = False  # Is function prototype guessed

        # Get function type info
        if not idaapi.get_tinfo2(self.proto_ea, self.typeInfo):
            idaapi.guess_tinfo2(self.proto_ea, self.typeInfo)
            isGuessed = True

        if self.typeInfo.empty():
            raise RuntimeError("Failed to retrieve function type info for function %s at %s" % (self.funcName, hex(self.ea)))

        # Get function detail
        self.typeInfo.get_func_details(self.funcInfo)

        # TODO: This seems to be creating false positives on 0 argument functions.
        #if self.funcInfo.empty():
        #    errStr = "Failed to retrieve function info for function %s" % self.funcName
        #    raise RuntimeError(errStr)

        self.argNum = len(self.funcInfo)

        # Iterate function arguments
        for argIndex in xrange(0, self.argNum):

            argType = None  # arg_type_info_t
            argLoc = None   # argloc_info
            argName = None

            #else:  # Input Argument
            argType = self.funcInfo.at(argIndex).type
            argLoc = self.funcInfo.at(argIndex).argloc
            argName = self.funcInfo.at(argIndex).name

            curArg = FuncArg(argType, argLoc, argIndex, argName, isGuessed)
            self.args.append(curArg)

        # Set return argument
        if not self.funcInfo.rettype.empty():
            self.retArg = FuncArg(self.funcInfo.rettype,
                                  self.funcInfo.retloc,
                                  -1,
                                  "Ret_Arg",
                                  isGuessed)
Beispiel #9
0
    def getArguments(self):
        """
        Retrieve function arguments and populate the object`s args list.
        """
        isGuessed = False  # Is function prototype guessed

        # Get function type info
        if not idaapi.get_tinfo2(self.proto_ea, self.typeInfo):
            idaapi.guess_tinfo2(self.proto_ea, self.typeInfo)
            isGuessed = True

        if self.typeInfo.empty():
            raise RuntimeError(
                "Failed to retrieve function type info for function %s at %s" %
                (self.funcName, hex(self.ea)))

        # Get function detail
        self.typeInfo.get_func_details(self.funcInfo)

        # TODO: This seems to be creating false positives on 0 argument functions.
        #if self.funcInfo.empty():
        #    errStr = "Failed to retrieve function info for function %s" % self.funcName
        #    raise RuntimeError(errStr)

        self.argNum = len(self.funcInfo)

        # Iterate function arguments
        for argIndex in xrange(0, self.argNum):

            argType = None  # arg_type_info_t
            argLoc = None  # argloc_info
            argName = None

            #else:  # Input Argument
            argType = self.funcInfo.at(argIndex).type
            argLoc = self.funcInfo.at(argIndex).argloc
            argName = self.funcInfo.at(argIndex).name

            curArg = FuncArg(argType, argLoc, argIndex, argName, isGuessed)
            self.args.append(curArg)

        # Set return argument
        if not self.funcInfo.rettype.empty():
            self.retArg = FuncArg(self.funcInfo.rettype, self.funcInfo.retloc,
                                  -1, "Ret_Arg", isGuessed)
Beispiel #10
0
    def imp_cb(self, ea, name, ord_nb):
        """
        get import type and add used types in local types to ensure "correct"
        export
        """
        # Get type
        imp_t = idaapi.tinfo_t()
        if idaapi.get_tinfo2(ea, imp_t):
            if not imp_t.is_func():
                self.imports.append(idaapi.print_type(ea, True) + ";")
            else:
                # Iterate over ret type and args
                for i in range(-1, imp_t.get_nargs()):
                    arg_t = imp_t.get_nth_arg(i)
                    if arg_t.is_ptr_or_array():
                        no_ptr = arg_t
                        no_ptr.remove_ptr_or_array()
                        self.import_name(str(no_ptr))

                    self.import_name(str(arg_t))
                self.imports.append(idaapi.print_type(ea, True) + " {}")
        return True
Beispiel #11
0
import idaapi
ti = idaapi.tinfo_t()

addrofW32UserProbeAddress = LocByName("_W32UserProbeAddress")
addrofProbeForWrite = LocByName("__imp__ProbeForWrite@12")

for functionAddr in Functions():
   if "memcpy" in GetFunctionName(functionAddr):
		UserProbeXrefs = [GetFunctionName(UserProbeXref) for UserProbeXref in DataRefsTo(addrofW32UserProbeAddress)]				
		ProbeForWrite = [GetFunctionName(ProbeForWrite) for ProbeForWrite in DataRefsTo(addrofProbeForWrite)]
		
		xrefs = CodeRefsTo(functionAddr, False)
		for xref in xrefs:
			if GetMnem(xref).lower() == "call":        
				function_head = GetFunctionAttr(xref, idc.FUNCATTR_START)
				idaapi.get_tinfo2(function_head, ti)
				fi = idaapi.func_type_data_t()
				ti.get_func_details(fi)
				perfunc = []
				for i in xrange(fi.size()):
					if fi[i].name:
						perfunc.append(fi[i].name)
				
				if perfunc:
					func_name = GetFunctionName(function_head)
					#Start searching with Nt prefix for SSDT calls
					if func_name[0:3] == "_Nt":
						print func_name
					#Search functions that doesn't have W32UserProbeAddress
					if func_name not in UserProbeXrefs:
						print func_name
Beispiel #12
0
def get_function_data(offset):
    """
    Obtain a idaapi.func_type_data_t object for the function with the provided start EA.

    :param int offset: start EA of function

    :return: idaapi.func_type_data_t object

    :raise RuntimeError: if func_type_data_t object cannot be obtained
    """
    tif = idaapi.tinfo_t()

    # First see if a type is already set.
    if idc.GetType(offset):
        idaapi.get_tinfo2(offset, tif)

    else:
        # Otherwise, try to use the Hexrays decompiler to determine function signature.
        # (It's better than IDA's GuessType)
        try:
            # This requires Hexrays decompiler, load it and make sure it's available before continuing.
            if not idaapi.init_hexrays_plugin():
                idc.RunPlugin("hexrays", 0) or idc.RunPlugin("hexx64", 0)
            if not idaapi.init_hexrays_plugin():
                raise RuntimeError('Unable to load Hexrays decompiler.')

            # Pull type from decompiled C code.
            decompiled = idaapi.decompile(offset)
            if decompiled is None:
                raise RuntimeError(
                    "Cannot decompile function at 0x{:X}".format(offset))
            decompiled.get_func_type(tif)

            # Save type for next time.
            format = decompiled.print_dcl2()
            # The 2's remove the unknown bytes always found at the start and end.
            idc.SetType(offset, "{};".format(format[2:-2]))

        # If we fail, resort to using GuessType+
        except RuntimeError:
            # Documentation states the type must be ';' terminated, also the function name must be inserted
            guessed_type = idc.GuessType(offset)
            if guessed_type is None:
                raise RuntimeError(
                    "failed to guess function type for offset 0x{:X}".format(
                        offset))

            func_name = idc.GetFunctionName(offset)
            if func_name is None:
                raise RuntimeError(
                    "failed to get function name for offset 0x{:X}".format(
                        offset))

            guessed_type = re.sub("\(", " {}(".format(func_name),
                                  "{};".format(guessed_type))
            idc.SetType(offset, guessed_type)
            # Try one more time to get the tinfo_t object
            if not idaapi.get_tinfo2(offset, tif):
                raise RuntimeError(
                    "failed to obtain tinfo_t object for offset 0x{:X}".format(
                        offset))

    funcdata = idaapi.func_type_data_t()
    if not tif.get_func_details(funcdata):
        raise RuntimeError(
            "failed to obtain func_type_data_t object for offset 0x{:X}".
            format(offset))

    return funcdata