Miasm2
 All Classes Namespaces Files Functions Variables Typedefs Properties Macros
simplifications.py
Go to the documentation of this file.
1 # #
2 # Simplification methods library #
3 # #
4 
5 from miasm2.expression import simplifications_common
6 from miasm2.expression import simplifications_cond
7 from miasm2.expression.expression_helper import fast_unify
8 import miasm2.expression.expression as m2_expr
9 
10 # Expression Simplifier
11 # ---------------------
12 
13 
15 
16  """Wrapper on expression simplification passes.
17 
18  Instance handle passes lists.
19 
20  Available passes lists are:
21  - commons: common passes such as constant folding
22  - heavy : rare passes (for instance, in case of obfuscation)
23  """
24 
25  # Common passes
26  PASS_COMMONS = {
27  m2_expr.ExprOp: [simplifications_common.simp_cst_propagation,
28  simplifications_common.simp_cond_op_int,
29  simplifications_common.simp_cond_factor],
30  m2_expr.ExprSlice: [simplifications_common.simp_slice],
31  m2_expr.ExprCompose: [simplifications_common.simp_compose],
32  m2_expr.ExprCond: [simplifications_common.simp_cond],
33  }
34 
35  # Heavy passes
36  PASS_HEAVY = {}
37 
38  # Cond passes
39  PASS_COND = {m2_expr.ExprSlice: [simplifications_cond.expr_simp_inf_signed,
40  simplifications_cond.expr_simp_inf_unsigned_inversed],
41  m2_expr.ExprOp: [simplifications_cond.exec_inf_unsigned,
42  simplifications_cond.exec_inf_signed,
43  simplifications_cond.expr_simp_inverse,
44  simplifications_cond.exec_equal],
45  m2_expr.ExprCond: [simplifications_cond.expr_simp_equal]
46  }
47 
48 
49  def __init__(self):
50  self.expr_simp_cb = {}
51 
52  def enable_passes(self, passes):
53  """Add passes from @passes
54  @passes: dict(Expr class : list(callback))
55 
56  Callback signature: Expr callback(ExpressionSimplifier, Expr)
57  """
58 
59  for k, v in passes.items():
60  self.expr_simp_cb[k] = fast_unify(self.expr_simp_cb.get(k, []) + v)
61 
62  def apply_simp(self, expression):
63  """Apply enabled simplifications on expression
64  @expression: Expr instance
65  Return an Expr instance"""
66 
67  cls = expression.__class__
68  for simp_func in self.expr_simp_cb.get(cls, []):
69  # Apply simplifications
70  expression = simp_func(self, expression)
71 
72  # If class changes, stop to prevent wrong simplifications
73  if expression.__class__ is not cls:
74  break
75 
76  return expression
77 
78  def expr_simp(self, expression):
79  """Apply enabled simplifications on expression and find a stable state
80  @expression: Expr instance
81  Return an Expr instance"""
82 
83  if expression.is_simp:
84  return expression
85 
86  # Find a stable state
87  while True:
88  # Canonize and simplify
89  e_new = self.apply_simp(expression.canonize())
90  if e_new == expression:
91  break
92 
93  # Launch recursivity
94  expression = self.expr_simp_wrapper(e_new)
95  expression.is_simp = True
96 
97  # Mark expression as simplified
98  e_new.is_simp = True
99  return e_new
100 
101  def expr_simp_wrapper(self, expression, callback=None):
102  """Apply enabled simplifications on expression
103  @expression: Expr instance
104  @manual_callback: If set, call this function instead of normal one
105  Return an Expr instance"""
106 
107  if expression.is_simp:
108  return expression
109 
110  if callback is None:
111  callback = self.expr_simp
112 
113  return expression.visit(callback, lambda e: not(e.is_simp))
114 
115  def __call__(self, expression, callback=None):
116  "Wrapper on expr_simp_wrapper"
117  return self.expr_simp_wrapper(expression, callback)
118 
119 
120 # Public ExprSimplificationPass instance with commons passes
121 expr_simp = ExpressionSimplifier()
122 expr_simp.enable_passes(ExpressionSimplifier.PASS_COMMONS)