angr 9.2.131__py3-none-manylinux2014_x86_64.whl → 9.2.132__py3-none-manylinux2014_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of angr might be problematic. Click here for more details.
- angr/__init__.py +1 -1
- angr/analyses/analysis.py +6 -2
- angr/analyses/cfg/cfg_emulated.py +5 -5
- angr/analyses/cfg/cfg_fast.py +2 -2
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +139 -94
- angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +1 -1
- angr/analyses/ddg.py +14 -11
- angr/analyses/decompiler/ail_simplifier.py +3 -2
- angr/analyses/decompiler/block_simplifier.py +10 -21
- angr/analyses/decompiler/clinic.py +108 -34
- angr/analyses/decompiler/condition_processor.py +12 -10
- angr/analyses/decompiler/dephication/graph_rewriting.py +1 -1
- angr/analyses/decompiler/dephication/rewriting_engine.py +169 -45
- angr/analyses/decompiler/dephication/seqnode_dephication.py +5 -4
- angr/analyses/decompiler/optimization_passes/const_derefs.py +1 -0
- angr/analyses/decompiler/optimization_passes/div_simplifier.py +41 -16
- angr/analyses/decompiler/optimization_passes/engine_base.py +261 -83
- angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +173 -35
- angr/analyses/decompiler/optimization_passes/mod_simplifier.py +5 -2
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +39 -19
- angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +2 -0
- angr/analyses/decompiler/ssailification/rewriting.py +1 -2
- angr/analyses/decompiler/ssailification/rewriting_engine.py +138 -55
- angr/analyses/decompiler/ssailification/ssailification.py +2 -1
- angr/analyses/decompiler/ssailification/traversal.py +4 -6
- angr/analyses/decompiler/ssailification/traversal_engine.py +125 -42
- angr/analyses/decompiler/structured_codegen/c.py +5 -3
- angr/analyses/decompiler/structuring/phoenix.py +26 -9
- angr/analyses/decompiler/structuring/structurer_nodes.py +9 -0
- angr/analyses/deobfuscator/irsb_reg_collector.py +29 -60
- angr/analyses/deobfuscator/string_obf_finder.py +2 -2
- angr/analyses/init_finder.py +47 -22
- angr/analyses/propagator/engine_base.py +21 -14
- angr/analyses/propagator/engine_vex.py +149 -179
- angr/analyses/propagator/propagator.py +10 -28
- angr/analyses/propagator/top_checker_mixin.py +211 -5
- angr/analyses/propagator/vex_vars.py +1 -1
- angr/analyses/reaching_definitions/dep_graph.py +1 -1
- angr/analyses/reaching_definitions/engine_ail.py +304 -329
- angr/analyses/reaching_definitions/engine_vex.py +243 -229
- angr/analyses/reaching_definitions/function_handler.py +3 -3
- angr/analyses/reaching_definitions/rd_state.py +37 -32
- angr/analyses/s_propagator.py +18 -3
- angr/analyses/s_reaching_definitions/s_reaching_definitions.py +9 -5
- angr/analyses/typehoon/simple_solver.py +7 -5
- angr/analyses/typehoon/translator.py +8 -0
- angr/analyses/typehoon/typeconsts.py +10 -2
- angr/analyses/typehoon/typevars.py +9 -7
- angr/analyses/variable_recovery/engine_ail.py +299 -259
- angr/analyses/variable_recovery/engine_base.py +135 -117
- angr/analyses/variable_recovery/engine_vex.py +175 -185
- angr/analyses/variable_recovery/irsb_scanner.py +49 -38
- angr/analyses/variable_recovery/variable_recovery.py +28 -5
- angr/analyses/variable_recovery/variable_recovery_base.py +32 -33
- angr/analyses/variable_recovery/variable_recovery_fast.py +2 -2
- angr/analyses/xrefs.py +46 -19
- angr/annocfg.py +19 -14
- angr/block.py +4 -9
- angr/calling_conventions.py +1 -1
- angr/engines/engine.py +30 -14
- angr/engines/light/__init__.py +11 -3
- angr/engines/light/engine.py +1003 -1185
- angr/engines/pcode/cc.py +2 -0
- angr/engines/successors.py +13 -9
- angr/engines/vex/claripy/datalayer.py +1 -1
- angr/engines/vex/claripy/irop.py +1 -1
- angr/engines/vex/light/slicing.py +2 -2
- angr/exploration_techniques/__init__.py +1 -124
- angr/exploration_techniques/base.py +126 -0
- angr/exploration_techniques/bucketizer.py +1 -1
- angr/exploration_techniques/dfs.py +3 -1
- angr/exploration_techniques/director.py +2 -3
- angr/exploration_techniques/driller_core.py +1 -1
- angr/exploration_techniques/explorer.py +4 -2
- angr/exploration_techniques/lengthlimiter.py +2 -1
- angr/exploration_techniques/local_loop_seer.py +2 -1
- angr/exploration_techniques/loop_seer.py +5 -5
- angr/exploration_techniques/manual_mergepoint.py +2 -1
- angr/exploration_techniques/memory_watcher.py +3 -1
- angr/exploration_techniques/oppologist.py +4 -5
- angr/exploration_techniques/slicecutor.py +4 -2
- angr/exploration_techniques/spiller.py +1 -1
- angr/exploration_techniques/stochastic.py +2 -1
- angr/exploration_techniques/stub_stasher.py +2 -1
- angr/exploration_techniques/suggestions.py +3 -1
- angr/exploration_techniques/symbion.py +3 -1
- angr/exploration_techniques/tech_builder.py +2 -1
- angr/exploration_techniques/threading.py +4 -7
- angr/exploration_techniques/timeout.py +4 -2
- angr/exploration_techniques/tracer.py +4 -3
- angr/exploration_techniques/unique.py +3 -2
- angr/exploration_techniques/veritesting.py +1 -1
- angr/knowledge_plugins/key_definitions/atoms.py +2 -2
- angr/knowledge_plugins/key_definitions/live_definitions.py +16 -13
- angr/knowledge_plugins/propagations/states.py +13 -8
- angr/knowledge_plugins/variables/variable_manager.py +23 -9
- angr/sim_manager.py +1 -3
- angr/sim_state.py +39 -41
- angr/sim_type.py +5 -0
- angr/sim_variable.py +29 -28
- angr/utils/bits.py +12 -0
- angr/utils/orderedset.py +4 -1
- angr/utils/ssa/__init__.py +21 -3
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/METADATA +6 -6
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/RECORD +109 -110
- angr/analyses/propagator/engine_ail.py +0 -1562
- angr/storage/memory_mixins/__init__.pyi +0 -48
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/LICENSE +0 -0
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/WHEEL +0 -0
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/entry_points.txt +0 -0
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/top_level.txt +0 -0
|
@@ -5,29 +5,25 @@ import logging
|
|
|
5
5
|
from ailment.block import Block
|
|
6
6
|
from ailment.statement import Statement, Assignment, Store, Call, Return, ConditionalJump, DirtyStatement
|
|
7
7
|
from ailment.expression import (
|
|
8
|
-
|
|
8
|
+
Expression,
|
|
9
9
|
VirtualVariable,
|
|
10
10
|
Load,
|
|
11
|
-
Const,
|
|
12
11
|
BinaryOp,
|
|
12
|
+
UnaryOp,
|
|
13
13
|
Phi,
|
|
14
14
|
Convert,
|
|
15
|
-
StackBaseOffset,
|
|
16
15
|
ITE,
|
|
17
16
|
VEXCCallExpression,
|
|
18
17
|
DirtyExpression,
|
|
19
18
|
)
|
|
20
19
|
|
|
21
|
-
from angr.engines.light import
|
|
20
|
+
from angr.engines.light import SimEngineNostmtAIL
|
|
22
21
|
|
|
23
22
|
|
|
24
23
|
_l = logging.getLogger(__name__)
|
|
25
24
|
|
|
26
25
|
|
|
27
|
-
class SimEngineDephiRewriting(
|
|
28
|
-
SimEngineLightAILMixin,
|
|
29
|
-
SimEngineLight,
|
|
30
|
-
):
|
|
26
|
+
class SimEngineDephiRewriting(SimEngineNostmtAIL[None, Expression | None, Statement | tuple[Statement, ...], None]):
|
|
31
27
|
"""
|
|
32
28
|
This engine rewrites every block to insert phi variables and replaces every used variable with their versioned
|
|
33
29
|
copies at each use location.
|
|
@@ -37,15 +33,22 @@ class SimEngineDephiRewriting(
|
|
|
37
33
|
|
|
38
34
|
def __init__(
|
|
39
35
|
self,
|
|
40
|
-
|
|
36
|
+
project,
|
|
41
37
|
vvar_to_vvar: dict[int, int],
|
|
42
38
|
):
|
|
43
|
-
super().__init__()
|
|
39
|
+
super().__init__(project)
|
|
44
40
|
|
|
45
|
-
self.arch = arch
|
|
46
41
|
self.vvar_to_vvar = vvar_to_vvar
|
|
47
42
|
self.out_block = None
|
|
48
43
|
|
|
44
|
+
self._stmt_handlers["IncompleteSwitchCaseHeadStatement"] = self._handle_stmt_IncompleteSwitchCaseHeadStatement
|
|
45
|
+
|
|
46
|
+
def _top(self, bits):
|
|
47
|
+
assert False, "Unreachable"
|
|
48
|
+
|
|
49
|
+
def _is_top(self, expr):
|
|
50
|
+
return False
|
|
51
|
+
|
|
49
52
|
def append_statement(self, stmt: Statement) -> None:
|
|
50
53
|
if self.out_block is None:
|
|
51
54
|
self.out_block = Block(self.block.addr, self.block.original_size, statements=[], idx=self.block.idx)
|
|
@@ -55,18 +58,19 @@ class SimEngineDephiRewriting(
|
|
|
55
58
|
# Handlers
|
|
56
59
|
#
|
|
57
60
|
|
|
58
|
-
def
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
def _process_block_end(self, block, stmt_data, whitelist):
|
|
62
|
+
assert whitelist is None
|
|
63
|
+
for stmt_idx, new_stmt in enumerate(stmt_data):
|
|
64
|
+
if new_stmt is not None:
|
|
65
|
+
if isinstance(new_stmt, tuple):
|
|
66
|
+
for stmt_ in new_stmt:
|
|
67
|
+
self.append_statement(stmt_)
|
|
68
|
+
else:
|
|
69
|
+
self.append_statement(new_stmt)
|
|
64
70
|
else:
|
|
65
|
-
self.append_statement(
|
|
66
|
-
else:
|
|
67
|
-
self.append_statement(stmt)
|
|
71
|
+
self.append_statement(block.statements[stmt_idx])
|
|
68
72
|
|
|
69
|
-
def
|
|
73
|
+
def _handle_stmt_Assignment(self, stmt):
|
|
70
74
|
new_src = self._expr(stmt.src)
|
|
71
75
|
new_dst = None
|
|
72
76
|
|
|
@@ -92,7 +96,7 @@ class SimEngineDephiRewriting(
|
|
|
92
96
|
)
|
|
93
97
|
return None
|
|
94
98
|
|
|
95
|
-
def
|
|
99
|
+
def _handle_stmt_Store(self, stmt):
|
|
96
100
|
new_addr = self._expr(stmt.addr)
|
|
97
101
|
new_data = self._expr(stmt.data)
|
|
98
102
|
|
|
@@ -110,7 +114,7 @@ class SimEngineDephiRewriting(
|
|
|
110
114
|
|
|
111
115
|
return None
|
|
112
116
|
|
|
113
|
-
def
|
|
117
|
+
def _handle_stmt_ConditionalJump(self, stmt):
|
|
114
118
|
new_cond = self._expr(stmt.condition)
|
|
115
119
|
new_true_target = self._expr(stmt.true_target) if stmt.true_target is not None else None
|
|
116
120
|
new_false_target = self._expr(stmt.false_target) if stmt.false_target is not None else None
|
|
@@ -127,7 +131,7 @@ class SimEngineDephiRewriting(
|
|
|
127
131
|
)
|
|
128
132
|
return None
|
|
129
133
|
|
|
130
|
-
def
|
|
134
|
+
def _handle_stmt_Call(self, stmt):
|
|
131
135
|
new_target = self._expr(stmt.target) if stmt.target is not None and not isinstance(stmt.target, str) else None
|
|
132
136
|
new_ret_expr = self._expr(stmt.ret_expr) if stmt.ret_expr is not None else None
|
|
133
137
|
new_fp_ret_expr = self._expr(stmt.fp_ret_expr) if stmt.fp_ret_expr is not None else None
|
|
@@ -146,24 +150,19 @@ class SimEngineDephiRewriting(
|
|
|
146
150
|
)
|
|
147
151
|
return None
|
|
148
152
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
def _handle_DirtyStatement(self, stmt: DirtyStatement) -> DirtyStatement | None:
|
|
153
|
+
def _handle_stmt_DirtyStatement(self, stmt: DirtyStatement) -> DirtyStatement | None:
|
|
152
154
|
dirty = self._expr(stmt.dirty)
|
|
153
155
|
if dirty is None or dirty is stmt.dirty:
|
|
154
156
|
return None
|
|
155
157
|
return DirtyStatement(stmt.idx, dirty, **stmt.tags)
|
|
156
158
|
|
|
157
|
-
def
|
|
158
|
-
return None
|
|
159
|
-
|
|
160
|
-
def _handle_Load(self, expr: Load) -> Load | None:
|
|
159
|
+
def _handle_expr_Load(self, expr):
|
|
161
160
|
new_addr = self._expr(expr.addr)
|
|
162
161
|
if new_addr is not None:
|
|
163
162
|
return Load(expr.idx, new_addr, expr.size, expr.endness, guard=expr.guard, alt=expr.alt, **expr.tags)
|
|
164
163
|
return None
|
|
165
164
|
|
|
166
|
-
def
|
|
165
|
+
def _handle_expr_Convert(self, expr):
|
|
167
166
|
new_operand = self._expr(expr.operand)
|
|
168
167
|
if new_operand is not None:
|
|
169
168
|
return Convert(
|
|
@@ -179,13 +178,13 @@ class SimEngineDephiRewriting(
|
|
|
179
178
|
)
|
|
180
179
|
return None
|
|
181
180
|
|
|
182
|
-
def
|
|
181
|
+
def _handle_expr_Const(self, expr):
|
|
183
182
|
return None
|
|
184
183
|
|
|
185
|
-
def
|
|
184
|
+
def _handle_expr_Phi(self, expr: Phi) -> None:
|
|
186
185
|
return None
|
|
187
186
|
|
|
188
|
-
def
|
|
187
|
+
def _handle_expr_VirtualVariable(self, expr: VirtualVariable) -> VirtualVariable | None:
|
|
189
188
|
if expr.varid in self.vvar_to_vvar:
|
|
190
189
|
return VirtualVariable(
|
|
191
190
|
expr.idx,
|
|
@@ -199,13 +198,13 @@ class SimEngineDephiRewriting(
|
|
|
199
198
|
)
|
|
200
199
|
return None
|
|
201
200
|
|
|
202
|
-
def
|
|
203
|
-
if
|
|
201
|
+
def _handle_stmt_Return(self, stmt):
|
|
202
|
+
if stmt.ret_exprs is None:
|
|
204
203
|
new_ret_exprs = None
|
|
205
204
|
else:
|
|
206
205
|
updated = False
|
|
207
206
|
new_ret_exprs = []
|
|
208
|
-
for r in
|
|
207
|
+
for r in stmt.ret_exprs:
|
|
209
208
|
new_r = self._expr(r)
|
|
210
209
|
if new_r is not None:
|
|
211
210
|
updated = True
|
|
@@ -214,10 +213,13 @@ class SimEngineDephiRewriting(
|
|
|
214
213
|
new_ret_exprs = None
|
|
215
214
|
|
|
216
215
|
if new_ret_exprs:
|
|
217
|
-
return Return(
|
|
216
|
+
return Return(stmt.idx, new_ret_exprs, **stmt.tags)
|
|
217
|
+
return None
|
|
218
|
+
|
|
219
|
+
def _handle_stmt_IncompleteSwitchCaseHeadStatement(self, stmt):
|
|
218
220
|
return None
|
|
219
221
|
|
|
220
|
-
def
|
|
222
|
+
def _handle_expr_BinaryOp(self, expr):
|
|
221
223
|
new_op0 = self._expr(expr.operands[0])
|
|
222
224
|
new_op1 = self._expr(expr.operands[1])
|
|
223
225
|
|
|
@@ -233,13 +235,24 @@ class SimEngineDephiRewriting(
|
|
|
233
235
|
bits=expr.bits,
|
|
234
236
|
floating_point=expr.floating_point,
|
|
235
237
|
rounding_mode=expr.rounding_mode,
|
|
236
|
-
from_bits=expr.from_bits,
|
|
237
|
-
to_bits=expr.to_bits,
|
|
238
238
|
**expr.tags,
|
|
239
239
|
)
|
|
240
240
|
return None
|
|
241
241
|
|
|
242
|
-
def
|
|
242
|
+
def _handle_expr_UnaryOp(self, expr):
|
|
243
|
+
new_op0 = self._expr(expr.operands[0])
|
|
244
|
+
|
|
245
|
+
if new_op0 is not None:
|
|
246
|
+
return UnaryOp(
|
|
247
|
+
expr.idx,
|
|
248
|
+
expr.op,
|
|
249
|
+
expr.operands[0] if new_op0 is None else new_op0,
|
|
250
|
+
bits=expr.bits,
|
|
251
|
+
**expr.tags,
|
|
252
|
+
)
|
|
253
|
+
return None
|
|
254
|
+
|
|
255
|
+
def _handle_expr_ITE(self, expr):
|
|
243
256
|
new_cond = self._expr(expr.cond)
|
|
244
257
|
new_iftrue = self._expr(expr.iftrue)
|
|
245
258
|
new_iffalse = self._expr(expr.iffalse)
|
|
@@ -275,7 +288,7 @@ class SimEngineDephiRewriting(
|
|
|
275
288
|
)
|
|
276
289
|
return None
|
|
277
290
|
|
|
278
|
-
def
|
|
291
|
+
def _handle_expr_DirtyExpression(self, expr: DirtyExpression) -> DirtyExpression | None:
|
|
279
292
|
new_operands = []
|
|
280
293
|
updated = False
|
|
281
294
|
for o in expr.operands:
|
|
@@ -306,5 +319,116 @@ class SimEngineDephiRewriting(
|
|
|
306
319
|
)
|
|
307
320
|
return None
|
|
308
321
|
|
|
309
|
-
def
|
|
322
|
+
def _handle_expr_BasePointerOffset(self, expr):
|
|
323
|
+
return None
|
|
324
|
+
|
|
325
|
+
def _handle_expr_StackBaseOffset(self, expr):
|
|
326
|
+
return None
|
|
327
|
+
|
|
328
|
+
def _handle_expr_Call(self, expr: Call):
|
|
329
|
+
new_target = self._expr(expr.target) if expr.target is not None and not isinstance(expr.target, str) else None
|
|
330
|
+
new_ret_expr = self._expr(expr.ret_expr) if expr.ret_expr is not None else None
|
|
331
|
+
new_fp_ret_expr = self._expr(expr.fp_ret_expr) if expr.fp_ret_expr is not None else None
|
|
332
|
+
|
|
333
|
+
if new_target is not None or new_ret_expr is not None or new_fp_ret_expr is not None:
|
|
334
|
+
return Call(
|
|
335
|
+
expr.idx,
|
|
336
|
+
expr.target if new_target is None else new_target,
|
|
337
|
+
calling_convention=expr.calling_convention,
|
|
338
|
+
prototype=expr.prototype,
|
|
339
|
+
args=expr.args,
|
|
340
|
+
ret_expr=expr.ret_expr if new_ret_expr is None else new_ret_expr,
|
|
341
|
+
fp_ret_expr=expr.fp_ret_expr if new_fp_ret_expr is None else new_fp_ret_expr,
|
|
342
|
+
bits=expr.bits,
|
|
343
|
+
**expr.tags,
|
|
344
|
+
)
|
|
345
|
+
return None
|
|
346
|
+
|
|
347
|
+
def _handle_expr_DirtyExpression(self, expr):
|
|
310
348
|
return None
|
|
349
|
+
|
|
350
|
+
def _handle_expr_MultiStatementExpression(self, expr):
|
|
351
|
+
return None
|
|
352
|
+
|
|
353
|
+
def _handle_expr_Register(self, expr):
|
|
354
|
+
return None
|
|
355
|
+
|
|
356
|
+
def _handle_expr_Reinterpret(self, expr):
|
|
357
|
+
return None
|
|
358
|
+
|
|
359
|
+
def _handle_expr_Tmp(self, expr):
|
|
360
|
+
return None
|
|
361
|
+
|
|
362
|
+
def _handle_expr_VEXCCallExpression(self, expr):
|
|
363
|
+
return None
|
|
364
|
+
|
|
365
|
+
def _unreachable(self, *args, **kwargs):
|
|
366
|
+
assert False
|
|
367
|
+
|
|
368
|
+
_handle_binop_Add = _unreachable
|
|
369
|
+
_handle_binop_AddF = _unreachable
|
|
370
|
+
_handle_binop_AddV = _unreachable
|
|
371
|
+
_handle_binop_And = _unreachable
|
|
372
|
+
_handle_binop_Carry = _unreachable
|
|
373
|
+
_handle_binop_CmpEQ = _unreachable
|
|
374
|
+
_handle_binop_CmpF = _unreachable
|
|
375
|
+
_handle_binop_CmpGE = _unreachable
|
|
376
|
+
_handle_binop_CmpGT = _unreachable
|
|
377
|
+
_handle_binop_CmpLE = _unreachable
|
|
378
|
+
_handle_binop_CmpLT = _unreachable
|
|
379
|
+
_handle_binop_CmpNE = _unreachable
|
|
380
|
+
_handle_binop_Concat = _unreachable
|
|
381
|
+
_handle_binop_Div = _unreachable
|
|
382
|
+
_handle_binop_DivF = _unreachable
|
|
383
|
+
_handle_binop_DivV = _unreachable
|
|
384
|
+
_handle_binop_LogicalAnd = _unreachable
|
|
385
|
+
_handle_binop_LogicalOr = _unreachable
|
|
386
|
+
_handle_binop_Mod = _unreachable
|
|
387
|
+
_handle_binop_Mul = _unreachable
|
|
388
|
+
_handle_binop_Mull = _unreachable
|
|
389
|
+
_handle_binop_MulF = _unreachable
|
|
390
|
+
_handle_binop_MulV = _unreachable
|
|
391
|
+
_handle_binop_MulHiV = _unreachable
|
|
392
|
+
_handle_binop_Or = _unreachable
|
|
393
|
+
_handle_binop_Rol = _unreachable
|
|
394
|
+
_handle_binop_Ror = _unreachable
|
|
395
|
+
_handle_binop_SBorrow = _unreachable
|
|
396
|
+
_handle_binop_SCarry = _unreachable
|
|
397
|
+
_handle_binop_Sar = _unreachable
|
|
398
|
+
_handle_binop_Shl = _unreachable
|
|
399
|
+
_handle_binop_Shr = _unreachable
|
|
400
|
+
_handle_binop_Sub = _unreachable
|
|
401
|
+
_handle_binop_SubF = _unreachable
|
|
402
|
+
_handle_binop_SubV = _unreachable
|
|
403
|
+
_handle_binop_Xor = _unreachable
|
|
404
|
+
_handle_binop_InterleaveLOV = _unreachable
|
|
405
|
+
_handle_binop_InterleaveHIV = _unreachable
|
|
406
|
+
_handle_binop_CasCmpEQ = _unreachable
|
|
407
|
+
_handle_binop_CasCmpNE = _unreachable
|
|
408
|
+
_handle_binop_ExpCmpNE = _unreachable
|
|
409
|
+
_handle_binop_SarNV = _unreachable
|
|
410
|
+
_handle_binop_ShrNV = _unreachable
|
|
411
|
+
_handle_binop_ShlNV = _unreachable
|
|
412
|
+
_handle_binop_CmpEQV = _unreachable
|
|
413
|
+
_handle_binop_CmpNEV = _unreachable
|
|
414
|
+
_handle_binop_CmpGEV = _unreachable
|
|
415
|
+
_handle_binop_CmpGTV = _unreachable
|
|
416
|
+
_handle_binop_CmpLEV = _unreachable
|
|
417
|
+
_handle_binop_CmpLTV = _unreachable
|
|
418
|
+
_handle_binop_MinV = _unreachable
|
|
419
|
+
_handle_binop_MaxV = _unreachable
|
|
420
|
+
_handle_binop_QAddV = _unreachable
|
|
421
|
+
_handle_binop_QNarrowBinV = _unreachable
|
|
422
|
+
_handle_binop_PermV = _unreachable
|
|
423
|
+
_handle_binop_Set = _unreachable
|
|
424
|
+
_handle_unop_BitwiseNeg = _unreachable
|
|
425
|
+
_handle_unop_Dereference = _unreachable
|
|
426
|
+
_handle_unop_Neg = _unreachable
|
|
427
|
+
_handle_unop_Not = _unreachable
|
|
428
|
+
_handle_unop_Reference = _unreachable
|
|
429
|
+
_handle_unop_Clz = _unreachable
|
|
430
|
+
_handle_unop_Ctz = _unreachable
|
|
431
|
+
_handle_unop_GetMSBs = _unreachable
|
|
432
|
+
_handle_unop_unpack = _unreachable
|
|
433
|
+
_handle_unop_Sqrt = _unreachable
|
|
434
|
+
_handle_unop_RSqrtEst = _unreachable
|
|
@@ -7,6 +7,7 @@ from ailment.block import Block
|
|
|
7
7
|
from ailment.statement import Assignment
|
|
8
8
|
from ailment.expression import VirtualVariable, Phi
|
|
9
9
|
|
|
10
|
+
import angr
|
|
10
11
|
from angr.utils.ail import is_phi_assignment
|
|
11
12
|
from angr.knowledge_plugins.functions import Function
|
|
12
13
|
from angr.analyses import register_analysis
|
|
@@ -53,7 +54,7 @@ class SeqNodeRewriter(SequenceWalker):
|
|
|
53
54
|
variables.
|
|
54
55
|
"""
|
|
55
56
|
|
|
56
|
-
def __init__(self, seq_node: SequenceNode, vvar_to_vvar: dict[int, int],
|
|
57
|
+
def __init__(self, seq_node: SequenceNode, vvar_to_vvar: dict[int, int], project: angr.Project):
|
|
57
58
|
super().__init__(
|
|
58
59
|
handlers={
|
|
59
60
|
Block: self._handle_Block,
|
|
@@ -63,7 +64,7 @@ class SeqNodeRewriter(SequenceWalker):
|
|
|
63
64
|
)
|
|
64
65
|
|
|
65
66
|
self.vvar_to_vvar = vvar_to_vvar
|
|
66
|
-
self.engine = SimEngineDephiRewriting(
|
|
67
|
+
self.engine = SimEngineDephiRewriting(project, self.vvar_to_vvar)
|
|
67
68
|
|
|
68
69
|
self.output = self.walk(seq_node)
|
|
69
70
|
if self.output is None:
|
|
@@ -71,7 +72,7 @@ class SeqNodeRewriter(SequenceWalker):
|
|
|
71
72
|
self.output = seq_node
|
|
72
73
|
|
|
73
74
|
def _handle_Assignment(self, stmt: Assignment, **kwargs) -> Assignment: # pylint:disable=unused-argument
|
|
74
|
-
return self.engine.
|
|
75
|
+
return self.engine._handle_stmt_Assignment(stmt)
|
|
75
76
|
|
|
76
77
|
def _handle_Block(self, block: Block, **kwargs) -> Block | None: # pylint:disable=unused-argument
|
|
77
78
|
self.engine.out_block = None
|
|
@@ -117,7 +118,7 @@ class SeqNodeDephication(DephicationBase):
|
|
|
117
118
|
return collector.phi_to_src
|
|
118
119
|
|
|
119
120
|
def _rewrite_container(self) -> Any:
|
|
120
|
-
rewriter = SeqNodeRewriter(self._seq_node, self.vvar_to_vvar_mapping, self.project
|
|
121
|
+
rewriter = SeqNodeRewriter(self._seq_node, self.vvar_to_vvar_mapping, self.project)
|
|
121
122
|
return rewriter.output
|
|
122
123
|
|
|
123
124
|
|
|
@@ -19,7 +19,7 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
21
|
@staticmethod
|
|
22
|
-
def _check_divisor(a, b, ndigits=6):
|
|
22
|
+
def _check_divisor(a: int, b: int, ndigits: int = 6) -> int | None:
|
|
23
23
|
if b == 0:
|
|
24
24
|
return None
|
|
25
25
|
divisor_1 = 1 + (a // b)
|
|
@@ -27,7 +27,7 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
27
27
|
return divisor_1 if divisor_1 == divisor_2 else None
|
|
28
28
|
|
|
29
29
|
# pylint: disable=too-many-boolean-expressions
|
|
30
|
-
def
|
|
30
|
+
def _handle_expr_Convert(self, expr: Expr.Convert):
|
|
31
31
|
if expr.from_bits == 128 and expr.to_bits == 64:
|
|
32
32
|
operand_expr = self._expr(expr.operand)
|
|
33
33
|
if (
|
|
@@ -42,18 +42,20 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
42
42
|
):
|
|
43
43
|
if operand_expr.operands[0].op == "Shr":
|
|
44
44
|
Y = operand_expr.operands[0].operands[1].value
|
|
45
|
+
assert isinstance(Y, int)
|
|
45
46
|
else:
|
|
46
47
|
Y = int(math.log2(operand_expr.operands[0].operands[1].value))
|
|
47
48
|
C = operand_expr.operands[1].value
|
|
49
|
+
assert isinstance(C, int)
|
|
48
50
|
divisor = self._check_divisor(pow(2, 64 + Y), C)
|
|
49
51
|
if divisor:
|
|
50
52
|
X = operand_expr.operands[0].operands[0]
|
|
51
53
|
new_const = Expr.Const(expr.idx, None, divisor, 64)
|
|
52
54
|
return Expr.BinaryOp(expr.idx, "Div", [X, new_const], expr.signed, **expr.tags)
|
|
53
55
|
|
|
54
|
-
return
|
|
56
|
+
return expr
|
|
55
57
|
|
|
56
|
-
def
|
|
58
|
+
def _handle_binop_Shr(self, expr):
|
|
57
59
|
operand_0 = self._expr(expr.operands[0])
|
|
58
60
|
operand_1 = self._expr(expr.operands[1])
|
|
59
61
|
|
|
@@ -90,6 +92,8 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
90
92
|
if isinstance(operand_0.operand.operands[1], Expr.Const):
|
|
91
93
|
C = operand_0.operand.operands[1].value
|
|
92
94
|
Y = operand_1.value
|
|
95
|
+
assert isinstance(C, int)
|
|
96
|
+
assert isinstance(Y, int)
|
|
93
97
|
divisor = self._check_divisor(pow(2, 64 + Y), C)
|
|
94
98
|
X = operand_0.operand.operands[0]
|
|
95
99
|
elif isinstance(operand_0.operand.operands[0], Expr.BinaryOp) and operand_0.operand.operands[0].op in {
|
|
@@ -102,6 +106,9 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
102
106
|
Y = operand_0.operand.operands[0].operands[1].value
|
|
103
107
|
else:
|
|
104
108
|
Y = int(math.log2(operand_0.operand.operands[0].operands[1].value))
|
|
109
|
+
assert isinstance(C, int)
|
|
110
|
+
assert isinstance(Y, int)
|
|
111
|
+
assert isinstance(Z, int)
|
|
105
112
|
divisor = self._check_divisor(pow(2, 64 + Z + Y), C)
|
|
106
113
|
X = operand_0.operand.operands[0].operands[0]
|
|
107
114
|
if isinstance(operand_1, Expr.Const) and isinstance(operand_0, Expr.BinaryOp) and operand_0.op == "Add":
|
|
@@ -127,6 +134,9 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
127
134
|
and V_.operands[0] == X
|
|
128
135
|
and V_.operands[1] == xC
|
|
129
136
|
):
|
|
137
|
+
assert isinstance(Y, int)
|
|
138
|
+
assert isinstance(Z, int)
|
|
139
|
+
assert isinstance(V, int)
|
|
130
140
|
divisor = self._check_divisor(
|
|
131
141
|
pow(2, Y + V + Z), C * (pow(2, V) - 1) + pow(2, Y)
|
|
132
142
|
)
|
|
@@ -141,6 +151,9 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
141
151
|
if isinstance(V, Expr.Const):
|
|
142
152
|
V = V.value
|
|
143
153
|
if isinstance(V_, Expr.BinaryOp) and V_.op == "Sub" and V_.operands[1] == xC:
|
|
154
|
+
assert isinstance(Y, int)
|
|
155
|
+
assert isinstance(Z, int)
|
|
156
|
+
assert isinstance(V, int)
|
|
144
157
|
divisor = self._check_divisor(pow(2, Y + V + Z), C * (pow(2, V) - 1) + pow(2, Y))
|
|
145
158
|
elif (
|
|
146
159
|
isinstance(xC, Expr.BinaryOp)
|
|
@@ -164,6 +177,9 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
164
177
|
Y = xC.operands[1].value
|
|
165
178
|
V = x_xC.operands[1].value
|
|
166
179
|
if x_xC.operands[0].operands[0] == X:
|
|
180
|
+
assert isinstance(Y, int)
|
|
181
|
+
assert isinstance(Z, int)
|
|
182
|
+
assert isinstance(V, int)
|
|
167
183
|
divisor = self._check_divisor(pow(2, Y + V + Z), C * (pow(2, V) - 1) + pow(2, Y))
|
|
168
184
|
|
|
169
185
|
# unsigned int
|
|
@@ -178,6 +194,9 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
178
194
|
C = operand_0.operands[1].value
|
|
179
195
|
Z = operand_1.value
|
|
180
196
|
X = operand_0.operands[0]
|
|
197
|
+
assert isinstance(C, int)
|
|
198
|
+
assert isinstance(Z, int)
|
|
199
|
+
assert isinstance(V, int)
|
|
181
200
|
divisor = self._check_divisor(pow(2, V + Z), C)
|
|
182
201
|
elif (
|
|
183
202
|
isinstance(operand_0.operands[0], Expr.BinaryOp)
|
|
@@ -196,11 +215,17 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
196
215
|
if operand_0.operands[0].op == "Mod":
|
|
197
216
|
Y = int(math.log2(operand_0.operands[0].operands[1].value))
|
|
198
217
|
Z = operand_1.value
|
|
218
|
+
assert isinstance(Y, int)
|
|
219
|
+
assert isinstance(Z, int)
|
|
220
|
+
assert isinstance(V, int)
|
|
221
|
+
assert isinstance(C, int)
|
|
199
222
|
divisor = self._check_divisor(pow(2, Y + Z + V), C, ndigits)
|
|
200
223
|
else:
|
|
201
224
|
X = operand_0.operands[0]
|
|
202
225
|
Y = operand_1.value
|
|
203
226
|
C = operand_0.operands[1].value
|
|
227
|
+
assert isinstance(Y, int)
|
|
228
|
+
assert isinstance(C, int)
|
|
204
229
|
divisor = self._check_divisor(pow(2, Y), C)
|
|
205
230
|
|
|
206
231
|
if divisor and X:
|
|
@@ -225,7 +250,7 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
225
250
|
return Expr.BinaryOp(expr.idx, "Shr", [operand_0, operand_1], expr.signed)
|
|
226
251
|
return expr
|
|
227
252
|
|
|
228
|
-
def
|
|
253
|
+
def _handle_binop_Mul(self, expr):
|
|
229
254
|
operand_0, operand_1 = expr.operands
|
|
230
255
|
|
|
231
256
|
if (
|
|
@@ -234,6 +259,8 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
234
259
|
and isinstance(operand_0.operands[1], Expr.Const)
|
|
235
260
|
and operand_0.op in {"Mod", "Shr"}
|
|
236
261
|
):
|
|
262
|
+
assert isinstance(operand_0.operands[1].value, int)
|
|
263
|
+
assert isinstance(operand_1.value, int)
|
|
237
264
|
Y = int(math.log2(operand_0.operands[1].value)) if operand_0.op == "Mod" else operand_0.operands[1].value
|
|
238
265
|
C = operand_1.value
|
|
239
266
|
X = operand_0.operands[0]
|
|
@@ -242,8 +269,7 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
242
269
|
if isinstance(X, Expr.Convert):
|
|
243
270
|
V = X.from_bits - X.to_bits
|
|
244
271
|
ndigits = 5 if V == 32 else 6
|
|
245
|
-
if self._check_divisor(pow(2, V + Y), C, ndigits) and X:
|
|
246
|
-
divisor = self._check_divisor(pow(2, Y + V), C, ndigits)
|
|
272
|
+
if (divisor := self._check_divisor(pow(2, V + Y), C, ndigits)) and X:
|
|
247
273
|
new_const = Expr.Const(expr.idx, None, divisor, 64)
|
|
248
274
|
return Expr.BinaryOp(expr.idx, "Div", [X, new_const], expr.signed, **expr.tags)
|
|
249
275
|
if (
|
|
@@ -252,7 +278,9 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
252
278
|
and isinstance(operand_0.operand, Expr.BinaryOp)
|
|
253
279
|
and isinstance(operand_0.operand.operands[1], Expr.Const)
|
|
254
280
|
and operand_0.operand.op in {"Mod", "Shr"}
|
|
281
|
+
and isinstance(operand_1.value, int)
|
|
255
282
|
):
|
|
283
|
+
assert isinstance(operand_0.operand.operands[1].value, int)
|
|
256
284
|
if operand_0.operand.op == "Mod":
|
|
257
285
|
Y = int(math.log2(operand_0.operand.operands[1].value))
|
|
258
286
|
else:
|
|
@@ -261,13 +289,12 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
261
289
|
X = operand_0.operand.operands[0]
|
|
262
290
|
V = operand_0.from_bits - operand_0.to_bits
|
|
263
291
|
ndigits = 5 if V == 32 else 6
|
|
264
|
-
if self._check_divisor(pow(2, V + Y), C, ndigits) and X:
|
|
265
|
-
divisor = self._check_divisor(pow(2, Y + V), C, ndigits)
|
|
292
|
+
if (divisor := self._check_divisor(pow(2, V + Y), C, ndigits)) and X:
|
|
266
293
|
new_const = Expr.Const(expr.idx, None, divisor, 64)
|
|
267
294
|
return Expr.BinaryOp(expr.idx, "Div", [X, new_const], expr.signed, **expr.tags)
|
|
268
|
-
return
|
|
295
|
+
return expr
|
|
269
296
|
|
|
270
|
-
def
|
|
297
|
+
def _handle_binop_Div(self, expr):
|
|
271
298
|
operand_0 = self._expr(expr.operands[0])
|
|
272
299
|
operand_1 = self._expr(expr.operands[1])
|
|
273
300
|
|
|
@@ -285,10 +312,7 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
285
312
|
return Expr.BinaryOp(expr.idx, "Div", [operand_0, operand_1], expr.signed, **expr.tags)
|
|
286
313
|
return expr
|
|
287
314
|
|
|
288
|
-
def
|
|
289
|
-
if len(expr.operands) != 2:
|
|
290
|
-
return super()._ail_handle_Add(expr)
|
|
291
|
-
|
|
315
|
+
def _handle_binop_Add(self, expr):
|
|
292
316
|
op0 = self._expr(expr.operands[0])
|
|
293
317
|
op1 = self._expr(expr.operands[1])
|
|
294
318
|
|
|
@@ -350,6 +374,7 @@ class DivSimplifierAILEngine(SimplifierAILEngine):
|
|
|
350
374
|
X = operand_1
|
|
351
375
|
V = bits
|
|
352
376
|
ndigits = 5 if V == 32 else 6
|
|
377
|
+
assert isinstance(C, int)
|
|
353
378
|
divisor = self._check_divisor(pow(2, V), C, ndigits)
|
|
354
379
|
if divisor is not None and X:
|
|
355
380
|
new_const = Expr.Const(None, None, divisor, V)
|
|
@@ -380,7 +405,7 @@ class DivSimplifier(OptimizationPass):
|
|
|
380
405
|
super().__init__(func, **kwargs)
|
|
381
406
|
|
|
382
407
|
self.state = SimplifierAILState(self.project.arch)
|
|
383
|
-
self.engine = DivSimplifierAILEngine()
|
|
408
|
+
self.engine = DivSimplifierAILEngine(self.project)
|
|
384
409
|
|
|
385
410
|
self.analyze()
|
|
386
411
|
|