# Match the expected form ## isinstance(expr, m2_expr.ExprOp) is not needed: simplifications are ## attached to expression types if expr.op == "+" and \ len(expr.args) == 3 and \ expr.args.count(expr.args[0]) == len(expr.args): # Effective simplification return m2_expr.ExprOp("*", expr.args[0], m2_expr.ExprInt(3, expr.args[0].size)) else: # Do not simplify return expr a = m2_expr.ExprId('a') base_expr = a + a + a print "Without adding the simplification:" print "\t%s = %s" % (base_expr, expr_simp(base_expr)) # Enable pass expr_simp.enable_passes({m2_expr.ExprOp: [simp_add_mul]}) print "After adding the simplification:" print "\t%s = %s" % (base_expr, expr_simp(base_expr)) # Automatic fail assert (expr_simp(base_expr) == m2_expr.ExprOp("*", a, m2_expr.ExprInt(3, a.size)))
(ExprOp_inf_unsigned(a, b) ^ (a ^ b).msb(), ExprOp_inf_signed(a, b)), (ExprOp_inf_signed(a, b) ^ (a ^ b).msb(), ExprOp_inf_unsigned(a, b)), (ExprOp_equal(ExprInt(12, 32), ExprInt(10, 32)), ExprInt(0, 1)), (ExprOp_equal(ExprInt(12, 32), ExprInt(12, 32)), ExprInt(1, 1)), (ExprOp_equal(ExprInt(12, 32), ExprInt(-12, 32)), ExprInt(0, 1)), (ExprCond(a - b, ExprInt(0, 1), ExprInt(1, 1)), ExprOp_equal(a, b)), (ExprCond(a + b, ExprInt(0, 1), ExprInt(1, 1)), ExprOp_equal(a, -b)), (ExprOp_inf_signed(ExprInt(-2, 32), ExprInt(3, 32)), ExprInt(1, 1)), (ExprOp_inf_signed(ExprInt(3, 32), ExprInt(-3, 32)), ExprInt(0, 1)), (ExprOp_inf_signed(ExprInt(2, 32), ExprInt(3, 32)), ExprInt(1, 1)), (ExprOp_inf_signed(ExprInt(-3, 32), ExprInt(-2, 32)), ExprInt(1, 1)), (ExprOp_inf_signed(ExprInt(0, 32), ExprInt(2, 32)), ExprInt(1, 1)), (ExprOp_inf_signed(ExprInt(-3, 32), ExprInt(0, 32)), ExprInt(1, 1)), ] expr_simp.enable_passes(ExpressionSimplifier.PASS_COND) for e_input, e_check in to_test: print "#" * 80 e_check = expr_simp(e_check) e_new = expr_simp(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 simp(%s) is %s and should be %s' % (e_input, e_new, e_check) ) if args.z3:
(ExprOp_inf_signed(a, b) ^ (a ^ b).msb(), ExprOp_inf_unsigned(a, b)), (ExprOp_equal(ExprInt(12, 32), ExprInt(10, 32)), ExprInt(0, 1)), (ExprOp_equal(ExprInt(12, 32), ExprInt(12, 32)), ExprInt(1, 1)), (ExprOp_equal(ExprInt(12, 32), ExprInt(-12, 32)), ExprInt(0, 1)), (ExprCond(a - b, ExprInt(0, 1), ExprInt(1, 1)), ExprOp_equal(a, b)), (ExprCond(a + b, ExprInt(0, 1), ExprInt(1, 1)), ExprOp_equal(a, -b)), (ExprOp_inf_signed(ExprInt(-2, 32), ExprInt(3, 32)), ExprInt(1, 1)), (ExprOp_inf_signed(ExprInt(3, 32), ExprInt(-3, 32)), ExprInt(0, 1)), (ExprOp_inf_signed(ExprInt(2, 32), ExprInt(3, 32)), ExprInt(1, 1)), (ExprOp_inf_signed(ExprInt(-3, 32), ExprInt(-2, 32)), ExprInt(1, 1)), (ExprOp_inf_signed(ExprInt(0, 32), ExprInt(2, 32)), ExprInt(1, 1)), (ExprOp_inf_signed(ExprInt(-3, 32), ExprInt(0, 32)), ExprInt(1, 1)), ] expr_simp_cond = ExpressionSimplifier() expr_simp.enable_passes(ExpressionSimplifier.PASS_COND) for e, e_check in to_test[:]: # print "#" * 80 e_check = expr_simp(e_check) # print str(e), str(e_check) e_new = expr_simp(e) print "original: ", str(e), "new: ", str(e_new) rez = e_new == e_check if not rez: raise ValueError( 'bug in expr_simp simp(%s) is %s and should be %s' % (e, e_new, e_check))
# add stack alignment simpl def simp_stack_align(expr_simp, expr): if not expr.is_op("&"): return expr if len(expr.args) != 2: return expr if not expr.args[1].is_int(0xFFFFFFF0): return expr if expr.args[0] != ir_arch.arch.regs.ESP_init: return expr return expr.args[0] expr_simp.enable_passes({m2_expr.ExprOp: [simp_stack_align]}) # Init machine = guess_machine() mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira bs = bin_stream_ida() mdis = dis_engine(bs, dont_dis_nulstart_bloc=True) ir_arch = ira(mdis.symbol_pool) # Get the current function func = idaapi.get_func(ScreenEA()) addr = func.startEA blocks = mdis.dis_multibloc(addr) # Generate IR for block in blocks:
"Naive Simplification: a + a + a == a * 3" # Match the expected form ## isinstance(expr, m2_expr.ExprOp) is not needed: simplifications are ## attached to expression types if expr.op == "+" and \ len(expr.args) == 3 and \ expr.args.count(expr.args[0]) == len(expr.args): # Effective simplification return m2_expr.ExprOp("*", expr.args[0], m2_expr.ExprInt(3, expr.args[0].size)) else: # Do not simplify return expr a = m2_expr.ExprId('a') base_expr = a + a + a print "Without adding the simplification:" print "\t%s = %s" % (base_expr, expr_simp(base_expr)) # Enable pass expr_simp.enable_passes({m2_expr.ExprOp: [simp_add_mul]}) print "After adding the simplification:" print "\t%s = %s" % (base_expr, expr_simp(base_expr)) # Automatic fail assert(expr_simp(base_expr) == m2_expr.ExprOp("*", a, m2_expr.ExprInt(3, a.size)))