Beispiel #1
0
def infer_function_signature(cfunc, expr, index_interface, index_output):
    """
    This function will infer type of variable present at index_output
    in function signature by type found in registry in accordance 
    to the GUID set at the index_interface
    :ivar cfunc_t cfunc: function object that is decompiling
    :ivar cexpr_t expr: IDA expression AST
    :ivar int index_interface: index of the GUID parameter into function signature
    :ivar int index_output: index of the output variable that will be infer
    """

    curent_expr = expr.a[index_output]
    while curent_expr.op in [idaapi.cot_cast, idaapi.cot_ref]:
        curent_expr = curent_expr.x

    variable = curent_expr.v

    if variable is None:
        ComIDA.log("Variable name not found")
        return False

    ComIDA.log("infer type of variable: (%s)" % cfunc.lvars[variable.idx].name)
    # try to find type name from third parameter
    value = idc.get_operand_value(expr.a[index_interface].ea, 1)
    if value == -1:
        value = idc.get_operand_value(expr.a[index_interface].ea,
                                      0)  # 32 bits case
    guid_bytes = idc.get_bytes(value, 16)
    guid = guid_bytes_to_string(guid_bytes)

    interface = None
    try:
        interface = build_com_from_interface_definition(
            expr.a[index_interface].ea, guid)
    except WindowsError as e:
        ComIDA.log("Interface type (%s) not found" % guid)

    tinfo = idaapi.tinfo_t()
    if interface is None or not tinfo.get_named_type(idaapi.get_idati(),
                                                     interface.name):
        ComIDA.log(
            "type (%s) not found in registry switch to symbol name base heuristic"
            % guid)
        symbol_name = idc.get_name(
            idc.get_operand_value(expr.a[index_interface].ea, 1))
        if symbol_name is None or not tinfo.get_named_type(
                idaapi.get_idati(), symbol_name[4:]):
            ComIDA.log("unable to find type for (%s)" % guid)
            return False

    cfunc.get_lvars()[variable.idx].set_final_lvar_type(
        idaapi.make_pointer(tinfo))
    return True
Beispiel #2
0
def parse(info):
    '''Parse the string `info` into an ``idaapi.tinfo_t``.'''
    if idaapi.__version__ < 7.0:
        til, ti = idaapi.cvar.idati, idaapi.tinfo_t(),
    else:
        til, ti = idaapi.get_idati(), idaapi.tinfo_t(),

    # Convert info to a string if it's a tinfo_t
    info_s = "{!s}".format(info) if isinstance(info, idaapi.tinfo_t) else info

    # Firstly we need to ';'-terminate the type the user provided in order
    # for IDA's parser to understand it.
    terminated = info_s if info_s.endswith(';') else "{:s};".format(info_s)

    # Ask IDA to parse this into a tinfo_t for us. We pass the silent flag so
    # that we're responsible for raising an exception if there's a parsing
    # error of some sort. If it succeeds, then we can return our typeinfo.
    # Otherwise we return None because of the inability to parse it.
    if idaapi.__version__ < 6.9:
        return None if idaapi.parse_decl2(til, terminated, None, ti,
                                          idaapi.PT_SIL) is None else ti
    elif idaapi.__version__ < 7.0:
        return None if idaapi.parse_decl2(til, terminated, ti,
                                          idaapi.PT_SIL) is None else ti
    return None if idaapi.parse_decl(ti, til, terminated,
                                     idaapi.PT_SIL) is None else ti
Beispiel #3
0
def process_funcs(all_funcs):
    for func in all_funcs:
        # rename
        idc.set_name(func.start_ea, f"string_{func.start_ea:X}")

        # set type
        struc_id = idaapi.get_struc_id("std::string")
        # print(f"{struc_id:x}")

        if struc_id == idaapi.BADADDR:
            idc.set_local_type(-1, "struct std::string {char *ptr; size_t length; char buf[0x10];};", idaapi.PT_TYP)
            print("create std::string")

        func_tinfo = idaapi.tinfo_t()
        cfunc = idaapi.decompile(func.start_ea)
        cfunc.get_func_type(func_tinfo)
        func_details = idaapi.func_type_data_t()
        func_tinfo.get_func_details(func_details)


        std_string_tinfo = idaapi.tinfo_t()
        std_string_tinfo.get_named_type(idaapi.get_idati(), "std::string")
        std_string_ptr_tinfo = idaapi.tinfo_t()
        std_string_ptr_tinfo.create_ptr(std_string_tinfo)

        func_details[0].type = std_string_ptr_tinfo
        func_tinfo.create_func(func_details)
        idaapi.apply_tinfo(func.start_ea, func_tinfo, idaapi.TINFO_DEFINITE)
    def getBuiltinGlobalTypePython(self):
        logger.debug('Getting GlobalType the Python way')
        sym = idaapi.til_symbol_t()
        if using_ida7api:
            ret = idaapi.choose_named_type(sym, idaapi.get_idati(),
                                           'Choose type to apply',
                                           idaapi.NTF_SYMM, None)
        else:
            ret = idaapi.choose_named_type2(idaapi.cvar.idati,
                                            'Choose type to apply',
                                            idaapi.NTF_SYMM, None, sym)
        if not ret:
            logger.debug('User canceled. Bailing out')
            return

        tuple = idaapi.get_named_type(sym.til, sym.name, 0)

        if tuple == None:
            logger.debug('Could not find %s', sym.name)
            return

        tinfo = idaapi.tinfo_t()
        tinfo.deserialize(sym.til, tuple[1], tuple[2])

        return tinfo
Beispiel #5
0
def ParseAMXNativeInfo():
    ida_string = idautils.Strings()

    last_native = ""
    for string in ida_string:
        for native in natives:
            if (str(string) == native and last_native != native):
                last_native = native
                for xref in XrefsTo(string.ea):
                    offset = xref.frm + 4
                    for native_addr in XrefsFrom(offset):
                        # Rename native handler function n_NativeName
                        idc.MakeNameEx(native_addr.to, "n_" + native,
                                       idc.SN_NOWARN)

                        # Setup function prototype & automate setting the native's
                        tinfo = idaapi.tinfo_t()
                        ida_typeinf.guess_tinfo(native_addr.to, tinfo)
                        funcdata = idaapi.func_type_data_t()
                        tinfo.get_func_details(funcdata)
                        tinfo2 = idaapi.tinfo_t()
                        tinfo2.get_named_type(idaapi.get_idati(),
                                              "Native" + native + "Params")
                        tinfo3 = idaapi.tinfo_t()
                        tinfo3.create_ptr(tinfo2)
                        if (
                                len(funcdata)
                        ):  # For some reason this is 0 for some natives with params? Not sure why...
                            funcdata[len(funcdata) - 1].type = tinfo3
                            function_tinfo = idaapi.tinfo_t()
                            function_tinfo.create_func(funcdata)
                            idaapi.apply_tinfo2(native_addr.to, function_tinfo,
                                                idaapi.TINFO_DEFINITE)
Beispiel #6
0
def get_tinfo(name):
    idati = idaapi.get_idati()
    ti = idaapi.tinfo_t()

    for ordinal in range(1, idaapi.get_ordinal_qty(idati) + 1):
        if ti.get_numbered_type(idati, ordinal) and ti.dstr() == name:
            return ti
    return None
Beispiel #7
0
def InsertType(type_obj, fReplace=False):
    # print("Insert type %s." % type_obj.name)
    wrapperTypeString = b'\x0d\x01\x01'
    if getTypeOrdinal(type_obj.name) != 0:
        idx = getTypeOrdinal(type_obj.name)
        t = ImportLocalType(idx)
        if (t.TypeFields is None or t.TypeFields == "") and t.is_sue():
            fReplace = True
        if t.isEqual(type_obj) or type_obj.TypeString == wrapperTypeString:
            return 1
        if not fReplace:
            type_obj = DuplicateResolver(t, type_obj, False)
    else:
        idx = ida_typeinf.alloc_type_ordinals(idaapi.get_idati(), 1)
    tif = ida_typeinf.tinfo_t()
    ret = tif.deserialize(ida_typeinf.get_idati(), type_obj.GetTypeString(),
                          type_obj.TypeFields, type_obj.fieldcmts)
    if not ret:
        idaapi.warning(
            "Error on tinfo deserilization, type name = %s, ret = %d" %
            (type_obj.name, ret))
        ret = -1
    else:
        ret = tif.set_numbered_type(idaapi.get_idati(), idx, 0x4,
                                    type_obj.name)
    del tif
    # ret = idaapi.set_numbered_type(
    #     my_ti,
    #     idx,
    #     0x4,
    #     type_obj.name,
    #     type_obj.GetTypeString(),
    #     type_obj.TypeFields,
    #     type_obj.cmt,
    #     type_obj.fieldcmts
    # )
    # print "Insert type %s. ret = %d"%(type_obj.name,ret)
    if (ida_pro.IDA_SDK_VERSION < 700
            and ret != 1) or (ida_pro.IDA_SDK_VERSION >= 700 and ret != 0):
        print("bad insert: %s; ret = %d" % (type_obj.name, ret))
    return ret
Beispiel #8
0
def get_typeinf(typestr):
    if not typestr:
        # Passing None to tinfo_t.get_named_type() can crash IDA
        return None
    tif = idaapi.tinfo_t()
    if tif.get_named_type(idaapi.get_idati(), typestr):
        return tif
    PT_SILENT = 1  # in IDA7.0 idc.PT_SILENT=2, which is incorrect
    py_type = idc.parse_decl(typestr, PT_SILENT)
    if not py_type:
        return None
    return deserialize_tinfo(py_type[1:])
Beispiel #9
0
def get_local_type(ordinal=None, name=None, til=None):
    if til is None:
        til = idaapi.get_idati()

    tif = idaapi.tinfo_t()
    if ordinal is not None:
        found = tif.get_numbered_type(til, ordinal)
        if not found:
            raise ValueError("Unknown ordinal type.")

    elif name is not None:
        found = tif.get_named_type(til, name)
        if not found:
            raise ValueError("Unknown named type.")

    else:
        raise ValueError("Must specify type ordinal or name.")

    return til, tif
Beispiel #10
0
    def getBuiltinGlobalTypePython(self):
        logger.debug('Getting GlobalType the Python way')
        sym = idaapi.til_symbol_t()
        if using_ida7api:
            ret = idaapi.choose_named_type(sym, idaapi.get_idati(), 'Choose type to apply', idaapi.NTF_SYMM, None)
        else:
            ret = idaapi.choose_named_type2(idaapi.cvar.idati, 'Choose type to apply', idaapi.NTF_SYMM, None, sym)
        if not ret:
            logger.debug('User canceled. Bailing out')
            return

        tuple = idaapi.get_named_type(sym.til, sym.name, 0)

        if tuple == None:
            logger.debug('Could not find %s', sym.name)
            return

        tinfo = idaapi.tinfo_t()
        tinfo.deserialize(sym.til, tuple[1], tuple[2])

        return tinfo
Beispiel #11
0
def size(string):
    '''Returns the size of a type described by a C declaration in `string`.'''
    til = idaapi.cvar.idati if idaapi.__version__ < 7.0 else idaapi.get_idati()

    string = string.strip()
    if string.lower() == 'void':
        return 0
    elif string.startswith('class') and string.endswith('&'):
        res = idaapi.idc_parse_decl(til, 'void*;', 0)
    else:
        semicoloned = string if string.endswith(';') else "{:s};".format(
            string)
        res = idaapi.idc_parse_decl(til, internal.utils.string.to(semicoloned),
                                    0)

    if res is None:
        raise internal.exceptions.DisassemblerError(
            u"Unable to parse the specified C declaration (\"{:s}\").".format(
                internal.utils.string.escape(string, '"')))
    _, type, _ = res
    f = idaapi.get_type_size0 if idaapi.__version__ < 6.8 else idaapi.calc_type_size
    return f(til, type)
Beispiel #12
0
def GetTypeString(parsedList, name=""):
    ti = idaapi.get_idati()
    # print "GetTypeString: name %s"%self.name
    the_bytes = []
    for thing in parsedList:
        if type(thing) == int:  # if it's a byte, just put it back in
            the_bytes.append(thing)
        elif len(thing) == 1:
            if list(thing.keys())[0] == "local_type":
                the_bytes.append(ord("="))  # a type starts with =
            # print type(thing["local_type"]),thing["local_type"]
            ordinal = idaapi.get_type_ordinal(
                ti,
                list(thing.values())
                [0])  # get the ordinal of the Local Type based on its name
            if ordinal > 0:
                the_bytes = the_bytes + encode_ordinal_to_string(ordinal)
            else:
                raise NameError("Depends local type not in IDB")
        else:
            raise NameError("Wrong depend record for type: %s!" % name)
    packed = struct.pack("%dB" % len(the_bytes), *the_bytes)
    return packed
Beispiel #13
0
 def find_type_by_name(name):
     my_ti = idaapi.get_idati()
     ordinal = idaapi.get_type_ordinal(my_ti, name)
Beispiel #14
0
def get_typeinf(typestr):
    tif = idaapi.tinfo_t()
    tif.get_named_type(idaapi.get_idati(), typestr)
    return tif
Beispiel #15
0
# Copyright (C) 2020 Alibaba Group Holding Limited

import idaapi
import idc
import shutil
import os

idb_fp = idc.get_idb_path()
modulename = os.path.basename(idb_fp)[:-4]
idb_dirpath = os.path.dirname(idb_fp)
til_dirpath = os.path.join(idb_dirpath, "tils")
if not os.path.isdir(til_dirpath):
    os.makedirs(til_dirpath)
self_til = idaapi.get_idati()
ida_typeinf.compact_til(self_til)
ida_typeinf.store_til(self_til, None,
                      os.path.join(til_dirpath, modulename + ".til"))
#til_fp = modulename + ".til"
#shutil.copy(til_fp, til_fp[:-4]+".exported.til")
idc.Exit(0)
Beispiel #16
0
    "short": 's',
    "char": 'c',
    "float": 'f',
    "void": 'p',
    "_DWORD": "i",
    "_QWORD": 'j',
    "_WORD": 's',
    "_BYTE": 'b',
    "unsigned __int64": 'j',
    "unsigned __int16": 's',
    "double": 'd',
    "long double": 'D'
}
size2c = {1: 'b', 2: 's', 4: 'i', 8: 'j'}
basec = set(t2c.values())
idaapi.get_idati()

MAX_INT32 = (1 << 32) - 1
MAX_INT8 = (1 << 8) - 1
MAX_INT16 = (1 << 16) - 1

_common_dbg = Debugger()

_common_dbg.on()

Arch = None


def get_arch():
    global Arch
    """