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