angr 9.2.131__py3-none-manylinux2014_aarch64.whl → 9.2.132__py3-none-manylinux2014_aarch64.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.

Files changed (111) hide show
  1. angr/__init__.py +1 -1
  2. angr/analyses/analysis.py +6 -2
  3. angr/analyses/cfg/cfg_emulated.py +5 -5
  4. angr/analyses/cfg/cfg_fast.py +2 -2
  5. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +139 -94
  6. angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +1 -1
  7. angr/analyses/ddg.py +14 -11
  8. angr/analyses/decompiler/ail_simplifier.py +3 -2
  9. angr/analyses/decompiler/block_simplifier.py +10 -21
  10. angr/analyses/decompiler/clinic.py +108 -34
  11. angr/analyses/decompiler/condition_processor.py +12 -10
  12. angr/analyses/decompiler/dephication/graph_rewriting.py +1 -1
  13. angr/analyses/decompiler/dephication/rewriting_engine.py +169 -45
  14. angr/analyses/decompiler/dephication/seqnode_dephication.py +5 -4
  15. angr/analyses/decompiler/optimization_passes/const_derefs.py +1 -0
  16. angr/analyses/decompiler/optimization_passes/div_simplifier.py +41 -16
  17. angr/analyses/decompiler/optimization_passes/engine_base.py +261 -83
  18. angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +173 -35
  19. angr/analyses/decompiler/optimization_passes/mod_simplifier.py +5 -2
  20. angr/analyses/decompiler/optimization_passes/optimization_pass.py +39 -19
  21. angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +2 -0
  22. angr/analyses/decompiler/ssailification/rewriting.py +1 -2
  23. angr/analyses/decompiler/ssailification/rewriting_engine.py +138 -55
  24. angr/analyses/decompiler/ssailification/ssailification.py +2 -1
  25. angr/analyses/decompiler/ssailification/traversal.py +4 -6
  26. angr/analyses/decompiler/ssailification/traversal_engine.py +125 -42
  27. angr/analyses/decompiler/structured_codegen/c.py +5 -3
  28. angr/analyses/decompiler/structuring/phoenix.py +26 -9
  29. angr/analyses/decompiler/structuring/structurer_nodes.py +9 -0
  30. angr/analyses/deobfuscator/irsb_reg_collector.py +29 -60
  31. angr/analyses/deobfuscator/string_obf_finder.py +2 -2
  32. angr/analyses/init_finder.py +47 -22
  33. angr/analyses/propagator/engine_base.py +21 -14
  34. angr/analyses/propagator/engine_vex.py +149 -179
  35. angr/analyses/propagator/propagator.py +10 -28
  36. angr/analyses/propagator/top_checker_mixin.py +211 -5
  37. angr/analyses/propagator/vex_vars.py +1 -1
  38. angr/analyses/reaching_definitions/dep_graph.py +1 -1
  39. angr/analyses/reaching_definitions/engine_ail.py +304 -329
  40. angr/analyses/reaching_definitions/engine_vex.py +243 -229
  41. angr/analyses/reaching_definitions/function_handler.py +3 -3
  42. angr/analyses/reaching_definitions/rd_state.py +37 -32
  43. angr/analyses/s_propagator.py +18 -3
  44. angr/analyses/s_reaching_definitions/s_reaching_definitions.py +9 -5
  45. angr/analyses/typehoon/simple_solver.py +7 -5
  46. angr/analyses/typehoon/translator.py +8 -0
  47. angr/analyses/typehoon/typeconsts.py +10 -2
  48. angr/analyses/typehoon/typevars.py +9 -7
  49. angr/analyses/variable_recovery/engine_ail.py +299 -259
  50. angr/analyses/variable_recovery/engine_base.py +135 -117
  51. angr/analyses/variable_recovery/engine_vex.py +175 -185
  52. angr/analyses/variable_recovery/irsb_scanner.py +49 -38
  53. angr/analyses/variable_recovery/variable_recovery.py +28 -5
  54. angr/analyses/variable_recovery/variable_recovery_base.py +32 -33
  55. angr/analyses/variable_recovery/variable_recovery_fast.py +2 -2
  56. angr/analyses/xrefs.py +46 -19
  57. angr/annocfg.py +19 -14
  58. angr/block.py +4 -9
  59. angr/calling_conventions.py +1 -1
  60. angr/engines/engine.py +30 -14
  61. angr/engines/light/__init__.py +11 -3
  62. angr/engines/light/engine.py +1003 -1185
  63. angr/engines/pcode/cc.py +2 -0
  64. angr/engines/successors.py +13 -9
  65. angr/engines/vex/claripy/datalayer.py +1 -1
  66. angr/engines/vex/claripy/irop.py +1 -1
  67. angr/engines/vex/light/slicing.py +2 -2
  68. angr/exploration_techniques/__init__.py +1 -124
  69. angr/exploration_techniques/base.py +126 -0
  70. angr/exploration_techniques/bucketizer.py +1 -1
  71. angr/exploration_techniques/dfs.py +3 -1
  72. angr/exploration_techniques/director.py +2 -3
  73. angr/exploration_techniques/driller_core.py +1 -1
  74. angr/exploration_techniques/explorer.py +4 -2
  75. angr/exploration_techniques/lengthlimiter.py +2 -1
  76. angr/exploration_techniques/local_loop_seer.py +2 -1
  77. angr/exploration_techniques/loop_seer.py +5 -5
  78. angr/exploration_techniques/manual_mergepoint.py +2 -1
  79. angr/exploration_techniques/memory_watcher.py +3 -1
  80. angr/exploration_techniques/oppologist.py +4 -5
  81. angr/exploration_techniques/slicecutor.py +4 -2
  82. angr/exploration_techniques/spiller.py +1 -1
  83. angr/exploration_techniques/stochastic.py +2 -1
  84. angr/exploration_techniques/stub_stasher.py +2 -1
  85. angr/exploration_techniques/suggestions.py +3 -1
  86. angr/exploration_techniques/symbion.py +3 -1
  87. angr/exploration_techniques/tech_builder.py +2 -1
  88. angr/exploration_techniques/threading.py +4 -7
  89. angr/exploration_techniques/timeout.py +4 -2
  90. angr/exploration_techniques/tracer.py +4 -3
  91. angr/exploration_techniques/unique.py +3 -2
  92. angr/exploration_techniques/veritesting.py +1 -1
  93. angr/knowledge_plugins/key_definitions/atoms.py +2 -2
  94. angr/knowledge_plugins/key_definitions/live_definitions.py +16 -13
  95. angr/knowledge_plugins/propagations/states.py +13 -8
  96. angr/knowledge_plugins/variables/variable_manager.py +23 -9
  97. angr/sim_manager.py +1 -3
  98. angr/sim_state.py +39 -41
  99. angr/sim_type.py +5 -0
  100. angr/sim_variable.py +29 -28
  101. angr/utils/bits.py +12 -0
  102. angr/utils/orderedset.py +4 -1
  103. angr/utils/ssa/__init__.py +21 -3
  104. {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/METADATA +6 -6
  105. {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/RECORD +109 -110
  106. angr/analyses/propagator/engine_ail.py +0 -1562
  107. angr/storage/memory_mixins/__init__.pyi +0 -48
  108. {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/LICENSE +0 -0
  109. {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/WHEEL +0 -0
  110. {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/entry_points.txt +0 -0
  111. {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
- SimEngineLightAILMixin,
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=None,
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 _handle_Stmt(self, stmt: Statement):
85
- new_stmt = super()._handle_Stmt(stmt)
86
- if new_stmt is not None:
87
- if type(new_stmt) is tuple:
88
- for stmt_ in new_stmt:
89
- self.state.append_statement(stmt_)
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(new_stmt)
92
- else:
93
- self.state.append_statement(stmt)
94
+ self.state.append_statement(block.statements[stmt_idx])
94
95
 
95
- def _handle_Assignment(self, stmt: Assignment) -> Assignment | tuple[Assignment, ...] | None:
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 _handle_Store(self, stmt: Store) -> Store | Assignment | None:
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 _handle_ConditionalJump(self, stmt: ConditionalJump) -> ConditionalJump | None:
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 _handle_Call(self, stmt: Call) -> Call | None:
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
- _handle_CallExpr = _handle_Call
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 _handle_Register(self, expr: Register) -> VirtualVariable | None:
271
+ def _handle_expr_Register(self, expr: Register) -> VirtualVariable | None:
272
272
  return self._replace_use_reg(expr)
273
273
 
274
- def _handle_Tmp(self, expr: Tmp) -> VirtualVariable | None:
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 _handle_Load(self, expr: Load) -> Load | VirtualVariable | None:
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 _handle_Convert(self, expr: Convert) -> Convert | None:
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 _handle_Const(self, expr: Const) -> None:
307
- return None
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 expr.ret_exprs:
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(expr.idx, new_ret_exprs, **expr.tags)
321
+ return Return(stmt.idx, new_ret_exprs, **stmt.tags)
331
322
  return None
332
323
 
333
- def _handle_BinaryOp(self, expr: BinaryOp) -> BinaryOp | None:
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 _handle_UnaryOp(self, expr) -> UnaryOp | None:
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 _handle_ITE(self, expr: ITE) -> ITE | None:
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 _handle_VEXCCallExpression(self, expr: VEXCCallExpression) -> VEXCCallExpression | None:
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 _handle_DirtyExpression(self, expr: DirtyExpression) -> DirtyExpression | None:
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 _handle_Dummy(self, expr) -> None:
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
- frontier |= frontiers[b]
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[None, NodeType, object, object]):
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.arch,
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
- tmps=self._tmps,
37
+ use_tmps=self._tmps,
40
38
  )
41
39
 
42
- self._visited_blocks: set[Any] = 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 Assignment, Call, Store, ConditionalJump
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 SimEngineLight, SimEngineLightAILMixin
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
- arch,
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
- tmps: bool = False,
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.tmps = tmps
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 _handle_Assignment(self, stmt: Assignment):
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 _handle_Store(self, stmt: Store):
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 _handle_ConditionalJump(self, stmt: ConditionalJump):
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 _handle_Call(self, stmt: Call):
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
- super()._ail_handle_Call(stmt)
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
- _handle_CallExpr = _handle_Call
118
+ _handle_stmt_Label = _handle_stmt_Dummy
108
119
 
109
- def _handle_Register(self, expr: Register):
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 _handle_Tmp(self, expr: Tmp):
122
- if self.tmps:
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 _handle_Cmp(self, expr: BinaryOp):
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
- _handle_CmpLE = _handle_Cmp
136
- _handle_CmpLT = _handle_Cmp
137
- _handle_CmpGE = _handle_Cmp
138
- _handle_CmpGT = _handle_Cmp
139
- _handle_CmpEQ = _handle_Cmp
140
- _handle_CmpNE = _handle_Cmp
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
- def _handle_UnaryOp(self, expr):
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 _handle_BinaryOp(self, expr):
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 _handle_ITE(self, expr: ITE):
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 _handle_VEXCCallExpression(self, expr: VEXCCallExpression):
234
+ def _handle_expr_VEXCCallExpression(self, expr: VEXCCallExpression):
160
235
  for operand in expr.operands:
161
236
  self._expr(operand)
162
237
 
163
- def _handle_DirtyExpression(self, expr: DirtyExpression):
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
- _handle_VirtualVariable = _handle_Dummy
175
- _handle_Phi = _handle_Dummy
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