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
125
126
127
128
129
130
131
|
from __future__ import print_function
from future.utils import viewitems
from miasm.ir.symbexec import SymbolicExecutionEngine, StateEngine
from miasm.expression.simplifications import expr_simp
from miasm.expression.expression import ExprId, ExprMem
class SymbolicStateCTypes(StateEngine):
"""Store C types of symbols"""
def __init__(self, symbols):
tmp = {}
for expr, types in viewitems(symbols):
tmp[expr] = frozenset(types)
self._symbols = frozenset(viewitems(tmp))
def __hash__(self):
return hash((self.__class__, self._symbols))
def __str__(self):
out = []
for dst, src in sorted(self._symbols):
out.append("%s = %s" % (dst, src))
return "\n".join(out)
def __eq__(self, other):
if self is other:
return True
if self.__class__ != other.__class__:
return False
return self.symbols == other.symbols
def __ne__(self, other):
return not self.__eq__(other)
def __iter__(self):
for dst, src in self._symbols:
yield dst, src
def merge(self, other):
"""Merge two symbolic states
The resulting types are the union of types of both states.
@other: second symbolic state
"""
symb_a = self.symbols
symb_b = other.symbols
symbols = {}
for expr in set(symb_a).union(set(symb_b)):
ctypes = symb_a.get(expr, set()).union(symb_b.get(expr, set()))
if ctypes:
symbols[expr] = ctypes
return self.__class__(symbols)
@property
def symbols(self):
"""Return the dictionary of known symbols'types"""
return dict(self._symbols)
class SymbExecCType(SymbolicExecutionEngine):
"""Engine of C types propagation
WARNING: avoid memory aliases here!
"""
StateEngine = SymbolicStateCTypes
OBJC_INTERNAL = "___OBJC___"
def __init__(self, lifter,
symbols,
chandler,
sb_expr_simp=expr_simp):
self.chandler = chandler
super(SymbExecCType, self).__init__(lifter,
{},
sb_expr_simp)
self.symbols = dict(symbols)
def get_state(self):
"""Return the current state of the SymbolicEngine"""
return self.StateEngine(self.symbols)
def eval_assignblk(self, assignblk):
"""
Evaluate AssignBlock on the current state
@assignblk: AssignBlock instance
"""
pool_out = {}
for dst, src in viewitems(assignblk):
objcs = self.chandler.expr_to_types(src, self.symbols)
if isinstance(dst, ExprMem):
continue
elif isinstance(dst, ExprId):
pool_out[dst] = frozenset(objcs)
else:
raise ValueError("Unsupported assignment", str(dst))
return pool_out
def eval_expr(self, expr, eval_cache=None):
return frozenset(self.chandler.expr_to_types(expr, self.symbols))
def apply_change(self, dst, src):
if src is None:
if dst in self.symbols:
del self.symbols[dst]
else:
self.symbols[dst] = src
def del_mem_above_stack(self, stack_ptr):
"""No stack deletion"""
return
def dump_id(self):
"""
Dump modififed registers symbols only
"""
for expr, expr_types in sorted(viewitems(self.symbols)):
if not expr.is_mem():
print(expr)
for expr_type in expr_types:
print('\t', expr_type)
def dump_mem(self):
"""
Dump modififed memory symbols
"""
for expr, value in sorted(viewitems(self.symbols)):
if expr.is_mem():
print(expr, value)
|