Exemple #1
0
    def abi(self):
        """Return the IDA guessed ABI
        """

        architecture = self.architecture

        available_abis = self.IDAABI2SibylABI.get(architecture, None)
        if not available_abis:
            raise ValueError("No ABI available for architecture %s" %
                             architecture)

        if isinstance(available_abis, str):
            return available_abis

        # Search for IDA guessed type
        for func_addr in idautils.Functions():
            gtype = idc.GuessType(func_addr)
            if gtype is None:
                continue
            match = self.gtype_matcher.match(gtype)
            if match is None:
                continue
            calling_conv = match.group(1)
            abi = available_abis.get(calling_conv, None)
            if abi is None:
                raise ValueError("No ABI matching %s" % calling_conv)
            return abi
        raise ValueError("Unable to guess ABI")
Exemple #2
0
 def get_type(cls, function):
     '''Get function type.'''
     ctype = idc.GetType(function)
     if not ctype:
         ctype = idc.GuessType(function)
         if not ctype:
             ctype = ''
     return ctype
Exemple #3
0
 def readEA(self, ea):
     self.name = idc.GetFunctionName(ea)
     if not self.name:
         raise self.NotFunctionError(ea)
     self.ea = ea
     tp = idc.GetType(ea) or idc.GuessType(ea)
     if tp:
         self.parseType(tp, skipName=True)
     return self
 def include(self):
   t = idc.GetType(self.offset)
   # if failed getting type, there's no annotation here
   if t is None:
     return False
   # if type equals guessed type, no need to save annotation
   if t == idc.GuessType(self.offset):
     return False
   return True
Exemple #5
0
def make_strings_const():
    s = idautils.Strings(False)
    s.setup(strtypes=idautils.Strings.STR_UNICODE | idautils.Strings.STR_C)

    for v in s:
        gt = idc.GetType(v.ea)
        if not gt:
            gt = idc.GuessType(v.ea)
        if gt and not gt.startswith("const "):
            idc.SetType(v.ea, "const " + gt)
Exemple #6
0
def get_func_type(startEA):
    """
    Parse IDA's guessed type decl
    returns: tuple of: (return type, [arg types])
    (this is a giant hack)
     """

    type_str = idc.GuessType(startEA)

    if not type_str:
        # Probably wasn't a function
        print("ERROR: No function type guess")
        return None

    # Parse strings like this:
    # 'int __cdecl(int argc, const char **argv, const char **envp)'
    # 'int __cdecl(int)'

    # Try to make it into a parsable string
    type_str = re.sub(r"(__cdecl|__fastcall|[0-9_])", '', type_str)

    try:
        parser = pycparser.c_parser.CParser()
        res = parser.parse(type_str + ';')  # Need that semicolon of course
        type_ast = res.ext[0].type

        # Return type
        return_type = type_ast.type.type.names[0]

        # Arguments
        arg_types = []
        if type_ast.args:
            for param in type_ast.args.params:
                if type(param.type) is pycparser.c_ast.PtrDecl:
                    # Pointer, return "ptr" for now
                    arg_types.append("ptr")
                else:
                    arg_types.append(param.type.type.names[0])

        return (return_type, arg_types)
    except:
        print("ERROR: Couldn't parse function type guess")
        return None
Exemple #7
0
def _propagate_virtual_method_type_for_method(classinfo, class_vindex, vmethod):
    """Propagate the type of a class's virtual method to the vtable struct."""
    if not idau.is_function_start(vmethod):
        _log(2, 'Not a function start: {:x}', vmethod)
        return False
    vmethod_type = idc.GuessType(vmethod)
    if not vmethod_type:
        _log(2, 'No guessed type: {:x}', vmethod)
        return False
    vmethod_ptr_type = symbol.convert_function_type_to_function_pointer_type(vmethod_type)
    if not vmethod_ptr_type:
        _log(2, 'Could not convert to function pointer type: {:x}', vmethod)
        return False
    vmethods_sid = idau.struct_open(classinfo.classname + '::vmethods')
    vmethod_offset = class_vindex * idau.WORD_SIZE
    vmethod_mid = idc.GetMemberId(vmethods_sid, vmethod_offset)
    if not bool(idc.SetType(vmethod_mid, vmethod_ptr_type)):
        _log(2, 'Could not set vmethod field type: {:x}, {}, {}', vmethod, classinfo.classname,
                class_vindex)
        return False
    return True
Exemple #8
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