angr 9.2.131__py3-none-win_amd64.whl → 9.2.132__py3-none-win_amd64.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/lib/angr_native.dll +0 -0
- 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 +110 -111
- 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
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
import logging
|
|
4
4
|
|
|
5
|
+
from ailment.manager import Manager
|
|
5
6
|
from ailment.statement import Statement, Assignment, Store, Call, Return, ConditionalJump, DirtyStatement
|
|
6
7
|
from ailment.expression import (
|
|
7
8
|
Expression,
|
|
@@ -12,7 +13,6 @@ from ailment.expression import (
|
|
|
12
13
|
VirtualVariableCategory,
|
|
13
14
|
BinaryOp,
|
|
14
15
|
UnaryOp,
|
|
15
|
-
Phi,
|
|
16
16
|
Convert,
|
|
17
17
|
StackBaseOffset,
|
|
18
18
|
VEXCCallExpression,
|
|
@@ -21,8 +21,8 @@ from ailment.expression import (
|
|
|
21
21
|
DirtyExpression,
|
|
22
22
|
)
|
|
23
23
|
|
|
24
|
+
from angr.engines.light.engine import SimEngineNostmtAIL
|
|
24
25
|
from angr.utils.ssa import get_reg_offset_base_and_size
|
|
25
|
-
from angr.engines.light import SimEngineLight, SimEngineLightAILMixin
|
|
26
26
|
from .rewriting_state import RewritingState
|
|
27
27
|
|
|
28
28
|
|
|
@@ -30,34 +30,28 @@ _l = logging.getLogger(__name__)
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class SimEngineSSARewriting(
|
|
33
|
-
|
|
34
|
-
SimEngineLight,
|
|
33
|
+
SimEngineNostmtAIL[RewritingState, Expression | None, Statement | tuple[Statement, ...], None]
|
|
35
34
|
):
|
|
36
35
|
"""
|
|
37
36
|
This engine rewrites every block to insert phi variables and replaces every used variable with their versioned
|
|
38
37
|
copies at each use location.
|
|
39
38
|
"""
|
|
40
39
|
|
|
41
|
-
state: RewritingState
|
|
42
|
-
|
|
43
40
|
def __init__(
|
|
44
41
|
self,
|
|
45
|
-
arch,
|
|
46
|
-
*,
|
|
47
42
|
project,
|
|
43
|
+
*,
|
|
48
44
|
sp_tracker,
|
|
49
45
|
udef_to_phiid: dict[tuple, set[int]],
|
|
50
46
|
phiid_to_loc: dict[int, tuple[int, int | None]],
|
|
51
47
|
stackvar_locs: dict[int, int],
|
|
52
|
-
ail_manager
|
|
48
|
+
ail_manager: Manager,
|
|
53
49
|
vvar_id_start: int = 0,
|
|
54
50
|
bp_as_gpr: bool = False,
|
|
55
51
|
rewrite_tmps: bool = False,
|
|
56
52
|
):
|
|
57
|
-
super().__init__()
|
|
53
|
+
super().__init__(project)
|
|
58
54
|
|
|
59
|
-
self.arch = arch
|
|
60
|
-
self.project = project
|
|
61
55
|
self.sp_tracker = sp_tracker
|
|
62
56
|
self.bp_as_gpr = bp_as_gpr
|
|
63
57
|
self.def_to_vvid: dict[tuple[int, int | None, int, Expression | Statement], int] = {}
|
|
@@ -81,18 +75,25 @@ class SimEngineSSARewriting(
|
|
|
81
75
|
# Handlers
|
|
82
76
|
#
|
|
83
77
|
|
|
84
|
-
def
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
78
|
+
def _top(self, bits):
|
|
79
|
+
assert False, "Unreachable"
|
|
80
|
+
|
|
81
|
+
def _is_top(self, expr):
|
|
82
|
+
assert False, "Unreachable"
|
|
83
|
+
|
|
84
|
+
def _process_block_end(self, block, stmt_data, whitelist):
|
|
85
|
+
assert whitelist is None
|
|
86
|
+
for stmt_idx, new_stmt in enumerate(stmt_data):
|
|
87
|
+
if new_stmt is not None:
|
|
88
|
+
if isinstance(new_stmt, tuple):
|
|
89
|
+
for stmt_ in new_stmt:
|
|
90
|
+
self.state.append_statement(stmt_)
|
|
91
|
+
else:
|
|
92
|
+
self.state.append_statement(new_stmt)
|
|
90
93
|
else:
|
|
91
|
-
self.state.append_statement(
|
|
92
|
-
else:
|
|
93
|
-
self.state.append_statement(stmt)
|
|
94
|
+
self.state.append_statement(block.statements[stmt_idx])
|
|
94
95
|
|
|
95
|
-
def
|
|
96
|
+
def _handle_stmt_Assignment(self, stmt):
|
|
96
97
|
new_src = self._expr(stmt.src)
|
|
97
98
|
|
|
98
99
|
if isinstance(stmt.dst, VirtualVariable):
|
|
@@ -158,7 +159,7 @@ class SimEngineSSARewriting(
|
|
|
158
159
|
return new_stmt
|
|
159
160
|
return None
|
|
160
161
|
|
|
161
|
-
def
|
|
162
|
+
def _handle_stmt_Store(self, stmt: Store) -> Store | Assignment | None:
|
|
162
163
|
new_data = self._expr(stmt.data)
|
|
163
164
|
if stmt.guard is None:
|
|
164
165
|
vvar = self._replace_def_store(self.block.addr, self.block.idx, self.stmt_idx, stmt)
|
|
@@ -182,7 +183,7 @@ class SimEngineSSARewriting(
|
|
|
182
183
|
|
|
183
184
|
return None
|
|
184
185
|
|
|
185
|
-
def
|
|
186
|
+
def _handle_stmt_ConditionalJump(self, stmt: ConditionalJump) -> ConditionalJump | None:
|
|
186
187
|
new_cond = self._expr(stmt.condition)
|
|
187
188
|
new_true_target = self._expr(stmt.true_target) if stmt.true_target is not None else None
|
|
188
189
|
new_false_target = self._expr(stmt.false_target) if stmt.false_target is not None else None
|
|
@@ -199,7 +200,7 @@ class SimEngineSSARewriting(
|
|
|
199
200
|
)
|
|
200
201
|
return None
|
|
201
202
|
|
|
202
|
-
def
|
|
203
|
+
def _handle_stmt_Call(self, stmt: Call) -> Call | None:
|
|
203
204
|
changed = False
|
|
204
205
|
|
|
205
206
|
new_target = self._replace_use_expr(stmt.target)
|
|
@@ -260,23 +261,22 @@ class SimEngineSSARewriting(
|
|
|
260
261
|
)
|
|
261
262
|
return None
|
|
262
263
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
def _handle_DirtyStatement(self, stmt: DirtyStatement) -> DirtyStatement | None:
|
|
264
|
+
def _handle_stmt_DirtyStatement(self, stmt: DirtyStatement) -> DirtyStatement | None:
|
|
266
265
|
dirty = self._expr(stmt.dirty)
|
|
267
266
|
if dirty is None or dirty is stmt.dirty:
|
|
268
267
|
return None
|
|
268
|
+
assert isinstance(dirty, DirtyExpression)
|
|
269
269
|
return DirtyStatement(stmt.idx, dirty, **stmt.tags)
|
|
270
270
|
|
|
271
|
-
def
|
|
271
|
+
def _handle_expr_Register(self, expr: Register) -> VirtualVariable | None:
|
|
272
272
|
return self._replace_use_reg(expr)
|
|
273
273
|
|
|
274
|
-
def
|
|
274
|
+
def _handle_expr_Tmp(self, expr: Tmp) -> VirtualVariable | None:
|
|
275
275
|
return (
|
|
276
276
|
self._replace_use_tmp(self.block.addr, self.block.idx, self.stmt_idx, expr) if self.rewrite_tmps else None
|
|
277
277
|
)
|
|
278
278
|
|
|
279
|
-
def
|
|
279
|
+
def _handle_expr_Load(self, expr: Load) -> Load | VirtualVariable | None:
|
|
280
280
|
if isinstance(expr.addr, StackBaseOffset) and isinstance(expr.addr.offset, int):
|
|
281
281
|
new_expr = self._replace_use_load(expr)
|
|
282
282
|
if new_expr is not None:
|
|
@@ -287,7 +287,7 @@ class SimEngineSSARewriting(
|
|
|
287
287
|
return Load(expr.idx, new_addr, expr.size, expr.endness, guard=expr.guard, alt=expr.alt, **expr.tags)
|
|
288
288
|
return None
|
|
289
289
|
|
|
290
|
-
def
|
|
290
|
+
def _handle_expr_Convert(self, expr: Convert) -> Convert | None:
|
|
291
291
|
new_operand = self._expr(expr.operand)
|
|
292
292
|
if new_operand is not None:
|
|
293
293
|
return Convert(
|
|
@@ -303,22 +303,13 @@ class SimEngineSSARewriting(
|
|
|
303
303
|
)
|
|
304
304
|
return None
|
|
305
305
|
|
|
306
|
-
def
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
def _handle_Phi(self, expr: Phi) -> None:
|
|
310
|
-
return None
|
|
311
|
-
|
|
312
|
-
def _handle_VirtualVariable(self, expr: VirtualVariable) -> None:
|
|
313
|
-
return None
|
|
314
|
-
|
|
315
|
-
def _handle_Return(self, expr: Return) -> Return | None:
|
|
316
|
-
if expr.ret_exprs is None:
|
|
306
|
+
def _handle_stmt_Return(self, stmt: Return) -> Return | None:
|
|
307
|
+
if stmt.ret_exprs is None:
|
|
317
308
|
new_ret_exprs = None
|
|
318
309
|
else:
|
|
319
310
|
updated = False
|
|
320
311
|
new_ret_exprs = []
|
|
321
|
-
for r in
|
|
312
|
+
for r in stmt.ret_exprs:
|
|
322
313
|
new_r = self._expr(r)
|
|
323
314
|
if new_r is not None:
|
|
324
315
|
updated = True
|
|
@@ -327,10 +318,10 @@ class SimEngineSSARewriting(
|
|
|
327
318
|
new_ret_exprs = None
|
|
328
319
|
|
|
329
320
|
if new_ret_exprs:
|
|
330
|
-
return Return(
|
|
321
|
+
return Return(stmt.idx, new_ret_exprs, **stmt.tags)
|
|
331
322
|
return None
|
|
332
323
|
|
|
333
|
-
def
|
|
324
|
+
def _handle_expr_BinaryOp(self, expr: BinaryOp) -> BinaryOp | None:
|
|
334
325
|
new_op0 = self._expr(expr.operands[0])
|
|
335
326
|
new_op1 = self._expr(expr.operands[1])
|
|
336
327
|
|
|
@@ -346,24 +337,23 @@ class SimEngineSSARewriting(
|
|
|
346
337
|
bits=expr.bits,
|
|
347
338
|
floating_point=expr.floating_point,
|
|
348
339
|
rounding_mode=expr.rounding_mode,
|
|
349
|
-
from_bits=expr.from_bits,
|
|
350
|
-
to_bits=expr.to_bits,
|
|
351
340
|
**expr.tags,
|
|
352
341
|
)
|
|
353
342
|
return None
|
|
354
343
|
|
|
355
|
-
def
|
|
344
|
+
def _handle_expr_UnaryOp(self, expr) -> UnaryOp | None:
|
|
356
345
|
new_op = self._expr(expr.operand)
|
|
357
346
|
if new_op is not None:
|
|
358
347
|
return UnaryOp(
|
|
359
348
|
expr.idx,
|
|
360
349
|
expr.op,
|
|
361
350
|
new_op,
|
|
351
|
+
bits=expr.bits,
|
|
362
352
|
**expr.tags,
|
|
363
353
|
)
|
|
364
354
|
return None
|
|
365
355
|
|
|
366
|
-
def
|
|
356
|
+
def _handle_expr_ITE(self, expr: ITE) -> ITE | None:
|
|
367
357
|
new_cond = self._expr(expr.cond)
|
|
368
358
|
new_iftrue = self._expr(expr.iftrue)
|
|
369
359
|
new_iffalse = self._expr(expr.iffalse)
|
|
@@ -378,7 +368,7 @@ class SimEngineSSARewriting(
|
|
|
378
368
|
)
|
|
379
369
|
return None
|
|
380
370
|
|
|
381
|
-
def
|
|
371
|
+
def _handle_expr_VEXCCallExpression(self, expr: VEXCCallExpression) -> VEXCCallExpression | None:
|
|
382
372
|
updated = False
|
|
383
373
|
new_operands = []
|
|
384
374
|
for operand in expr.operands:
|
|
@@ -390,10 +380,19 @@ class SimEngineSSARewriting(
|
|
|
390
380
|
new_operands.append(operand)
|
|
391
381
|
|
|
392
382
|
if updated:
|
|
393
|
-
return VEXCCallExpression(expr.idx, expr.callee, new_operands, bits=expr.bits, **expr.tags)
|
|
383
|
+
return VEXCCallExpression(expr.idx, expr.callee, tuple(new_operands), bits=expr.bits, **expr.tags)
|
|
394
384
|
return None
|
|
395
385
|
|
|
396
|
-
def
|
|
386
|
+
def _handle_expr_BasePointerOffset(self, expr):
|
|
387
|
+
return None
|
|
388
|
+
|
|
389
|
+
def _handle_expr_Call(self, expr):
|
|
390
|
+
return self._handle_stmt_Call(expr)
|
|
391
|
+
|
|
392
|
+
def _handle_expr_Const(self, expr):
|
|
393
|
+
return None
|
|
394
|
+
|
|
395
|
+
def _handle_expr_DirtyExpression(self, expr: DirtyExpression) -> DirtyExpression | None:
|
|
397
396
|
updated = False
|
|
398
397
|
new_operands = []
|
|
399
398
|
for operand in expr.operands:
|
|
@@ -424,7 +423,19 @@ class SimEngineSSARewriting(
|
|
|
424
423
|
)
|
|
425
424
|
return None
|
|
426
425
|
|
|
427
|
-
def
|
|
426
|
+
def _handle_expr_MultiStatementExpression(self, expr):
|
|
427
|
+
return None
|
|
428
|
+
|
|
429
|
+
def _handle_expr_Phi(self, expr):
|
|
430
|
+
return None
|
|
431
|
+
|
|
432
|
+
def _handle_expr_Reinterpret(self, expr):
|
|
433
|
+
return None
|
|
434
|
+
|
|
435
|
+
def _handle_expr_StackBaseOffset(self, expr):
|
|
436
|
+
return None
|
|
437
|
+
|
|
438
|
+
def _handle_expr_VirtualVariable(self, expr):
|
|
428
439
|
return None
|
|
429
440
|
|
|
430
441
|
#
|
|
@@ -477,7 +488,7 @@ class SimEngineSSARewriting(
|
|
|
477
488
|
extended_vvar,
|
|
478
489
|
shift_amount,
|
|
479
490
|
],
|
|
480
|
-
extended_vvar.bits,
|
|
491
|
+
bits=extended_vvar.bits,
|
|
481
492
|
**extended_vvar.tags,
|
|
482
493
|
)
|
|
483
494
|
else:
|
|
@@ -606,6 +617,7 @@ class SimEngineSSARewriting(
|
|
|
606
617
|
and self.state.registers[reg_expr.reg_offset][reg_expr.size] is not None
|
|
607
618
|
):
|
|
608
619
|
vvar = self.state.registers[reg_expr.reg_offset][reg_expr.size]
|
|
620
|
+
assert vvar is not None
|
|
609
621
|
return VirtualVariable(
|
|
610
622
|
reg_expr.idx,
|
|
611
623
|
vvar.varid,
|
|
@@ -734,3 +746,74 @@ class SimEngineSSARewriting(
|
|
|
734
746
|
self.state.registers[off] = {base_size: self.state.registers[off][base_size]}
|
|
735
747
|
else:
|
|
736
748
|
del self.state.registers[off]
|
|
749
|
+
|
|
750
|
+
def _unreachable(self, *args, **kwargs):
|
|
751
|
+
assert False
|
|
752
|
+
|
|
753
|
+
_handle_binop_Add = _unreachable
|
|
754
|
+
_handle_binop_AddF = _unreachable
|
|
755
|
+
_handle_binop_AddV = _unreachable
|
|
756
|
+
_handle_binop_And = _unreachable
|
|
757
|
+
_handle_binop_Carry = _unreachable
|
|
758
|
+
_handle_binop_CmpEQ = _unreachable
|
|
759
|
+
_handle_binop_CmpF = _unreachable
|
|
760
|
+
_handle_binop_CmpGE = _unreachable
|
|
761
|
+
_handle_binop_CmpGT = _unreachable
|
|
762
|
+
_handle_binop_CmpLE = _unreachable
|
|
763
|
+
_handle_binop_CmpLT = _unreachable
|
|
764
|
+
_handle_binop_CmpNE = _unreachable
|
|
765
|
+
_handle_binop_Concat = _unreachable
|
|
766
|
+
_handle_binop_Div = _unreachable
|
|
767
|
+
_handle_binop_DivF = _unreachable
|
|
768
|
+
_handle_binop_DivV = _unreachable
|
|
769
|
+
_handle_binop_LogicalAnd = _unreachable
|
|
770
|
+
_handle_binop_LogicalOr = _unreachable
|
|
771
|
+
_handle_binop_Mod = _unreachable
|
|
772
|
+
_handle_binop_Mul = _unreachable
|
|
773
|
+
_handle_binop_Mull = _unreachable
|
|
774
|
+
_handle_binop_MulF = _unreachable
|
|
775
|
+
_handle_binop_MulV = _unreachable
|
|
776
|
+
_handle_binop_MulHiV = _unreachable
|
|
777
|
+
_handle_binop_Or = _unreachable
|
|
778
|
+
_handle_binop_Rol = _unreachable
|
|
779
|
+
_handle_binop_Ror = _unreachable
|
|
780
|
+
_handle_binop_SBorrow = _unreachable
|
|
781
|
+
_handle_binop_SCarry = _unreachable
|
|
782
|
+
_handle_binop_Sar = _unreachable
|
|
783
|
+
_handle_binop_Shl = _unreachable
|
|
784
|
+
_handle_binop_Shr = _unreachable
|
|
785
|
+
_handle_binop_Sub = _unreachable
|
|
786
|
+
_handle_binop_SubF = _unreachable
|
|
787
|
+
_handle_binop_SubV = _unreachable
|
|
788
|
+
_handle_binop_Xor = _unreachable
|
|
789
|
+
_handle_binop_InterleaveLOV = _unreachable
|
|
790
|
+
_handle_binop_InterleaveHIV = _unreachable
|
|
791
|
+
_handle_binop_CasCmpEQ = _unreachable
|
|
792
|
+
_handle_binop_CasCmpNE = _unreachable
|
|
793
|
+
_handle_binop_ExpCmpNE = _unreachable
|
|
794
|
+
_handle_binop_SarNV = _unreachable
|
|
795
|
+
_handle_binop_ShrNV = _unreachable
|
|
796
|
+
_handle_binop_ShlNV = _unreachable
|
|
797
|
+
_handle_binop_CmpEQV = _unreachable
|
|
798
|
+
_handle_binop_CmpNEV = _unreachable
|
|
799
|
+
_handle_binop_CmpGEV = _unreachable
|
|
800
|
+
_handle_binop_CmpGTV = _unreachable
|
|
801
|
+
_handle_binop_CmpLEV = _unreachable
|
|
802
|
+
_handle_binop_CmpLTV = _unreachable
|
|
803
|
+
_handle_binop_MinV = _unreachable
|
|
804
|
+
_handle_binop_MaxV = _unreachable
|
|
805
|
+
_handle_binop_QAddV = _unreachable
|
|
806
|
+
_handle_binop_QNarrowBinV = _unreachable
|
|
807
|
+
_handle_binop_PermV = _unreachable
|
|
808
|
+
_handle_binop_Set = _unreachable
|
|
809
|
+
_handle_unop_BitwiseNeg = _unreachable
|
|
810
|
+
_handle_unop_Dereference = _unreachable
|
|
811
|
+
_handle_unop_Neg = _unreachable
|
|
812
|
+
_handle_unop_Not = _unreachable
|
|
813
|
+
_handle_unop_Reference = _unreachable
|
|
814
|
+
_handle_unop_Clz = _unreachable
|
|
815
|
+
_handle_unop_Ctz = _unreachable
|
|
816
|
+
_handle_unop_GetMSBs = _unreachable
|
|
817
|
+
_handle_unop_unpack = _unreachable
|
|
818
|
+
_handle_unop_Sqrt = _unreachable
|
|
819
|
+
_handle_unop_RSqrtEst = _unreachable
|
|
@@ -178,7 +178,8 @@ class Ssailification(Analysis): # pylint:disable=abstract-method
|
|
|
178
178
|
while True:
|
|
179
179
|
frontier = set()
|
|
180
180
|
for b in blocks:
|
|
181
|
-
|
|
181
|
+
if b in frontiers:
|
|
182
|
+
frontier |= frontiers[b]
|
|
182
183
|
if last_frontier is not None and last_frontier == frontier:
|
|
183
184
|
break
|
|
184
185
|
last_frontier = frontier
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
-
from typing import Any
|
|
3
2
|
import logging
|
|
4
3
|
|
|
5
4
|
import ailment
|
|
6
5
|
|
|
7
6
|
from angr.analyses import ForwardAnalysis
|
|
8
|
-
from angr.analyses.forward_analysis.visitors.graph import NodeType
|
|
9
7
|
from angr.analyses.forward_analysis import FunctionGraphVisitor
|
|
10
8
|
from .traversal_engine import SimEngineSSATraversal
|
|
11
9
|
from .traversal_state import TraversalState
|
|
@@ -14,7 +12,7 @@ from .traversal_state import TraversalState
|
|
|
14
12
|
l = logging.getLogger(__name__)
|
|
15
13
|
|
|
16
14
|
|
|
17
|
-
class TraversalAnalysis(ForwardAnalysis[
|
|
15
|
+
class TraversalAnalysis(ForwardAnalysis[TraversalState, ailment.Block, object, tuple[int, int]]):
|
|
18
16
|
"""
|
|
19
17
|
TraversalAnalysis traverses the AIL graph and collects definitions.
|
|
20
18
|
"""
|
|
@@ -31,15 +29,15 @@ class TraversalAnalysis(ForwardAnalysis[None, NodeType, object, object]):
|
|
|
31
29
|
self, order_jobs=True, allow_merging=True, allow_widening=False, graph_visitor=self._graph_visitor
|
|
32
30
|
)
|
|
33
31
|
self._engine_ail = SimEngineSSATraversal(
|
|
34
|
-
self.project
|
|
32
|
+
self.project,
|
|
35
33
|
self.project.simos,
|
|
36
34
|
sp_tracker=sp_tracker,
|
|
37
35
|
bp_as_gpr=bp_as_gpr,
|
|
38
36
|
stackvars=self._stackvars,
|
|
39
|
-
|
|
37
|
+
use_tmps=self._tmps,
|
|
40
38
|
)
|
|
41
39
|
|
|
42
|
-
self._visited_blocks: set[
|
|
40
|
+
self._visited_blocks: set[tuple[int, int]] = set()
|
|
43
41
|
|
|
44
42
|
self._analyze()
|
|
45
43
|
|
|
@@ -1,50 +1,53 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
from collections import OrderedDict
|
|
3
3
|
|
|
4
|
-
from ailment.statement import
|
|
4
|
+
from ailment.statement import Call, Store, ConditionalJump
|
|
5
5
|
from ailment.expression import Register, BinaryOp, StackBaseOffset, ITE, VEXCCallExpression, Tmp, DirtyExpression
|
|
6
6
|
|
|
7
|
-
from angr.engines.light import
|
|
7
|
+
from angr.engines.light import SimEngineLightAIL
|
|
8
|
+
from angr.project import Project
|
|
8
9
|
from angr.utils.ssa import get_reg_offset_base
|
|
9
10
|
from angr.utils.orderedset import OrderedSet
|
|
10
11
|
from angr.calling_conventions import default_cc
|
|
11
12
|
from .traversal_state import TraversalState
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
class SimEngineSSATraversal(
|
|
15
|
-
SimEngineLightAILMixin,
|
|
16
|
-
SimEngineLight,
|
|
17
|
-
):
|
|
15
|
+
class SimEngineSSATraversal(SimEngineLightAIL[TraversalState, None, None, None]):
|
|
18
16
|
"""
|
|
19
17
|
This engine collects all register and stack variable locations and links them to the block of their creation.
|
|
20
18
|
"""
|
|
21
19
|
|
|
22
|
-
state: TraversalState
|
|
23
|
-
|
|
24
20
|
def __init__(
|
|
25
21
|
self,
|
|
26
|
-
|
|
22
|
+
project: Project,
|
|
27
23
|
simos,
|
|
28
24
|
sp_tracker=None,
|
|
29
25
|
bp_as_gpr: bool = False,
|
|
30
26
|
def_to_loc=None,
|
|
31
27
|
loc_to_defs=None,
|
|
32
28
|
stackvars: bool = False,
|
|
33
|
-
|
|
29
|
+
use_tmps: bool = False,
|
|
34
30
|
):
|
|
35
|
-
super().__init__()
|
|
36
|
-
|
|
37
|
-
self.arch = arch
|
|
31
|
+
super().__init__(project)
|
|
38
32
|
self.simos = simos
|
|
39
33
|
self.sp_tracker = sp_tracker
|
|
40
34
|
self.bp_as_gpr = bp_as_gpr
|
|
41
35
|
self.stackvars = stackvars
|
|
42
|
-
self.
|
|
36
|
+
self.use_tmps = use_tmps
|
|
43
37
|
|
|
44
38
|
self.def_to_loc = def_to_loc if def_to_loc is not None else []
|
|
45
39
|
self.loc_to_defs = loc_to_defs if loc_to_defs is not None else OrderedDict()
|
|
46
40
|
|
|
47
|
-
def
|
|
41
|
+
def _is_top(self, expr):
|
|
42
|
+
return True
|
|
43
|
+
|
|
44
|
+
def _top(self, bits):
|
|
45
|
+
return None
|
|
46
|
+
|
|
47
|
+
def _process_block_end(self, block, stmt_data, whitelist):
|
|
48
|
+
pass
|
|
49
|
+
|
|
50
|
+
def _handle_stmt_Assignment(self, stmt):
|
|
48
51
|
if isinstance(stmt.dst, Register):
|
|
49
52
|
codeloc = self._codeloc()
|
|
50
53
|
self.def_to_loc.append((stmt.dst, codeloc))
|
|
@@ -57,7 +60,7 @@ class SimEngineSSATraversal(
|
|
|
57
60
|
|
|
58
61
|
self._expr(stmt.src)
|
|
59
62
|
|
|
60
|
-
def
|
|
63
|
+
def _handle_stmt_Store(self, stmt: Store):
|
|
61
64
|
self._expr(stmt.addr)
|
|
62
65
|
self._expr(stmt.data)
|
|
63
66
|
if stmt.guard is not None:
|
|
@@ -72,14 +75,14 @@ class SimEngineSSATraversal(
|
|
|
72
75
|
|
|
73
76
|
self.state.live_stackvars.add((stmt.addr.offset, stmt.size))
|
|
74
77
|
|
|
75
|
-
def
|
|
78
|
+
def _handle_stmt_ConditionalJump(self, stmt: ConditionalJump):
|
|
76
79
|
self._expr(stmt.condition)
|
|
77
80
|
if stmt.true_target is not None:
|
|
78
81
|
self._expr(stmt.true_target)
|
|
79
82
|
if stmt.false_target is not None:
|
|
80
83
|
self._expr(stmt.false_target)
|
|
81
84
|
|
|
82
|
-
def
|
|
85
|
+
def _handle_stmt_Call(self, stmt: Call):
|
|
83
86
|
|
|
84
87
|
# kill caller-saved registers
|
|
85
88
|
cc = (
|
|
@@ -87,6 +90,7 @@ class SimEngineSSATraversal(
|
|
|
87
90
|
if stmt.calling_convention is None
|
|
88
91
|
else stmt.calling_convention
|
|
89
92
|
)
|
|
93
|
+
assert cc is not None
|
|
90
94
|
for reg_name in cc.CALLER_SAVED_REGS:
|
|
91
95
|
reg_offset = self.arch.registers[reg_name][0]
|
|
92
96
|
base_off = get_reg_offset_base(reg_offset, self.arch)
|
|
@@ -102,11 +106,22 @@ class SimEngineSSATraversal(
|
|
|
102
106
|
base_off = get_reg_offset_base(stmt.ret_expr.reg_offset, self.arch)
|
|
103
107
|
self.state.live_registers.add(base_off)
|
|
104
108
|
|
|
105
|
-
|
|
109
|
+
def _handle_stmt_Dummy(self, stmt):
|
|
110
|
+
pass
|
|
111
|
+
|
|
112
|
+
def _handle_stmt_DirtyStatement(self, stmt):
|
|
113
|
+
self._expr(stmt.dirty)
|
|
114
|
+
|
|
115
|
+
def _handle_stmt_Jump(self, stmt):
|
|
116
|
+
self._expr(stmt.target)
|
|
106
117
|
|
|
107
|
-
|
|
118
|
+
_handle_stmt_Label = _handle_stmt_Dummy
|
|
108
119
|
|
|
109
|
-
def
|
|
120
|
+
def _handle_stmt_Return(self, stmt):
|
|
121
|
+
for expr in stmt.ret_exprs:
|
|
122
|
+
self._expr(expr)
|
|
123
|
+
|
|
124
|
+
def _handle_expr_Register(self, expr: Register):
|
|
110
125
|
base_offset = get_reg_offset_base(expr.reg_offset, self.arch)
|
|
111
126
|
|
|
112
127
|
if base_offset not in self.state.live_registers:
|
|
@@ -118,8 +133,8 @@ class SimEngineSSATraversal(
|
|
|
118
133
|
|
|
119
134
|
self.state.live_registers.add(base_offset)
|
|
120
135
|
|
|
121
|
-
def
|
|
122
|
-
if self.
|
|
136
|
+
def _handle_expr_Tmp(self, expr: Tmp):
|
|
137
|
+
if self.use_tmps:
|
|
123
138
|
codeloc = self._codeloc()
|
|
124
139
|
self.def_to_loc.append((expr, codeloc))
|
|
125
140
|
if codeloc not in self.loc_to_defs:
|
|
@@ -128,39 +143,99 @@ class SimEngineSSATraversal(
|
|
|
128
143
|
|
|
129
144
|
self.state.live_tmps.add(expr.tmp_idx)
|
|
130
145
|
|
|
131
|
-
def
|
|
146
|
+
def _handle_binop_Default(self, expr: BinaryOp):
|
|
132
147
|
self._expr(expr.operands[0])
|
|
133
148
|
self._expr(expr.operands[1])
|
|
134
149
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
150
|
+
_handle_binop_CmpLE = _handle_binop_Default
|
|
151
|
+
_handle_binop_CmpLT = _handle_binop_Default
|
|
152
|
+
_handle_binop_CmpGE = _handle_binop_Default
|
|
153
|
+
_handle_binop_CmpGT = _handle_binop_Default
|
|
154
|
+
_handle_binop_CmpEQ = _handle_binop_Default
|
|
155
|
+
_handle_binop_CmpNE = _handle_binop_Default
|
|
156
|
+
_handle_binop_Add = _handle_binop_Default
|
|
157
|
+
_handle_binop_AddF = _handle_binop_Default
|
|
158
|
+
_handle_binop_AddV = _handle_binop_Default
|
|
159
|
+
_handle_binop_And = _handle_binop_Default
|
|
160
|
+
_handle_binop_Carry = _handle_binop_Default
|
|
161
|
+
_handle_binop_CmpF = _handle_binop_Default
|
|
162
|
+
_handle_binop_Concat = _handle_binop_Default
|
|
163
|
+
_handle_binop_Div = _handle_binop_Default
|
|
164
|
+
_handle_binop_DivF = _handle_binop_Default
|
|
165
|
+
_handle_binop_DivV = _handle_binop_Default
|
|
166
|
+
_handle_binop_LogicalAnd = _handle_binop_Default
|
|
167
|
+
_handle_binop_LogicalOr = _handle_binop_Default
|
|
168
|
+
_handle_binop_Mod = _handle_binop_Default
|
|
169
|
+
_handle_binop_Mul = _handle_binop_Default
|
|
170
|
+
_handle_binop_Mull = _handle_binop_Default
|
|
171
|
+
_handle_binop_MulF = _handle_binop_Default
|
|
172
|
+
_handle_binop_MulV = _handle_binop_Default
|
|
173
|
+
_handle_binop_MulHiV = _handle_binop_Default
|
|
174
|
+
_handle_binop_Or = _handle_binop_Default
|
|
175
|
+
_handle_binop_Rol = _handle_binop_Default
|
|
176
|
+
_handle_binop_Ror = _handle_binop_Default
|
|
177
|
+
_handle_binop_SBorrow = _handle_binop_Default
|
|
178
|
+
_handle_binop_SCarry = _handle_binop_Default
|
|
179
|
+
_handle_binop_Sar = _handle_binop_Default
|
|
180
|
+
_handle_binop_Shl = _handle_binop_Default
|
|
181
|
+
_handle_binop_Shr = _handle_binop_Default
|
|
182
|
+
_handle_binop_Sub = _handle_binop_Default
|
|
183
|
+
_handle_binop_SubF = _handle_binop_Default
|
|
184
|
+
_handle_binop_SubV = _handle_binop_Default
|
|
185
|
+
_handle_binop_Xor = _handle_binop_Default
|
|
186
|
+
_handle_binop_InterleaveLOV = _handle_binop_Default
|
|
187
|
+
_handle_binop_InterleaveHIV = _handle_binop_Default
|
|
188
|
+
_handle_binop_CasCmpEQ = _handle_binop_Default
|
|
189
|
+
_handle_binop_CasCmpNE = _handle_binop_Default
|
|
190
|
+
_handle_binop_ExpCmpNE = _handle_binop_Default
|
|
191
|
+
_handle_binop_SarNV = _handle_binop_Default
|
|
192
|
+
_handle_binop_ShrNV = _handle_binop_Default
|
|
193
|
+
_handle_binop_ShlNV = _handle_binop_Default
|
|
194
|
+
_handle_binop_CmpEQV = _handle_binop_Default
|
|
195
|
+
_handle_binop_CmpNEV = _handle_binop_Default
|
|
196
|
+
_handle_binop_CmpGEV = _handle_binop_Default
|
|
197
|
+
_handle_binop_CmpGTV = _handle_binop_Default
|
|
198
|
+
_handle_binop_CmpLEV = _handle_binop_Default
|
|
199
|
+
_handle_binop_CmpLTV = _handle_binop_Default
|
|
200
|
+
_handle_binop_MinV = _handle_binop_Default
|
|
201
|
+
_handle_binop_MaxV = _handle_binop_Default
|
|
202
|
+
_handle_binop_QAddV = _handle_binop_Default
|
|
203
|
+
_handle_binop_QNarrowBinV = _handle_binop_Default
|
|
204
|
+
_handle_binop_PermV = _handle_binop_Default
|
|
205
|
+
_handle_binop_Set = _handle_binop_Default
|
|
206
|
+
|
|
207
|
+
def _handle_unop_Default(self, expr):
|
|
208
|
+
self._expr(expr.operands[0])
|
|
141
209
|
|
|
142
|
-
|
|
210
|
+
_handle_unop_BitwiseNeg = _handle_unop_Default
|
|
211
|
+
_handle_unop_Dereference = _handle_unop_Default
|
|
212
|
+
_handle_unop_Neg = _handle_unop_Default
|
|
213
|
+
_handle_unop_Not = _handle_unop_Default
|
|
214
|
+
_handle_unop_Reference = _handle_unop_Default
|
|
215
|
+
_handle_unop_Clz = _handle_unop_Default
|
|
216
|
+
_handle_unop_Ctz = _handle_unop_Default
|
|
217
|
+
_handle_unop_GetMSBs = _handle_unop_Default
|
|
218
|
+
_handle_unop_unpack = _handle_unop_Default
|
|
219
|
+
_handle_unop_Sqrt = _handle_unop_Default
|
|
220
|
+
_handle_unop_RSqrtEst = _handle_unop_Default
|
|
221
|
+
|
|
222
|
+
def _handle_expr_UnaryOp(self, expr):
|
|
143
223
|
self._expr(expr.operand)
|
|
144
224
|
|
|
145
|
-
def
|
|
146
|
-
self._expr(expr.operands[0])
|
|
147
|
-
self._expr(expr.operands[1])
|
|
148
|
-
|
|
149
|
-
def _handle_TernaryOp(self, expr):
|
|
225
|
+
def _handle_expr_BinaryOp(self, expr):
|
|
150
226
|
self._expr(expr.operands[0])
|
|
151
227
|
self._expr(expr.operands[1])
|
|
152
|
-
self._expr(expr.operands[2])
|
|
153
228
|
|
|
154
|
-
def
|
|
229
|
+
def _handle_expr_ITE(self, expr: ITE):
|
|
155
230
|
self._expr(expr.cond)
|
|
156
231
|
self._expr(expr.iftrue)
|
|
157
232
|
self._expr(expr.iffalse)
|
|
158
233
|
|
|
159
|
-
def
|
|
234
|
+
def _handle_expr_VEXCCallExpression(self, expr: VEXCCallExpression):
|
|
160
235
|
for operand in expr.operands:
|
|
161
236
|
self._expr(operand)
|
|
162
237
|
|
|
163
|
-
def
|
|
238
|
+
def _handle_expr_DirtyExpression(self, expr: DirtyExpression):
|
|
164
239
|
for operand in expr.operands:
|
|
165
240
|
self._expr(operand)
|
|
166
241
|
if expr.guard is not None:
|
|
@@ -171,5 +246,13 @@ class SimEngineSSATraversal(
|
|
|
171
246
|
def _handle_Dummy(self, expr):
|
|
172
247
|
pass
|
|
173
248
|
|
|
174
|
-
|
|
175
|
-
|
|
249
|
+
_handle_expr_VirtualVariable = _handle_Dummy
|
|
250
|
+
_handle_expr_Phi = _handle_Dummy
|
|
251
|
+
_handle_expr_Load = _handle_Dummy
|
|
252
|
+
_handle_expr_Convert = _handle_Dummy
|
|
253
|
+
_handle_expr_Const = _handle_Dummy
|
|
254
|
+
_handle_expr_MultiStatementExpression = _handle_Dummy
|
|
255
|
+
_handle_expr_Reinterpret = _handle_Dummy
|
|
256
|
+
_handle_expr_StackBaseOffset = _handle_Dummy
|
|
257
|
+
_handle_expr_BasePointerOffset = _handle_Dummy
|
|
258
|
+
_handle_expr_Call = _handle_Dummy
|