Exemple #1
0
def exec_instruction(mn_str, init_values, results, index=0, offset=0):
    """Symbolically execute an instruction and check the expected results."""

    # Assemble and disassemble the instruction
    instr = mn_mep.fromstring(mn_str, "b")
    instr.mode = "b"
    mn_bin = mn_mep.asm(instr)[index]
    try:
        instr = mn_mep.dis(mn_bin, "b")
    except Disasm_Exception:
        assert (False)  # miasm don't know what to do

    # Specify the instruction offset and compute the destination label
    instr.offset = offset
    loc_db = LocationDB()
    if instr.dstflow():
        instr.dstflow2label(loc_db)

    # Get the IR
    im = Lifter_MEPb(loc_db)
    iir, eiir = im.get_ir(instr)

    # Filter out IRDst
    iir = [
        ir for ir in iir
        if not (isinstance(ir, ExprAssign) and isinstance(ir.dst, ExprId)
                and ir.dst.name == "IRDst")
    ]

    # Prepare symbolic execution
    sb = SymbolicExecutionEngine(LifterModelCallMepb(loc_db), regs_init)

    # Assign int values before symbolic evaluation
    for expr_id, expr_value in init_values:
        sb.symbols[expr_id] = expr_value

    # Execute the IR
    ab = AssignBlock(iir)
    sb.eval_updt_assignblk(ab)

    # Check if expected expr_id were modified
    matched_results = 0
    for expr_id, expr_value in results:

        result = sb.eval_expr(expr_id)
        if isinstance(result, ExprLoc):
            addr = loc_db.get_location_offset(result.loc_key)
            if expr_value.arg == addr:
                matched_results += 1
                continue
        elif result == expr_value:
            matched_results += 1
            continue

    # Ensure that all expected results were verified
    if len(results) is not matched_results:
        print("Expected:", results)
        print("Modified:", [r for r in sb.modified(mems=False)])
        assert (False)
Exemple #2
0
def exec_instruction(mn_str, init_values, results, index=0, offset=0):
    """Symbolically execute an instruction and check the expected results."""

    # Assemble and disassemble the instruction
    instr = mn_mep.fromstring(mn_str, "b")
    instr.mode = "b"
    mn_bin = mn_mep.asm(instr)[index]
    try:
        instr = mn_mep.dis(mn_bin, "b")
    except Disasm_Exception:
        assert(False)  # miasm don't know what to do

    # Specify the instruction offset and compute the destination label
    instr.offset = offset
    loc_db = LocationDB()
    if instr.dstflow():
        instr.dstflow2label(loc_db)

    # Get the IR
    im = ir_mepb(loc_db)
    iir, eiir = im.get_ir(instr)

    # Filter out IRDst
    iir = [ir for ir in iir if not (isinstance(ir, ExprAssign) and
                                    isinstance(ir.dst, ExprId) and
                                    ir.dst.name == "IRDst")]

    # Prepare symbolic execution
    sb = SymbolicExecutionEngine(ir_a_mepb(loc_db), regs_init)

    # Assign int values before symbolic evaluation
    for expr_id, expr_value in init_values:
        sb.symbols[expr_id] = expr_value

    # Execute the IR
    ab = AssignBlock(iir)
    sb.eval_updt_assignblk(ab)

    # Check if expected expr_id were modified
    matched_results = 0
    for expr_id, expr_value in results:

        result = sb.eval_expr(expr_id)
        if isinstance(result, ExprLoc):
            addr = loc_db.get_location_offset(result.loc_key)
            if expr_value.arg == addr:
                matched_results += 1
                continue
        elif result == expr_value:
            matched_results += 1
            continue

    # Ensure that all expected results were verified
    if len(results) is not matched_results:
        print("Expected:", results)
        print("Modified:", [r for r in sb.modified(mems=False)])
        assert(False)
Exemple #3
0
    def _recognize(self, max_loop_num):
        symb_engine = SymbolicExecutionEngine(self.ir_arch, regs.regs_init)
        todo = [(LocKey(0), symb_engine.get_state())]
        done_loc = set()
        if not max_loop_num:
            max_loop_num = float('inf')
        found_loops_num = 0
        while todo:
            loc_key, symb_state = todo.pop()
            if loc_key in done_loc or loc_key not in self.ircfg.blocks:
                continue
            done_loc.add(loc_key)
            ir_block = self.ircfg.blocks[loc_key]
            symb_engine.set_state(symb_state)
            for ind, assignblk in enumerate(ir_block.assignblks):
                for dst, src in assignblk.items():
                    if max_loop_num < found_loops_num:
                        return
                    if src.is_int() and int(src) in self.func_addresses:
                        assignblk_node = AssignblkNode(ir_block.loc_key, ind,
                                                       dst)
                        # no uses
                        if assignblk_node not in self.analyses.defuse_edges or not \
                                self.analyses.defuse_edges[assignblk_node]:
                            # possible virtual table initialization
                            self.possible_merge_funcs.add(
                                (int(src), frozenset(), loc_key))
                    elif src.is_op("call_func_stack"):
                        self._process_call(src, dst, symb_engine, assignblk,
                                           loc_key)
                    elif (expr_simp(src).is_int() and not is_bad_expr(dst)) \
                            or (ir_block.loc_key == LocKey(0) and dst == src and
                                (not self._merging_var_candidates or dst in self._merging_var_candidates)):
                        if self._process_assignment(ir_block, ind, dst):
                            self._merging_var_candidates = None
                            found_loops_num += 1
                symb_engine.eval_updt_assignblk(assignblk)

            for succ in self.ircfg.successors(loc_key):
                todo.append((succ, symb_engine.get_state()))