def check(expr_in, expr_out): """Check that expr_in is always equals to expr_out""" print("Ensure %s = %s" % (expr_in, expr_out)) solver = z3.Solver() solver.add(trans.from_expr(expr_in) != trans.from_expr(expr_out)) result = solver.check() if result != z3.unsat: print("ERROR: a counter-example has been founded:") model = solver.model() print(model) print("Reinjecting in the simplifier:") to_rep = {} expressions = expr_in.get_r().union(expr_out.get_r()) for expr in expressions: value = model.eval(trans.from_expr(expr)) if hasattr(value, "as_long"): new_val = ExprInt(value.as_long(), expr.size) else: raise RuntimeError("Unable to reinject %r" % value) to_rep[expr] = new_val new_expr_in = expr_in.replace_expr(to_rep) new_expr_out = expr_out.replace_expr(to_rep) print("Check %s = %s" % (new_expr_in, new_expr_out)) simp_in = expr_simp_explicit(new_expr_in) simp_out = expr_simp_explicit(new_expr_out) print("[%s] %s = %s" % (simp_in == simp_out, simp_in, simp_out)) # Either the simplification does not stand, either the test is wrong raise RuntimeError("Bad simplification")
def sym(data, addr, status): cont = Container.from_string(data, loc_db=loc_db, addr=addr) mdis = machine.dis_engine(cont.bin_stream, loc_db=loc_db) asm_block = mdis.dis_block(addr) # Translate ASM -> IR ircfg = ira.new_ircfg() try: ira.add_asmblock_to_ircfg(asm_block, ircfg) except NotImplementedError: return None # Instantiate a Symbolic Execution engine with default value for registers regs_init = regs.regs_init sympool = copy.deepcopy(regs_init) sympool.update(status) symb = SymbolicExecutionEngine(ira, sympool) # Emulate one IR basic block ## Emulation of several basic blocks can be done through .emul_ir_blocks cur_addr = symb.run_at(ircfg, addr) IRDst = symb.symbols[ira.IRDst] expr = expr_simp_explicit(IRDst) #if isinstance(expr, ExprMem): # expr = expr.ptr return expr
def _follow_simp_expr(exprs): """Simplify expression so avoid tracking useless elements, as: XOR EAX, EAX """ follow = set() for expr in exprs: follow.add(expr_simp_explicit(expr)) return follow, set()
(ExprOp('+', a, a, a), a * i3), ((a << i1) - a, a), ((a << i1) - (a << i2), a * im2), ((a << i1) - a - a, i0), ((a << i2) - (a << i1) - (a << i1), i0), ((a << i2) - a * i3, a), (((a + b) * i3) - (a + b), (a + b) * i2), (((a + b) * i2) + a + b, (a + b) * i3), (((a + b) * i3) - a - b, (a + b) * i2), (((a + b) * i2) - a - b, a + b), (((a + b) * i2) - i2 * a - i2 * b, i0), ] for e_input, e_check in to_test: print("#" * 80) e_new = expr_simp_explicit(e_input) print("original: ", str(e_input), "new: ", str(e_new)) rez = e_new == e_check if not rez: raise ValueError( 'bug in expr_simp_explicit simp(%s) is %s and should be %s' % (e_input, e_new, e_check)) check(e_input, e_check) # Test high level op to_test = [ (ExprOp(TOK_EQUAL, a + i2, i1), ExprOp(TOK_EQUAL, a + i1, i0)), (ExprOp(TOK_INF_SIGNED, a + i2, i1), ExprOp(TOK_INF_SIGNED, a + i2, i1)), (ExprOp(TOK_INF_UNSIGNED, a + i2, i1), ExprOp(TOK_INF_UNSIGNED, a + i2, i1)), (ExprOp(TOK_EQUAL, ExprCompose(a8, ExprInt(0, 24)),