def exec_instruction(hex_asm, init_values): """Symbolically execute an instruction""" print("Hex:", hex_asm) # Disassemble an instruction mn = mn_mep.dis(decode_hex(hex_asm), "b") print("Dis:", mn) loc_db = LocationDB() # Get the IR im = ir_mepb(loc_db) iir, eiir, = im.get_ir(mn) print("\nInternal representation:", iir) # Symbolic execution sb = SymbolicExecutionEngine(ir_a_mepb(loc_db), regs_init) # Assign register values before symbolic evaluation for reg_expr_id, reg_expr_value in init_values: sb.symbols[reg_expr_id] = reg_expr_value print("\nModified registers:", [reg for reg in sb.modified(mems=False)]) print("Modified memories:", [mem for mem in sb.modified()]) print("\nFinal registers:") sb.dump(mems=False) print("\nFinal mems:") sb.dump()
def ExecuteSymbolicSingleStep(addr, state=INIT_REG): size = idc.ItemSize(addr) code = idc.GetManyBytes(addr, size) loc_db = LocationDB() base = addr try: ins = mn_x86.dis(bin_stream_str(code, base_address=base), 64, base) except: return state.copy() ira = machine.ira(loc_db) ircfg = ira.new_ircfg() try: ira.add_instr_to_ircfg(ins, ircfg) sb = SymbolicExecutionEngine(ira, state) symbolic_pc = sb.run_at(ircfg, base) except: return state.copy() ret = state.copy() for key, value in sb.modified(): if isinstance(value, ExprOp) and value.op == "call_func_ret": value = ExprInt(0, 64) ret[key] = value return ret
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)
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)
def intra_block_flow_symb(ir_arch, _, flow_graph, irblock, in_nodes, out_nodes): symbols_init = ir_arch.arch.regs.regs_init.copy() sb = SymbolicExecutionEngine(ir_arch, symbols_init) sb.eval_updt_irblock(irblock) print('*' * 40) print(irblock) out = sb.modified(mems=False) current_nodes = {} # Gen mem arg to mem node links for dst, src in out: src = sb.eval_expr(dst) for n in [dst, src]: all_mems = set() all_mems.update(get_expr_mem(n)) for n in all_mems: node_n_w = get_node_name(irblock.loc_key, 0, n) if not n == src: continue o_r = n.ptr.get_r(mem_read=False, cst_read=True) for i, n_r in enumerate(o_r): if n_r in current_nodes: node_n_r = current_nodes[n_r] else: node_n_r = get_node_name(irblock.loc_key, i, n_r) if not n_r in in_nodes: in_nodes[n_r] = node_n_r flow_graph.add_uniq_edge(node_n_r, node_n_w) # Gen data flow links for dst in out: src = sb.eval_expr(dst) nodes_r = src.get_r(mem_read=False, cst_read=True) nodes_w = set([dst]) for n_r in nodes_r: if n_r in current_nodes: node_n_r = current_nodes[n_r] else: node_n_r = get_node_name(irblock.loc_key, 0, n_r) if not n_r in in_nodes: in_nodes[n_r] = node_n_r flow_graph.add_node(node_n_r) for n_w in nodes_w: node_n_w = get_node_name(irblock.loc_key, 1, n_w) out_nodes[n_w] = node_n_w flow_graph.add_node(node_n_w) flow_graph.add_uniq_edge(node_n_r, node_n_w)
def main(file_path: Path, start_addr: int, oracle_path: Path) -> None: # symbol table loc_db = LocationDB() # open the binary for analysis container = Container.from_stream(open(file_path, 'rb'), loc_db) # cpu abstraction machine = Machine(container.arch) # init disassemble engine mdis = machine.dis_engine(container.bin_stream, loc_db=loc_db) # initialize intermediate representation lifter = machine.lifter_model_call(mdis.loc_db) # disassemble the function at address asm_block = mdis.dis_block(start_addr) # lift to Miasm IR ira_cfg = lifter.new_ircfg() lifter.add_asmblock_to_ircfg(asm_block, ira_cfg) # init symbolic execution engine sb = SymbolicExecutionEngine(lifter) # symbolically execute basic block sb.run_block_at(ira_cfg, start_addr) # initialize simplifier simplifier = Simplifier(oracle_path) for k, v in sb.modified(): if v.is_int() or v.is_id() or v.is_loc(): continue print(f"before: {v}") simplified = simplifier.simplify(v) print(f"simplified: {simplified}") print("\n\n")
def symbolic_exec(): from miasm.ir.symbexec import SymbolicExecutionEngine from miasm.core.bin_stream_ida import bin_stream_ida from utils import guess_machine start, end = idc.read_selection_start(), idc.read_selection_end() loc_db = LocationDB() bs = bin_stream_ida() machine = guess_machine(addr=start) mdis = machine.dis_engine(bs, loc_db=loc_db) if start == idc.BADADDR and end == idc.BADADDR: start = idc.get_screen_ea() end = idc.next_head(start) # Get next instruction address mdis.dont_dis = [end] asmcfg = mdis.dis_multiblock(start) ira = machine.ira(loc_db=loc_db) ircfg = ira.new_ircfg_from_asmcfg(asmcfg) print("Run symbolic execution...") sb = SymbolicExecutionEngine(ira, machine.mn.regs.regs_init) sb.run_at(ircfg, start) modified = {} for dst, src in sb.modified(init_state=machine.mn.regs.regs_init): modified[dst] = src view = symbolicexec_t() all_views.append(view) if not view.Create( modified, machine, loc_db, "Symbolic Execution - 0x%x to 0x%x" % (start, idc.prev_head(end))): return view.Show()
def symbolic_exec(): from miasm.ir.symbexec import SymbolicExecutionEngine from miasm.core.bin_stream_ida import bin_stream_ida from utils import guess_machine start, end = idc.SelStart(), idc.SelEnd() bs = bin_stream_ida() machine = guess_machine(addr=start) mdis = machine.dis_engine(bs) if start == idc.BADADDR and end == idc.BADADDR: start = idc.ScreenEA() end = idc.next_head(start) # Get next instruction address mdis.dont_dis = [end] asmcfg = mdis.dis_multiblock(start) ira = machine.ira(loc_db=mdis.loc_db) ircfg = ira.new_ircfg_from_asmcfg(asmcfg) print("Run symbolic execution...") sb = SymbolicExecutionEngine(ira, machine.mn.regs.regs_init) sb.run_at(ircfg, start) modified = {} for dst, src in sb.modified(init_state=machine.mn.regs.regs_init): modified[dst] = src view = symbolicexec_t() all_views.append(view) if not view.Create(modified, machine, mdis.loc_db, "Symbolic Execution - 0x%x to 0x%x" % (start, idc.prev_head(end))): return view.Show()