コード例 #1
0
ファイル: LazyIDA.py プロジェクト: L4ys/LazyIDA
    def remove_rettype(self, vu):
        if vu.item.citype == idaapi.VDI_FUNC:
            # current function
            ea = vu.cfunc.entry_ea
            old_func_type = idaapi.tinfo_t()
            if not vu.cfunc.get_func_type(old_func_type):
                return False
        elif vu.item.citype == idaapi.VDI_EXPR and vu.item.e.is_expr() and vu.item.e.type.is_funcptr():
            # call xxx
            ea = vu.item.get_ea()
            old_func_type = idaapi.tinfo_t()

            func = idaapi.get_func(ea)
            if func:
                try:
                    cfunc = idaapi.decompile(func)
                except idaapi.DecompilationFailure:
                    return False

                if not cfunc.get_func_type(old_func_type):
                    return False
            else:
                return False
        else:
            return False

        fi = idaapi.func_type_data_t()
        if ea != idaapi.BADADDR and old_func_type.get_func_details(fi):
            # Return type is already void
            if fi.rettype.is_decl_void():
                # Restore ret type
                if ea not in self.ret_type:
                    return True
                ret = self.ret_type[ea]
            else:
                # Save ret type and change it to void
                self.ret_type[ea] = fi.rettype
                ret = idaapi.BT_VOID

            # Create new function info with new rettype
            fi.rettype = idaapi.tinfo_t(ret)

            # Create new function type with function info
            new_func_type = idaapi.tinfo_t()
            new_func_type.create_func(fi)

            # Apply new function type
            if idaapi.apply_tinfo2(ea, new_func_type, idaapi.TINFO_DEFINITE):
                return vu.refresh_view(True)

        return False
コード例 #2
0
ファイル: apply_callee_type.py プロジェクト: 4lextg/flare-ida
 def getUserDeclType(self, decl):
     tinfo = idaapi.tinfo_t()
     ret = idaapi.parse_decl2(idaapi.cvar.idati, decl, 'blah', tinfo, 0)
     if not ret:
         self.logger.info('parse_decl2 failed')
         return None
     return tinfo
コード例 #3
0
ファイル: ida.py プロジェクト: nihilus/epanos
def parse_decl(arg):
    '''str -> tinfo_t'''
    ti = idaapi.tinfo_t()
    success = idaapi.parse_decl2(idaapi.cvar.idati, arg + ';', '', ti, 0)
    if success is False:
        raise ParseDeclError("%s: couldn't parse type" % arg)
    return ti
コード例 #4
0
ファイル: ida.py プロジェクト: nihilus/epanos
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
コード例 #5
0
 def getUserDeclType(self, decl):
     tinfo = idaapi.tinfo_t()
     #logger.debug('Trying to parse declaration: %r', decl)
     ret = idaapi.parse_decl2(idaapi.cvar.idati, decl, tinfo, idaapi.PT_TYP)
     #logger.debug('Return from parse_decl2: %r', ret)
     if ret is None:
         logger.info('parse_decl2 failed')
         return None
     return tinfo
コード例 #6
0
ファイル: apply_callee_type.py プロジェクト: 4lextg/flare-ida
 def getLocalType(self):
     ret = idaapi.choose_local_tinfo(idaapi.cvar.idati, 'Choose local type to apply', None, None)
     if not ret:
         self.logger.debug('User canceled. Bailing out')
         return
     #ret is a numbered type rather than the name
     tinfo = idaapi.tinfo_t()
     tinfo.get_numbered_type(idaapi.cvar.idati, ret)
     return tinfo
コード例 #7
0
ファイル: ida.py プロジェクト: nihilus/epanos
def get_stkvar_map(ea):
    '''ea_t -> {int : (str, tinfo_t)}'''
    # NOTE mutates d
    frame = idaapi.get_frame(ea)

    def make_map(d, (off, name, _)):
        mem = idaapi.get_member(frame, off)
        ti = idaapi.tinfo_t()
        idaapi.get_or_guess_member_tinfo2(mem, ti)
        d[off] = (name, ti)
        return d
コード例 #8
0
ファイル: apply_callee_type.py プロジェクト: 4lextg/flare-ida
    def getBuiltinGlobalTypePython(self):
        self.logger.debug('Getting GlobalType the Python way')
        sym = idaapi.til_symbol_t()
        ret = idaapi.choose_named_type2(idaapi.cvar.idati, 'Choose type to apply', idaapi.NTF_SYMM, None, sym)
        if not ret:
            self.logger.debug('User canceled. Bailing out')
            return

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

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

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

        return tinfo
コード例 #9
0
ファイル: classes.py プロジェクト: aohwang/HexRaysPyTools
 def update_local_type(self):
     if self.modified:
         final_tinfo = idaapi.tinfo_t()
         udt_data = idaapi.udt_type_data_t()
         self.tinfo.get_udt_details(udt_data)
         if len(udt_data) == len(self.virtual_functions):
             for udt_member, virtual_function in zip(
                     udt_data, self.virtual_functions):
                 udt_member.name = virtual_function.name
                 udt_member.type = virtual_function.tinfo
                 virtual_function.commit()
             final_tinfo.create_udt(udt_data, idaapi.BTF_STRUCT)
             final_tinfo.set_numbered_type(idaapi.cvar.idati, self.ordinal,
                                           idaapi.NTF_REPLACE, self.name)
             self.modified = False
         else:
             print(
                 "[ERROR] Something have been modified in Local types. Please refresh this view"
             )
コード例 #10
0
def test_xx(idx, ctx):
    import ida_typeinf
    uni = ctx.get_expr('union_type')
    var = ctx.get_var('v1')
    tname = var.typ.dstr().split(' ')[0]
    tinfo = idaapi.tinfo_t()
    if tname == 'class1':
        idaapi.parse_decl2(idaapi.cvar.idati, 'vptr1_1 *;', tinfo,
                           idaapi.PT_TYP)
        uni[0].type = tinfo
        uni[0].m = 0
    elif tname == "class2":
        idaapi.parse_decl2(idaapi.cvar.idati, 'struc_5 *;', tinfo,
                           idaapi.PT_TYP)
        uni[0].type = tinfo
        uni[0].m = 1
    else:
        return False
    return True
コード例 #11
0
 def visit_expr(self, expression):
     if expression.op == idaapi.cot_add and expression.x.op == idaapi.cot_var and expression.y.op == idaapi.cot_num:
         # print "ADD TYPE", expression.type.dstr()
         index = expression.x.v.idx
         if index in self.negative_lvars:
             offset = expression.y.numval()
             if offset >= self.negative_lvars[index].size:
                 self.create_containing_record(expression, index, offset)
     elif expression.op == idaapi.cot_sub and expression.x.op == idaapi.cot_var and expression.y.op == idaapi.cot_num:
         # print "SUB TYPE", expression.type.dstr(), expression.x.type.dstr()
         index = expression.x.v.idx
         if index in self.negative_lvars:
             offset = -expression.y.n.value(idaapi.tinfo_t(idaapi.BT_INT))
             self.create_containing_record(expression, index, offset)
     # elif expression.op == idaapi.cot_var:
     #     index = expression.v.idx
     #     if index in self.negative_lvars:
     #         self.create_containing_record(expression, index, 0)
     return 0
コード例 #12
0
ファイル: IDATypeWrapers.py プロジェクト: zeuscane/DIE
    def __init__(self, ea, iatEA=None, library_name=None):
        """
        Ctor
        """
        self.logger = logging.getLogger(__name__)

        self.ea = ea  # Effective Address of the function
        self.iatEA = iatEA  # If imported function, the address in the IAT

        try:
            function = sark.Function(ea)
        except sark.exceptions.SarkNoFunction:
            raise DIE.Lib.DIE_Exceptions.DieNoFunction(
                "No Function at 0x%08X" % (ea, ))

        self.funcName = get_function_name(function.ea)
        self.func_start = function.startEA
        self.func_end = function.endEA

        self.proto_ea = self.getFuncProtoAdr()  # Address of function prototype
        self.typeInfo = idaapi.tinfo_t()  # Function type info
        self.funcInfo = idaapi.func_type_data_t()  # Function info
        self.argNum = 0  # Number of input arguments

        self.args = []  # Function argument list
        self.retArg = None  # Return argument

        self.library_name = library_name  # If library function, name of containing library
        self.isLibFunc = False
        if self.iatEA:
            self.isLibFunc = True  # Is this a library function

        elif sark.Function(ea).flags & (idaapi.FUNC_LIB | idaapi.FUNC_THUNK):
            self.isLibFunc = True

        try:
            self.getArguments()

        except Exception as ex:
            self.logger.error(
                "Failed to get function arguments for function %s: %s",
                self.funcName, ex)
コード例 #13
0
ファイル: apply_callee_type.py プロジェクト: zhouat/flare-ida
    def getBuiltinGlobalTypePython(self):
        self.logger.debug('Getting GlobalType the Python way')
        sym = idaapi.til_symbol_t()
        ret = idaapi.choose_named_type2(idaapi.cvar.idati,
                                        'Choose type to apply',
                                        idaapi.NTF_SYMM, None, sym)
        if not ret:
            self.logger.debug('User canceled. Bailing out')
            return

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

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

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

        return tinfo
コード例 #14
0
ファイル: Actions.py プロジェクト: ydc1992/HexRaysPyTools
 def activate(self, ctx):
     # ctx - action_activation_ctx_t
     vu = idaapi.get_tform_vdui(ctx.form)
     function_tinfo = idaapi.tinfo_t()
     if not vu.cfunc.get_func_type(function_tinfo):
         return
     function_details = idaapi.func_type_data_t()
     function_tinfo.get_func_details(function_details)
     convention = idaapi.CM_CC_MASK & function_details.cc
     if convention == idaapi.CM_CC_CDECL:
         function_details.cc = idaapi.CM_CC_SPECIAL
     elif convention in (idaapi.CM_CC_STDCALL, idaapi.CM_CC_FASTCALL, idaapi.CM_CC_PASCAL, idaapi.CM_CC_THISCALL):
         function_details.cc = idaapi.CM_CC_SPECIALP
     elif convention == idaapi.CM_CC_ELLIPSIS:
         function_details.cc = idaapi.CM_CC_SPECIALE
     else:
         return
     function_tinfo.create_func(function_details)
     idaapi.apply_tinfo2(vu.cfunc.entry_ea, function_tinfo, idaapi.TINFO_DEFINITE)
     vu.refresh_view(True)
コード例 #15
0
ファイル: helper.py プロジェクト: wxjwz/HexRaysPyTools
def create_padding_udt_member(offset, size):
    # type: (long, long) -> idaapi.udt_member_t
    """ Creates internal IDA structure with name gap_XXX and appropriate size and offset """

    udt_member = idaapi.udt_member_t()
    udt_member.name = "gap_{0:X}".format(offset)
    udt_member.offset = offset
    udt_member.size = size

    if size == 1:
        udt_member.type = const.BYTE_TINFO
    else:
        array_data = idaapi.array_type_data_t()
        array_data.base = 0
        array_data.elem_type = const.BYTE_TINFO
        array_data.nelems = size
        tmp_tinfo = idaapi.tinfo_t()
        tmp_tinfo.create_array(array_data)
        udt_member.type = tmp_tinfo
    return udt_member
コード例 #16
0
    def __init__(self, cdg, name, return_type=idaapi.tinfo_t(idaapi.BT_VOID)):
        self.emitted = False
        self.cdg = cdg
        self.callinfo = ida_hexrays.mcallinfo_t()
        self.callinfo.callee = idaapi.BADADDR
        self.callinfo.solid_args = 0x00
        self.callinfo.call_spd = 0x00
        self.callinfo.stkargs_top = 0x00
        self.callinfo.cc = idaapi.CM_CC_FASTCALL
        self.callinfo.return_type = return_type
        self.callinfo.flags = idaapi.FCI_SPLOK | idaapi.FCI_FINAL | idaapi.FCI_PROP
        self.callinfo.role = idaapi.ROLE_UNK

        glbhigh_off = cdg.mba.get_stack_region(
        ).off + cdg.mba.get_stack_region().size
        # what memory is visible to the call : GLBLOW - GLBHIGH
        self.callinfo.visible_memory.add(ida_hexrays.ivl_t(0x00, 0x100000))
        self.callinfo.visible_memory.add(
            ida_hexrays.ivl_t(glbhigh_off, 0xFFFFFFFFFFFFFFFF - glbhigh_off))
        # spoiled locations : GLBLOW - GLBHIGH
        self.callinfo.spoiled.mem.add(ida_hexrays.ivl_t(0x00, 0x100000))
        self.callinfo.spoiled.mem.add(
            ida_hexrays.ivl_t(glbhigh_off, 0xFFFFFFFFFFFFFFFF - glbhigh_off))

        self.callins = MicroInstruction(ida_hexrays.m_call, self.cdg.insn.ea)
        self.callins.l.make_helper(name)
        self.callins.d.t = ida_hexrays.mop_f
        self.callins.d.size = 0x00
        self.callins.d.f = self.callinfo

        if (return_type.is_void()):
            self.ins = self.callins
        else:
            self.callins.d.size = return_type.get_size()
            self.ins = MicroInstruction(ida_hexrays.m_mov, self.cdg.insn.ea)
            self.ins.l.t = ida_hexrays.mop_d
            self.ins.l.d = self.callins
            self.ins.l.size = self.callins.d.size
            self.ins.d.t = ida_hexrays.mop_r
            self.ins.d.r = 0x00
            self.ins.d.size = self.callins.d.size
コード例 #17
0
 def processStructIDA7(self, regPrefix, struc, sid):
     members = loadMembers(struc, sid)
     foundFunctions = 0
     for off, name, memb in members:
         funcname  = self.filterName(regPrefix, name)
         tup = idaapi.get_named_type(None, funcname, idaapi.NTF_SYMM)
         if tup is None:
             continue
         code, type_str, fields_str, cmt, field_cmts, sclass, value  = tup
         foundFunctions += 1
         tif = idaapi.tinfo_t()
         tif.deserialize(None, type_str, fields_str, cmt)
         if not tif.is_func():
             logger.debug('Found named type, but not a function: %s', funcname)
             continue
         tif.create_ptr(tif)
         ret = idaapi.set_member_tinfo(struc, memb, off, tif, 0)
         if ret != idaapi.SMT_OK:
             logger.info("Got set_member_tinfo ret code: %d" % ret)
         else:
             logger.info('set_member_tinfo: %s', tif.dstr())
コード例 #18
0
ファイル: struct_typer.py プロジェクト: fireeye/flare-ida
 def processStructIDA7(self, regPrefix, struc, sid):
     members = loadMembers(struc, sid)
     foundFunctions = 0
     for off, name, memb in members:
         funcname  = self.filterName(regPrefix, name)
         tup = idaapi.get_named_type(None, funcname, idaapi.NTF_SYMM)
         if tup is None:
             continue
         code, type_str, fields_str, cmt, field_cmts, sclass, value  = tup
         foundFunctions += 1
         tif = idaapi.tinfo_t()
         tif.deserialize(None, type_str, fields_str, cmt)
         if not tif.is_func():
             logger.debug('Found named type, but not a function: %s', funcname)
             continue
         tif.create_ptr(tif)
         ret = idaapi.set_member_tinfo(struc, memb, off, tif, 0)
         if ret != idaapi.SMT_OK:
             logger.info("Got set_member_tinfo ret code: %d" % ret)
         else:
             logger.info('set_member_tinfo: %s', tif.dstr())
コード例 #19
0
 def set_first_argument_type(self, name):
     func_data = idaapi.func_type_data_t()
     func_tinfo = self.tinfo.get_pointed_object()
     class_tinfo = idaapi.tinfo_t()
     if func_tinfo.get_func_details(func_data) and func_tinfo.get_nargs() and \
             class_tinfo.get_named_type(idaapi.cvar.idati, name):
         class_tinfo.create_ptr(class_tinfo)
         first_arg_tinfo = func_data[0].type
         if (first_arg_tinfo.is_ptr() and first_arg_tinfo.get_pointed_object().is_udt()) or \
                 helper.is_legal_type(func_data[0].type):
             func_data[0].type = class_tinfo
             func_data[0].name = "this"
             func_tinfo.create_func(func_data)
             func_tinfo.create_ptr(func_tinfo)
             if func_tinfo.dstr() != self.tinfo.dstr():
                 self.tinfo = func_tinfo
                 self.tinfo_modified = True
                 for parent in self.parents:
                     parent.modified = True
         else:
             print("[Warning] function {0} probably have wrong type".format(self.name))
コード例 #20
0
def get_winapi_decl(name):
    '''
    fetch the C function declaration for the given Windows API function.
    '''
    tup = idaapi.get_named_type(None, name, idaapi.NTF_SYMM)
    if tup is None:
        raise ValueError("failed to fetch type")
    code, type_str, fields_str, cmt, field_cmts, sclass, value = tup
    ti = idaapi.tinfo_t()
    ti.deserialize(None, type_str, fields_str, cmt)

    # the rendered declaration from IDA doesn't include the function name,
    # so insert the function name, naively.
    #
    # for example;
    #
    #    > DWORD (DWORD a, DWORD b)
    #    < DWORD foo(DWORD a, DWORD b);
    decl = str(ti).replace("(", " " + name + "(") + ";"

    return decl
コード例 #21
0
    def get_padding_member(offset, size):
        udt_member = idaapi.udt_member_t()
        if size == 1:
            udt_member.name = "gap_{0:X}".format(offset)
            udt_member.type = Const.BYTE_TINFO
            udt_member.size = Const.BYTE_TINFO.get_size()
            udt_member.offset = offset
            return udt_member

        array_data = idaapi.array_type_data_t()
        array_data.base = 0
        array_data.elem_type = Const.BYTE_TINFO
        array_data.nelems = size
        tmp_tinfo = idaapi.tinfo_t()
        tmp_tinfo.create_array(array_data)

        udt_member.name = "gap_{0:X}".format(offset)
        udt_member.type = tmp_tinfo
        udt_member.size = size
        udt_member.offset = offset
        return udt_member
コード例 #22
0
    def get_member(self, offset, index, **kwargs):

        # Handling all sorts of functions call
        try:
            call_expr, arg_expr = kwargs['call'], kwargs['arg']
            arg_index, arg_type = Helper.get_func_argument_info(
                call_expr, arg_expr)
            if arg_type.equals_to(Const.PVOID_TINFO) or arg_type.equals_to(
                    Const.CONST_PVOID_TINFO):
                if SCAN_ALL_ARGUMENTS or not arg_index:
                    self.scan_function(call_expr.x.obj_ea, offset, arg_index)
                return self.create_member(offset, index)
            elif arg_type.equals_to(Const.X_WORD_TINFO) or arg_type.equals_to(Const.PX_WORD_TINFO) or \
                    arg_type.equals_to(Const.PBYTE_TINFO):
                nice_tinfo = Helper.get_nice_pointed_object(arg_type)
                if nice_tinfo:
                    return self.create_member(offset, index, nice_tinfo)
                if SCAN_ALL_ARGUMENTS or not arg_index:
                    self.scan_function(call_expr.x.obj_ea, offset, arg_index)
                return self.create_member(offset, index, pvoid_applicable=True)
            arg_type.remove_ptr_or_array()
            return self.create_member(offset, index, arg_type)
        except KeyError:
            pass

        # When we have pointer dereference on the left side and expression on the right
        try:
            right_expr, cast_type = kwargs['object'], kwargs['default']
            if right_expr.op in (idaapi.cot_ref, idaapi.cot_cast):
                right_expr = right_expr.x
            if right_expr.op == idaapi.cot_obj:
                member_type = idaapi.tinfo_t(right_expr.type)
                member_type.create_ptr(member_type)
                return self.create_member(offset, index, member_type,
                                          right_expr.obj_ea)
            if right_expr.op in Const.COT_ARITHMETIC:
                return self.create_member(offset, index, cast_type)
            return self.create_member(offset, index, right_expr.type)
        except KeyError:
            pass
コード例 #23
0
    def visit_expr(self, expression):
        # Checks if expression is reference by pointer or by value
        if expression.op == idaapi.cot_memptr:
            struct_type = expression.x.type.get_pointed_object()
        elif expression.op == idaapi.cot_memref:
            struct_type = expression.x.type
        else:
            return 0

        # Getting information about structure, field offset, address and one line corresponding to code
        ordinal = struct_type.get_ordinal()
        if ordinal == 0:
            t = idaapi.tinfo_t()
            struct_name = struct_type.dstr().split()[
                -1]  # Get rid of `struct` prefix or something else
            t.get_named_type(idaapi.cvar.idati, struct_name)
            ordinal = t.get_ordinal()

        field_offset = expression.m
        ea = self.__find_ref_address(expression)
        usage_type = self.__get_type(expression)

        if ea == idaapi.BADADDR or not ordinal:
            logger.warning(
                "Failed to parse at address {0}, ordinal - {1}, type - {2}".
                format(Helper.to_hex(ea), ordinal, struct_type.dstr()))

        one_line = self.__get_line()

        occurrence_offset = ea - self.__function_address
        xref_info = (occurrence_offset, one_line, usage_type)

        # Saving results
        if ordinal not in self.__result:
            self.__result[ordinal] = {field_offset: [xref_info]}
        elif field_offset not in self.__result[ordinal]:
            self.__result[ordinal][field_offset] = [xref_info]
        else:
            self.__result[ordinal][field_offset].append(xref_info)
        return 0
コード例 #24
0
    def parse_declaration(declaration):
        m = re.search(r"^(\w+[ *]+)(\w+)(\[(\d+)\])?$", declaration)
        if m is None:
            logger.error("Member declaration should be like `TYPE_NAME NAME[SIZE]` (Array is optional)")
            return

        type_name, field_name, _, arr_size = m.groups()
        if field_name[0].isdigit():
            logger.error("Bad field name")
            return

        result = idc.parse_decl(type_name, 0)
        if result is None:
            logger.error("Failed to parse member type. It should be like `TYPE_NAME NAME[SIZE]` (Array is optional)")
            return

        _, tp, fld = result
        tinfo = idaapi.tinfo_t()
        tinfo.deserialize(idaapi.cvar.idati, tp, fld, None)
        if arr_size:
            assert tinfo.create_array(tinfo, int(arr_size))
        return tinfo, field_name
コード例 #25
0
ファイル: IDATypeWrapers.py プロジェクト: 453483289/DIE
    def __init__(self, ea, iatEA=None, library_name=None):
        """
        Ctor
        """
        self.logger = logging.getLogger(__name__)

        self.ea = ea        # Effective Address of the function
        self.iatEA = iatEA  # If imported function, the address in the IAT

        try:
            function = sark.Function(ea)
        except sark.exceptions.SarkNoFunction:
            raise DIE.Lib.DIE_Exceptions.DieNoFunction("No Function at 0x%08X" % (ea, ))

        self.funcName = get_function_name(function.ea)
        self.func_start = function.startEA
        self.func_end = function.endEA

        self.proto_ea = self.getFuncProtoAdr()      # Address of function prototype
        self.typeInfo = idaapi.tinfo_t()            # Function type info
        self.funcInfo = idaapi.func_type_data_t()   # Function info
        self.argNum = 0                             # Number of input arguments

        self.args = []      # Function argument list
        self.retArg = None  # Return argument

        self.library_name = library_name  # If library function, name of containing library
        self.isLibFunc = False
        if self.iatEA:
            self.isLibFunc = True  # Is this a library function

        elif sark.Function(ea).flags & (idaapi.FUNC_LIB | idaapi.FUNC_THUNK):
            self.isLibFunc = True

        try:
            self.getArguments()

        except Exception as ex:
            self.logger.error("Failed to get function arguments for function %s: %s", self.funcName, ex)
コード例 #26
0
ファイル: npkgen.py プロジェクト: wxh0000mm/bincat
    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_tinfo(imp_t, ea):
            if not imp_t.is_func():
                self.imports.append(idaapi.print_type(ea, PRTYPE_1LINE) + ";")
            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, PRTYPE_1LINE) + " {}")
        return True
コード例 #27
0
ファイル: index.py プロジェクト: zyantific/continuum
    def index_types_for_this_idb(self, purge_locally_deleted=False):
        """Indexes local types from this IDB into the DB."""
        cursor = self.db.cursor()

        # Create or update types.
        local_types = set()
        for cur_named_type in LocalTypesIter():
            local_types.add(cur_named_type)
            code, type_str, fields_str, cmt, field_cmts, sclass, value = idaapi.get_named_type64(
                idaapi.cvar.idati,
                cur_named_type,
                idaapi.NTF_TYPE | idaapi.NTF_SYMM,
            )

            ti = idaapi.tinfo_t()
            ti.deserialize(idaapi.cvar.idati, type_str, fields_str)
            c_type = ti._print(
                cur_named_type,
                idaapi.PRTYPE_1LINE | idaapi.PRTYPE_TYPE | idaapi.PRTYPE_SEMI,
                0, 0, None, cmt,
            )

            # TODO: prefer more concrete type rather than stupidly replacing.
            cursor.execute(
                "INSERT OR REPLACE INTO types (name, is_fwd_decl, c_type) VALUES (?, ?, ?)",
                [cur_named_type, ti.is_forward_decl(), c_type],
            )

        # If requested, remove locally deleted types from index.
        if purge_locally_deleted:
            cursor.execute("SELECT id, name FROM types")
            deleted_types = [x['id'] for x in cursor.fetchall() if x['name'] not in local_types]
            if deleted_types:
                print("[continuum] Deleting {} types".format(len(deleted_types)))
                query_fmt = "DELETE FROM types WHERE id IN ({})"
                cursor.execute(query_fmt.format(','.join('?' * len(deleted_types))), deleted_types)

        self.db.commit()
コード例 #28
0
def make_helper_call(ret_type, name, arg_types): # type: (str, str, typing.List[str]) -> hr.cexpr_t
    """Make a call expression to a helper function (non-existing function with arbitrary name)."""

    helper_expr = hr.cexpr_t()
    helper_expr.ea = idaapi.BADADDR
    helper_expr.op = hr.cot_helper
    helper_expr.helper = name

    call_expr = hr.cexpr_t()
    call_expr.op = hr.cot_call
    call_expr.x = helper_expr
    call_expr.a = hr.carglist_t()

    # EXTREMELY IMPORTANT: set the expression types. Without this, Hex-Rays will crash
    # in mysterious ways.
    t = idaapi.tinfo_t()
    idaapi.parse_decl2(idaapi.cvar.idati, "%s (__cdecl *)(%s);" % (ret_type, ','.join(arg_types)),
                       t, idaapi.PT_TYP)
    helper_expr.type = t
    call_expr.a.functype = t
    call_expr.type = t.get_rettype()

    return call_expr
コード例 #29
0
 def setData(self, column, value):
     if column == 0:
         if idaapi.is_ident(value) and self.name != value:
             self.name = value
             self.name_modified = True
             for parent in self.parents:
                 parent.modified = True
             return True
     elif column == 1:
         tinfo = idaapi.tinfo_t()
         split = value.split('(')
         if len(split) == 2:
             value = split[0] + ' ' + self.name + '(' + split[1] + ';'
             if idaapi.parse_decl(tinfo, idaapi.cvar.idati, value, idaapi.PT_TYP) is not None:
                 if tinfo.is_func():
                     tinfo.create_ptr(tinfo)
                     if tinfo.dstr() != self.tinfo.dstr():
                         self.tinfo = tinfo
                         self.tinfo_modified = True
                         for parent in self.parents:
                             parent.modified = True
                         return True
     return False
コード例 #30
0
ファイル: fn_fuzzy.py プロジェクト: dhulliger/ida_haru
    def export(self):
        if self.existed() and not self.f_update:
            info('{}: The sample records are present in DB. skipped.'.format(
                self.sha256))
            return False

        self.cur.execute("REPLACE INTO sample values(?, ?)",
                         (self.sha256, self.idb_path))

        pnum = tnum = 0
        records = []
        for fva in idautils.Functions():
            fname = get_func_name(fva)
            tnum += 1
            if self.exclude_libthunk(fva, fname):
                continue
            fhd, bsize = self.calc_fn_ssdeep(fva, fname)
            fhm, cfgnum = self.calc_fn_machoc(fva, fname)
            if fhd and fhm:
                pnum += 1
                f_ana = bool(
                    self.ana_pat.search(fname)) if self.f_ana_exp else False
                tinfo = idaapi.tinfo_t()
                idaapi.get_tinfo(fva, tinfo)
                ptype = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE,
                                           tinfo, fname, '')
                ptype = ptype + ';' if ptype is not None else ptype
                records.append(
                    (self.sha256, fname, fhd, fhm, f_ana, bsize, ptype))
                self.debug(
                    'EXPORT {}: ssdeep={} (size={}), machoc={} (num of CFG={})'
                    .format(fname, fhd, bsize, fhm, cfgnum))

        self.cur.executemany(
            "REPLACE INTO function values (?, ?, ?, ?, ?, ?, ?)", records)
        success('{} of {} functions exported'.format(pnum, tnum))
        return True
コード例 #31
0
 def visit_expr(self, expression):
     if expression.op == idaapi.cot_call and expression.x.op == idaapi.cot_helper and len(expression.a) == 3:
         if expression.x.helper == "CONTAINING_RECORD":
             if expression.a[0].op == idaapi.cot_var:
                 idx = expression.a[0].v.idx
                 if expression.a[1].op == idaapi.cot_helper and expression.a[2].op == idaapi.cot_helper:
                     parent_name = expression.a[1].helper
                     member_name = expression.a[2].helper
                     parent_tinfo = idaapi.tinfo_t()
                     if not parent_tinfo.get_named_type(idaapi.cvar.idati, parent_name):
                         return 0
                     udt_data = idaapi.udt_type_data_t()
                     parent_tinfo.get_udt_details(udt_data)
                     udt_member = filter(lambda x: x.name == member_name, udt_data)
                     if udt_member:
                         tinfo = udt_member[0].type
                         self.result[idx] = NegativeLocalInfo(
                             tinfo,
                             parent_tinfo,
                             udt_member[0].offset / 8,
                             member_name
                         )
                         return 1
     return 0
コード例 #32
0
 def create_class(ordinal):
     tinfo = idaapi.tinfo_t()
     tinfo.get_numbered_type(idaapi.cvar.idati, ordinal)
     vtables = {}
     if tinfo.is_struct():
         udt_data = idaapi.udt_type_data_t()
         tinfo.get_udt_details(udt_data)
         for field_udt in udt_data:
             if field_udt.type.is_ptr():
                 possible_vtable = field_udt.type.get_pointed_object()
                 if possible_vtable.is_struct():
                     v_udt_data = idaapi.udt_type_data_t()
                     possible_vtable.get_udt_details(v_udt_data)
                     for possible_func_udt in v_udt_data:
                         if not possible_func_udt.type.is_funcptr():
                             break
                     else:
                         vtables[field_udt.offset // 8] = possible_vtable
     if vtables:
         class_ = Class(tinfo.dstr(), tinfo, ordinal)
         for offset, vtable_tinfo in vtables.items():
             vtables[offset] = VirtualTable.create(vtable_tinfo, class_)
         class_.vtables = vtables
         return class_
コード例 #33
0
    def recognize_shape(self, indices):
        min_idx = max_idx = None
        if indices:
            min_idx, max_idx = min(indices), max(indices, key=lambda x: (x.row(), x.column()))

        if min_idx == max_idx:
            tinfo = self.get_recognized_shape()
            if tinfo:
                tinfo.create_ptr(tinfo)
                for scanned_var in self.get_unique_scanned_variables(origin=0):
                    scanned_var.apply_type(tinfo)
                self.clear()
        else:
            # indices = sorted(indices)
            start, stop = min_idx.row(), max_idx.row() + 1
            base = self.items[start].offset
            tinfo = self.get_recognized_shape(start, stop)
            if tinfo:
                ptr_tinfo = idaapi.tinfo_t()
                ptr_tinfo.create_ptr(tinfo)
                for scanned_var in self.get_unique_scanned_variables(base):
                    scanned_var.apply_type(ptr_tinfo)
                self.items = filter(lambda x: x.offset < base or x.offset >= base + tinfo.get_size(), self.items)
                self.add_row(Member(base, tinfo, None))
コード例 #34
0
def get_member_type(struct, idx):
    """
    Retrieve the type information for the struct member

    :return: Type string
    """

    member = ida_struct.get_member(struct, idx)
    tif = idaapi.tinfo_t()
    ida_struct.get_member_tinfo(tif, member)
    elements = str(tif).split(' ')
    typ = None
    if len(elements) == 2 and elements[0] == 'unsigned':
        if elements[1] == '__int8':
            typ = 'uint8_t'
        elif elements[1] == '__int16':
            typ = 'uint16_t'
        elif elements[1] == '__int32':
            typ = 'uint32_t'
        elif elements[1] == '__int64':
            typ = 'uint64_t'
        elif elements[1] != '':
            typ = elements[1]
    elif len(elements) == 1:
        if elements[0] == '__int8':
            typ = 'int8_t'
        elif elements[0] == '__int16':
            typ = 'int16_t'
        elif elements[0] == '__int32':
            typ = 'int32_t'
        elif elements[0] == '__int64':
            typ = 'int64_t'
        elif elements[0] != '':
            typ = str(tif)

    return typ
コード例 #35
0
ファイル: helper.py プロジェクト: sfinktah/HexRaysPyTools
def create_padding_udt_member(offset, size):
    # type: (long, long) -> idaapi.udt_member_t
    """ Creates internal IDA structure with name gap_XXX and appropriate size and offset """

    udt_member = idaapi.udt_member_t()
    udt_member.name = "gap_{0:X}".format(offset)
    udt_member.offset = offset
    udt_member.size = size

    if size == 1:
        udt_member.type = const.BYTE_TINFO
    else:
        if size < 1 or size > 0xffffffff:
            print(
                "HexRaysPyTools::core::helper::create_padding_udt_member: size is out of uint32 range (offset:{} size:{})"
                .format(offset, size))
        array_data = idaapi.array_type_data_t()
        array_data.base = 0
        array_data.elem_type = const.BYTE_TINFO
        array_data.nelems = size
        tmp_tinfo = idaapi.tinfo_t()
        tmp_tinfo.create_array(array_data)
        udt_member.type = tmp_tinfo
    return udt_member
コード例 #36
0
 def load(types, fields=None, cmts=None, lib=None):
     ti = idaapi.tinfo_t()
     if not ti.deserialize(lib, types, fields, cmts):
         ti = None
     return ti
コード例 #37
0
 def get_ptr_tinfo(self):
     ptr_tinfo = idaapi.tinfo_t()
     ptr_tinfo.create_ptr(self.tinfo)
     return ptr_tinfo
コード例 #38
0
 def tinfo(self):
     print "[INFO] Ignoring import function at 0x{0:08X}".format(self.address)
     tinfo = idaapi.tinfo_t()
     if idaapi.guess_tinfo2(self.address, tinfo):
         return tinfo
     return Const.DUMMY_FUNC
コード例 #39
0
    def getBuiltinGlobalType(self):
        sym = idaapi.til_symbol_t()
        #dang - no predicate func support via idapython :(
        #idaapi.choose_named_type2(idaapi.cvar.idati, 'Choose type to apply', idaapi.NTF_SYMM, predFunc, sym)
        ret = idaapi.choose_named_type2(idaapi.cvar.idati, 'Choose type to apply', idaapi.NTF_SYMM, None, sym)
        if not ret:
            self.logger.debug('User canceled. Bailing out')
            return
        til = sym.til
        funcname = sym.name

        typ_type = ctypes.POINTER(ctypes.c_ubyte)()
        typ_fields = ctypes.POINTER(ctypes.c_ubyte)()
        typ_cmt = ctypes.POINTER(ctypes.c_ubyte)()
        typ_fieldcmts = ctypes.POINTER(ctypes.c_ubyte)()
        typ_sclass = ctypes.c_ulong()
        value = ctypes.c_ulong()
        ret = get_named_type(
                long(til.this),
                funcname, 
                idaapi.NTF_SYMM, 
                ctypes.byref(typ_type),
                ctypes.byref(typ_fields),
                ctypes.byref(typ_cmt),
                ctypes.byref(typ_fieldcmts),
                ctypes.byref(typ_sclass),
                ctypes.byref(value)
        )
        if ret == 0:
            self.logger.debug('Could not find %s', funcname)
            return
        ########################################
        # the following isn't needed, as moved to tinfo_t usage
        #if typ_type[0] != idaapi.BT_FUNC:
        #    #not positive that the first type value has to be BT_FUNC or not...
        #    # and whether it's important to only apply to funcs or not
        #    self.logger.debug('Found named type, but not a function: %s', funcname)
        #    return
        #type_arr = ctypes.create_string_buffer(0x400)
        #type_arr[0] = chr(idaapi.BT_PTR)
        #manualTypeCopy(type_arr, 1, len(type_arr), typ_type)
        #name_buffer = ctypes.create_string_buffer(0x400)
        #print_type_to_one_line(
        #    name_buffer, 
        #    len(name_buffer),
        #    long(til.this),
        #    typ_type,
        #    funcname,
        #    typ_cmt,
        #    typ_fields,
        #    typ_fieldcmts
        #)
        #self.logger.info('Found type: %s', name_buffer.value)
        ########################################
        #this works as well, but it's deprecated
        #self.logger.info('Trying to set type: %s', name_buffer.value)
        #ret = g_dll.apply_callee_type(
        #    ctypes.c_uint(here),
        #    type_arr,
        #    typ_fields
        #)
        tinfo = idaapi.tinfo_t()
        #self.logger.info('Trying to deserialize stuff')
        #self.logger.info('Type of til: %s', type(til))
        #self.logger.info('Type of typ_type: %s', type(typ_type))
        ret = g_dll.deserialize_tinfo(
            long(tinfo.this),
            long(til.this), 
            ctypes.byref(typ_type), 
            ctypes.byref(typ_fields),
            ctypes.byref(typ_fieldcmts)
        )
        return tinfo
コード例 #40
0
 def type(self):
     self.ti = idaapi.tinfo_t()
     if not idaapi.get_member_tinfo(self.ti, self.member):
         print "[-] can't get member `%s` type" % self.name
         return
     return Type(self.ti)
コード例 #41
0
 def get_ptr_tinfo(self):
     # print self.tinfo.dstr()
     ptr_tinfo = idaapi.tinfo_t()
     ptr_tinfo.create_ptr(self.tinfo)
     return ptr_tinfo
コード例 #42
0
    def pack(self, start=0, stop=None):
        if self.collisions[start:stop].count(True):
            print("[Warning] Collisions detected")
            return

        final_tinfo = idaapi.tinfo_t()
        udt_data = idaapi.udt_type_data_t()
        origin = self.items[start].offset if start else 0
        offset = origin

        for item in [x for x in self.items[start:stop]
                     if x.enabled]:  # Filter disabled members
            gap_size = item.offset - offset
            if gap_size:
                udt_data.push_back(
                    helper.create_padding_udt_member(offset - origin,
                                                     gap_size))
            if item.is_array:
                array_size = self.calculate_array_size(
                    bisect.bisect_left(self.items, item))
                if array_size:
                    udt_data.push_back(
                        item.get_udt_member(array_size, offset=origin))
                    offset = item.offset + item.size * array_size
                    continue
            udt_data.push_back(item.get_udt_member(offset=origin))
            offset = item.offset + item.size

        final_tinfo.create_udt(udt_data, idaapi.BTF_STRUCT)
        cdecl = idaapi.print_tinfo(
            None, 4, 5,
            idaapi.PRTYPE_MULTI | idaapi.PRTYPE_TYPE | idaapi.PRTYPE_SEMI,
            final_tinfo, self.get_name(), None)
        cdecl = idaapi.ask_text(0x10000, '#pragma pack(push, 1)\n' + cdecl,
                                "The following new type will be created")

        if cdecl:
            structure_name = idaapi.idc_parse_decl(idaapi.cvar.idati, cdecl,
                                                   idaapi.PT_TYP)[0]
            previous_ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati,
                                                       structure_name)

            if previous_ordinal:
                reply = QtWidgets.QMessageBox.question(
                    None, "HexRaysPyTools",
                    "Structure already exist. Do you want to overwrite it?",
                    QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
                if reply == QtWidgets.QMessageBox.Yes:
                    idaapi.del_numbered_type(idaapi.cvar.idati,
                                             previous_ordinal)
                    ordinal = idaapi.idc_set_local_type(
                        previous_ordinal, cdecl, idaapi.PT_TYP)
                else:
                    return
            else:
                ordinal = idaapi.idc_set_local_type(-1, cdecl, idaapi.PT_TYP)
            if ordinal:
                print("[Info] New type {0} was added to Local Types".format(
                    structure_name))
                tid = idaapi.import_type(idaapi.cvar.idati, -1, structure_name)
                if tid:
                    tinfo = idaapi.create_typedef(structure_name)
                    ptr_tinfo = idaapi.tinfo_t()
                    ptr_tinfo.create_ptr(tinfo)
                    for scanned_var in self.get_unique_scanned_variables(
                            origin):
                        scanned_var.apply_type(ptr_tinfo)
                    return tinfo
            else:
                print("[ERROR] Structure {0} probably already exist".format(
                    structure_name))
コード例 #43
0
ファイル: apply_callee_type.py プロジェクト: 4lextg/flare-ida
    def getBuiltinGlobalTypeCtypes(self):
        self.logger.debug('Getting GlobalType the Ctypes way')

        ############################################################
        # Several type-related functions aren't accessibly via IDAPython
        # so have to do things with ctypes
        idaname = "ida64" if idc.__EA64__ else "ida"
        if sys.platform == "win32":
            g_dll = ctypes.windll[idaname + ".wll"]
        elif sys.platform == "linux2":
            g_dll = ctypes.cdll["lib" + idaname + ".so"]
        elif sys.platform == "darwin":
            g_dll = ctypes.cdll["lib" + idaname + ".dylib"]

        ############################################################
        # Specifying function types for a few IDA SDK functions to keep the 
        # pointer-to-pointer args clear.
        get_named_type = g_dll.get_named_type
        get_named_type.argtypes = [
            ctypes.c_void_p,                                #const til_t *ti,
            ctypes.c_char_p,                                #const char *name,
            ctypes.c_int,                                   #int ntf_flags,
            ctypes.POINTER(ctypes.POINTER(ctypes.c_ubyte)), #const type_t **type=NULL,
            ctypes.POINTER(ctypes.POINTER(ctypes.c_ubyte)), #const p_list **fields=NULL,
            ctypes.POINTER(ctypes.POINTER(ctypes.c_ubyte)), #const char **cmt=NULL,
            ctypes.POINTER(ctypes.POINTER(ctypes.c_ubyte)), #const p_list **fieldcmts=NULL,
            ctypes.POINTER(ctypes.c_ulong),                 #sclass_t *sclass=NULL,
            ctypes.POINTER(ctypes.c_ulong),                 #uint32 *value=NULL);
        ]

        sym = idaapi.til_symbol_t()
        #dang - no predicate func support via idapython :(
        #idaapi.choose_named_type2(idaapi.cvar.idati, 'Choose type to apply', idaapi.NTF_SYMM, predFunc, sym)
        ret = idaapi.choose_named_type2(idaapi.cvar.idati, 'Choose type to apply', idaapi.NTF_SYMM, None, sym)
        if not ret:
            self.logger.debug('User canceled. Bailing out')
            return
        til = sym.til
        funcname = sym.name

        typ_type = ctypes.POINTER(ctypes.c_ubyte)()
        typ_fields = ctypes.POINTER(ctypes.c_ubyte)()
        typ_cmt = ctypes.POINTER(ctypes.c_ubyte)()
        typ_fieldcmts = ctypes.POINTER(ctypes.c_ubyte)()
        typ_sclass = ctypes.c_ulong()
        value = ctypes.c_ulong()
        ret = get_named_type(
                long(til.this),
                funcname, 
                idaapi.NTF_SYMM, 
                ctypes.byref(typ_type),
                ctypes.byref(typ_fields),
                ctypes.byref(typ_cmt),
                ctypes.byref(typ_fieldcmts),
                ctypes.byref(typ_sclass),
                ctypes.byref(value)
        )
        if ret == 0:
            self.logger.debug('Could not find %s', funcname)
            return
        ########################################
        # the following isn't needed, as moved to tinfo_t usage
        #if typ_type[0] != idaapi.BT_FUNC:
        #    #not positive that the first type value has to be BT_FUNC or not...
        #    # and whether it's important to only apply to funcs or not
        #    self.logger.debug('Found named type, but not a function: %s', funcname)
        #    return
        #type_arr = ctypes.create_string_buffer(0x400)
        #type_arr[0] = chr(idaapi.BT_PTR)
        #manualTypeCopy(type_arr, 1, len(type_arr), typ_type)
        #name_buffer = ctypes.create_string_buffer(0x400)
        #print_type_to_one_line(
        #    name_buffer, 
        #    len(name_buffer),
        #    long(til.this),
        #    typ_type,
        #    funcname,
        #    typ_cmt,
        #    typ_fields,
        #    typ_fieldcmts
        #)
        #self.logger.info('Found type: %s', name_buffer.value)
        ########################################
        #this works as well, but it's deprecated
        #self.logger.info('Trying to set type: %s', name_buffer.value)
        #ret = g_dll.apply_callee_type(
        #    ctypes.c_uint(here),
        #    type_arr,
        #    typ_fields
        #)
        tinfo = idaapi.tinfo_t()
        #self.logger.info('Trying to deserialize stuff')
        #self.logger.info('Type of til: %s', type(til))
        #self.logger.info('Type of typ_type: %s', type(typ_type))
        ret = g_dll.deserialize_tinfo(
            long(tinfo.this),
            long(til.this), 
            ctypes.byref(typ_type), 
            ctypes.byref(typ_fields),
            ctypes.byref(typ_fieldcmts)
        )
        return tinfo