Example #1
0
def extract_insn_number_features(f, bb, insn):
    """parse instruction number features

    args:
        f (IDA func_t)
        bb (IDA BasicBlock)
        insn (IDA insn_t)

    example:
        push    3136B0h         ; dwControlCode
    """
    if idaapi.is_ret_insn(insn):
        # skip things like:
        #   .text:0042250E retn 8
        return

    if capa.features.extractors.ida.helpers.is_sp_modified(insn):
        # skip things like:
        #   .text:00401145 add esp, 0Ch
        return

    for op in capa.features.extractors.ida.helpers.get_insn_ops(
            insn, target_ops=(idaapi.o_imm, idaapi.o_mem)):
        # skip things like:
        #   .text:00401100 shr eax, offset loc_C
        if capa.features.extractors.ida.helpers.is_op_offset(insn, op):
            continue

        if op.type == idaapi.o_imm:
            const = capa.features.extractors.ida.helpers.mask_op_val(op)
        else:
            const = op.addr

        yield Number(const), insn.ea
        yield Number(const, arch=get_arch(f.ctx)), insn.ea
Example #2
0
def extract_insn_number_features(f, bb, insn):
    """ parse instruction number features

        args:
            f (IDA func_t)
            bb (IDA BasicBlock)
            insn (IDA insn_t)

        example:
            push    3136B0h         ; dwControlCode
    """
    if idaapi.is_ret_insn(insn):
        # skip things like:
        #   .text:0042250E retn 8
        return

    if capa.features.extractors.ida.helpers.is_sp_modified(insn):
        # skip things like:
        #   .text:00401145 add esp, 0Ch
        return

    for op in capa.features.extractors.ida.helpers.get_insn_ops(
            insn, target_ops=(idaapi.o_imm, )):
        const = capa.features.extractors.ida.helpers.mask_op_val(op)
        if not idaapi.is_mapped(const):
            yield Number(const), insn.ea
            yield Number(const, arch=get_arch(f.ctx)), insn.ea
Example #3
0
    def is_ret(self):
        """
            Property indicating if this instruction is a ret.

            :return bool: True if this instruction is a ret, False otherwise.
        """
        return idaapi.is_ret_insn(self.ea)
Example #4
0
def decode_instruction(address):

    # DEBUG
    #print("Decoding instruction: 0x%x" % address)

    i = DecodeInstruction(address)

    mnemonic = i.get_canon_mnem()
    ops = []

    ignore_ops = False
    if isinstance(__builtin__.REGISTERS, RegistersX64):
        # uses floating point register "st" which has
        # overlapping index with "rax" and so on
        ignore_ops = mnemonic in [
            "fabs,", "fadd", "faddp", "fbld", "fbstp", "fchs", "fclex",
            "fcmov", "fcmovb", "fcmovbe", "fcmove", "fcmovnb", "fcmovnbe",
            "fcmovne", "fcmovnu", "fcmovu", "fcom", "fcomi", "fcomip", "fcomp",
            "fcompp", "fdecstp", "fdiv", "fdivp", "fdivr", "fdivrp", "ffree",
            "fiadd", "ficom", "ficomp", "fidiv", "fidivr", "fild", "fimul",
            "fincstp", "finit", "fist", "fistp", "fisub", "fisubr", "fld,"
            "fld1", "fldcw", "fldenv", "fldenvw", "fldl2e", "fldl2t", "fldlg2",
            "fldln2", "fldpi", "fldz", "fmul", "fmulp", "fnclex", "fndisi",
            "fneni", "fninit", "fnop", "fnsave", "fnsavew", "fnstcw",
            "fnstenv", "fnstenvw", "fnstsw", "fpatan", "fprem", "fptan",
            "frndint", "frstor", "frstorw", "fsave", "fsavew", "fscale",
            "fsqrt", "fst", "fstcw", "fstenv", "fstenvw", "fstp", "fstsw",
            "fsub", "fsubp", "fsubr", "fsubrp", "ftst", "fucomi", "fucomip",
            "fwait", "fxam", "fxch", "fxtract", "fyl2x", "fyl2xp1"
        ]

    if not ignore_ops:
        for o in range(6):
            if i[o].type == o_void:
                break

            # NOTE: for x64 we only consider 64 bit granularity at the moment.
            ida_operand_str = GetOpnd(address, o)
            # Some instructions like "stosq" do not have string operands
            # => ignore for now.
            if ida_operand_str == "":
                break

            # DEBUG
            #print(ida_operand_str)

            operand = instruction.Operand(get_operand_access_type(i, o),
                                          i[o],
                                          ida_operand_str=ida_operand_str,
                                          address=address,
                                          op_num=o)

            normalized = normalize_operand(operand)
            ops.extend(normalized)

    is_control_flow = is_ret_insn(address) or \
                      len(list(CodeRefsFrom(address, 1))) > 1

    return instruction.Instruction(address, mnemonic, ops, is_control_flow)
Example #5
0
File: insn.py Project: clayne/capa
def extract_insn_number_features(f, bb, insn):
    """parse instruction number features

    args:
        f (IDA func_t)
        bb (IDA BasicBlock)
        insn (IDA insn_t)

    example:
        push    3136B0h         ; dwControlCode
    """
    if idaapi.is_ret_insn(insn):
        # skip things like:
        #   .text:0042250E retn 8
        return

    if capa.features.extractors.ida.helpers.is_sp_modified(insn):
        # skip things like:
        #   .text:00401145 add esp, 0Ch
        return

    for i, op in enumerate(insn.ops):
        if op.type == idaapi.o_void:
            break
        if op.type not in (idaapi.o_imm, idaapi.o_mem):
            continue
        # skip things like:
        #   .text:00401100 shr eax, offset loc_C
        if capa.features.extractors.ida.helpers.is_op_offset(insn, op):
            continue

        if op.type == idaapi.o_imm:
            const = capa.features.extractors.ida.helpers.mask_op_val(op)
        else:
            const = op.addr

        yield Number(const), insn.ea
        yield OperandNumber(i, const), insn.ea

        if insn.itype == idaapi.NN_add and 0 < const < MAX_STRUCTURE_SIZE and op.type == idaapi.o_imm:
            # for pattern like:
            #
            #     add eax, 0x10
            #
            # assume 0x10 is also an offset (imagine eax is a pointer).
            yield Offset(const), insn.ea
            yield OperandOffset(i, const), insn.ea
Example #6
0
 def is_ret(self, ea):
     return idaapi.is_ret_insn(ea)
Example #7
0
 def is_ret(self):
     """Is the instruction a return instruction."""
     return idaapi.is_ret_insn(self._ea)
Example #8
0
 def is_ret(self):
     """Is the instruction a return instruction."""
     return idaapi.is_ret_insn(self._insn)
Example #9
0
def raw_main(p=True):
    global res
    # find .text section startEA first
    #text_startEA = None
    #for s in Segments():
    #    if SegName(s) == '.text':
    #        text_startEA = s
    #        break
    #if text_startEA is None:
    #    text_startEA = 0
    #f = idaapi.get_func(text_startEA)
    f = idaapi.get_next_func(0)
    fc = idaapi.FlowChart(f)

    while f:
        funcea = f.startEA
        fn = GetFunctionName(funcea)
        # if "Pl" in fn:
        #     funcaddr = f.startEA
        #     f = idaapi.get_next_func(funcaddr)
        #     continue

        q = idaapi.qflow_chart_t("The title", f, 0, 0, idaapi.FC_PREDS)
        res.append("##############################\n")
        for n in xrange(0, q.size()):
            b = q[n]
            if p:
                res.append("%x - %x [%d]:\n" % (b.startEA, b.endEA, n))

            for ns in xrange(0, q.nsucc(n)):
                res.append("SUCC:  %d->%d\n" % (n, q.succ(n, ns)))
            pred_set = set()
            for ns in xrange(0, q.npred(n)):
                res.append("PRED:  %d->%d\n" % (n, q.pred(n, ns)))
                pred_set.add(q.pred(n, ns))

            if q.nsucc(n) == 0:
                # this is a block with no successors
                last_insn = None
                for h in Heads(b.startEA, b.endEA):
                    last_insn = h
                if last_insn is None:
                    continue
                insn = DecodeInstruction(last_insn)
                if idaapi.is_ret_insn(insn):
                    continue
                disasm_str = GetDisasm(last_insn)
                if 'abort' in disasm_str or 'exit' in disasm_str or 'hlt' in disasm_str or '___stack_chk_fail' in disasm_str or '___assert_fail' in disasm_str:
                    continue
                if idaapi.is_indirect_jump_insn(insn):
                    # if this function ends with an indirect jump, it means ida failed to
                    # determine the successors. We treat all blocks in this function as possible successors
                    #with open('wierd_jump.txt', 'a') as tmp_f:
                    #    tmp_f.write(disasm_str + '\n')
                    for tn in xrange(0, q.size()):
                        res.append("SUCC:  %d->%d\n" % (n, tn))
                        if tn not in pred_set:
                            res.append("PRED:  %d->%d\n" % (tn, n))
                elif idaapi.is_call_insn(insn):
                    # if this function ends with a call (not something like abort), it is somewhat wierd.
                    # do not solve this temporarily
                    #with open('wierd_call.txt', 'a') as tmp_f:
                    #    tmp_f.write(disasm_str + '\n')
                    for tn in xrange(0, q.size()):
                        res.append("SUCC:  %d->%d\n" % (n, tn))
                        if tn not in pred_set:
                            res.append("PRED:  %d->%d\n" % (tn, n))

        funcaddr = f.startEA
        f = idaapi.get_next_func(funcaddr)
Example #10
0
def isReturn(ea):
    return idaapi.is_ret_insn(ea)
Example #11
0
 def is_ret(self, ea):
     return idaapi.is_ret_insn(ea)