angr 9.2.131__py3-none-manylinux2014_aarch64.whl → 9.2.133__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 (264) hide show
  1. angr/__init__.py +128 -128
  2. angr/analyses/__init__.py +38 -38
  3. angr/analyses/analysis.py +6 -2
  4. angr/analyses/backward_slice.py +3 -4
  5. angr/analyses/binary_optimizer.py +5 -12
  6. angr/analyses/bindiff.py +3 -6
  7. angr/analyses/calling_convention.py +3 -4
  8. angr/analyses/cfg/__init__.py +3 -3
  9. angr/analyses/cfg/cfg_base.py +1 -1
  10. angr/analyses/cfg/cfg_emulated.py +5 -5
  11. angr/analyses/cfg/cfg_fast.py +19 -17
  12. angr/analyses/cfg/indirect_jump_resolvers/__init__.py +5 -5
  13. angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +1 -1
  14. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +148 -101
  15. angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +1 -1
  16. angr/analyses/data_dep/__init__.py +4 -4
  17. angr/analyses/datagraph_meta.py +1 -1
  18. angr/analyses/ddg.py +16 -17
  19. angr/analyses/decompiler/__init__.py +12 -12
  20. angr/analyses/decompiler/ail_simplifier.py +24 -12
  21. angr/analyses/decompiler/block_similarity.py +2 -4
  22. angr/analyses/decompiler/block_simplifier.py +10 -21
  23. angr/analyses/decompiler/callsite_maker.py +1 -1
  24. angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +1 -1
  25. angr/analyses/decompiler/clinic.py +122 -41
  26. angr/analyses/decompiler/condition_processor.py +57 -39
  27. angr/analyses/decompiler/counters/__init__.py +3 -3
  28. angr/analyses/decompiler/decompilation_cache.py +7 -7
  29. angr/analyses/decompiler/dephication/__init__.py +1 -1
  30. angr/analyses/decompiler/dephication/graph_rewriting.py +1 -1
  31. angr/analyses/decompiler/dephication/graph_vvar_mapping.py +11 -3
  32. angr/analyses/decompiler/dephication/rewriting_engine.py +169 -45
  33. angr/analyses/decompiler/dephication/seqnode_dephication.py +5 -4
  34. angr/analyses/decompiler/expression_narrower.py +1 -1
  35. angr/analyses/decompiler/graph_region.py +8 -8
  36. angr/analyses/decompiler/optimization_passes/__init__.py +20 -20
  37. angr/analyses/decompiler/optimization_passes/const_derefs.py +1 -0
  38. angr/analyses/decompiler/optimization_passes/deadblock_remover.py +1 -2
  39. angr/analyses/decompiler/optimization_passes/div_simplifier.py +41 -16
  40. angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +8 -7
  41. angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py +1 -3
  42. angr/analyses/decompiler/optimization_passes/engine_base.py +262 -84
  43. angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +175 -39
  44. angr/analyses/decompiler/optimization_passes/ite_region_converter.py +2 -5
  45. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +5 -5
  46. angr/analyses/decompiler/optimization_passes/mod_simplifier.py +12 -3
  47. angr/analyses/decompiler/optimization_passes/optimization_pass.py +42 -19
  48. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +9 -5
  49. angr/analyses/decompiler/peephole_optimizations/__init__.py +1 -1
  50. angr/analyses/decompiler/peephole_optimizations/base.py +6 -6
  51. angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +2 -0
  52. angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +1 -1
  53. angr/analyses/decompiler/presets/__init__.py +1 -1
  54. angr/analyses/decompiler/region_simplifiers/expr_folding.py +3 -3
  55. angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +8 -12
  56. angr/analyses/decompiler/ssailification/rewriting.py +1 -2
  57. angr/analyses/decompiler/ssailification/rewriting_engine.py +139 -56
  58. angr/analyses/decompiler/ssailification/ssailification.py +2 -1
  59. angr/analyses/decompiler/ssailification/traversal.py +4 -6
  60. angr/analyses/decompiler/ssailification/traversal_engine.py +125 -42
  61. angr/analyses/decompiler/structured_codegen/__init__.py +5 -5
  62. angr/analyses/decompiler/structured_codegen/base.py +3 -3
  63. angr/analyses/decompiler/structured_codegen/c.py +39 -40
  64. angr/analyses/decompiler/structuring/__init__.py +3 -3
  65. angr/analyses/decompiler/structuring/phoenix.py +45 -29
  66. angr/analyses/decompiler/structuring/structurer_base.py +2 -2
  67. angr/analyses/decompiler/structuring/structurer_nodes.py +23 -14
  68. angr/analyses/deobfuscator/__init__.py +3 -3
  69. angr/analyses/deobfuscator/irsb_reg_collector.py +29 -60
  70. angr/analyses/deobfuscator/string_obf_finder.py +2 -2
  71. angr/analyses/deobfuscator/string_obf_opt_passes.py +1 -1
  72. angr/analyses/disassembly.py +4 -4
  73. angr/analyses/forward_analysis/__init__.py +1 -1
  74. angr/analyses/forward_analysis/visitors/graph.py +6 -6
  75. angr/analyses/init_finder.py +47 -22
  76. angr/analyses/loop_analysis.py +1 -1
  77. angr/analyses/loopfinder.py +1 -1
  78. angr/analyses/propagator/engine_base.py +21 -14
  79. angr/analyses/propagator/engine_vex.py +149 -179
  80. angr/analyses/propagator/outdated_definition_walker.py +12 -6
  81. angr/analyses/propagator/propagator.py +10 -28
  82. angr/analyses/propagator/top_checker_mixin.py +211 -5
  83. angr/analyses/propagator/vex_vars.py +4 -4
  84. angr/analyses/reaching_definitions/__init__.py +9 -9
  85. angr/analyses/reaching_definitions/call_trace.py +2 -2
  86. angr/analyses/reaching_definitions/dep_graph.py +1 -1
  87. angr/analyses/reaching_definitions/engine_ail.py +304 -329
  88. angr/analyses/reaching_definitions/engine_vex.py +243 -229
  89. angr/analyses/reaching_definitions/function_handler.py +3 -3
  90. angr/analyses/reaching_definitions/function_handler_library/__init__.py +1 -1
  91. angr/analyses/reaching_definitions/rd_state.py +47 -42
  92. angr/analyses/reassembler.py +26 -31
  93. angr/analyses/s_liveness.py +8 -0
  94. angr/analyses/s_propagator.py +18 -3
  95. angr/analyses/s_reaching_definitions/s_rda_view.py +2 -5
  96. angr/analyses/s_reaching_definitions/s_reaching_definitions.py +9 -5
  97. angr/analyses/stack_pointer_tracker.py +4 -4
  98. angr/analyses/typehoon/simple_solver.py +14 -14
  99. angr/analyses/typehoon/translator.py +10 -2
  100. angr/analyses/typehoon/typeconsts.py +11 -3
  101. angr/analyses/typehoon/typevars.py +26 -26
  102. angr/analyses/unpacker/__init__.py +1 -1
  103. angr/analyses/variable_recovery/engine_ail.py +299 -259
  104. angr/analyses/variable_recovery/engine_base.py +138 -121
  105. angr/analyses/variable_recovery/engine_vex.py +175 -185
  106. angr/analyses/variable_recovery/irsb_scanner.py +49 -38
  107. angr/analyses/variable_recovery/variable_recovery.py +28 -5
  108. angr/analyses/variable_recovery/variable_recovery_base.py +33 -34
  109. angr/analyses/variable_recovery/variable_recovery_fast.py +4 -8
  110. angr/analyses/veritesting.py +2 -2
  111. angr/analyses/vfg.py +5 -5
  112. angr/analyses/xrefs.py +46 -19
  113. angr/angrdb/serializers/__init__.py +1 -1
  114. angr/annocfg.py +20 -15
  115. angr/blade.py +2 -2
  116. angr/block.py +20 -25
  117. angr/calling_conventions.py +12 -14
  118. angr/code_location.py +6 -10
  119. angr/codenode.py +3 -3
  120. angr/engines/__init__.py +12 -14
  121. angr/engines/engine.py +24 -61
  122. angr/engines/light/__init__.py +13 -5
  123. angr/engines/light/data.py +1 -1
  124. angr/engines/light/engine.py +1003 -1185
  125. angr/engines/pcode/__init__.py +1 -1
  126. angr/engines/pcode/behavior.py +1 -1
  127. angr/engines/pcode/cc.py +2 -0
  128. angr/engines/pcode/lifter.py +13 -15
  129. angr/engines/soot/expressions/__init__.py +12 -12
  130. angr/engines/soot/statements/__init__.py +6 -6
  131. angr/engines/soot/values/__init__.py +6 -6
  132. angr/engines/soot/values/arrayref.py +2 -2
  133. angr/engines/soot/values/constants.py +1 -1
  134. angr/engines/soot/values/instancefieldref.py +1 -1
  135. angr/engines/soot/values/paramref.py +1 -1
  136. angr/engines/soot/values/staticfieldref.py +1 -1
  137. angr/engines/successors.py +15 -14
  138. angr/engines/vex/__init__.py +5 -5
  139. angr/engines/vex/claripy/ccall.py +2 -2
  140. angr/engines/vex/claripy/datalayer.py +1 -1
  141. angr/engines/vex/claripy/irop.py +19 -19
  142. angr/engines/vex/heavy/__init__.py +2 -2
  143. angr/engines/vex/heavy/actions.py +1 -3
  144. angr/engines/vex/heavy/heavy.py +4 -6
  145. angr/engines/vex/lifter.py +2 -4
  146. angr/engines/vex/light/light.py +0 -2
  147. angr/engines/vex/light/slicing.py +5 -5
  148. angr/exploration_techniques/__init__.py +19 -142
  149. angr/exploration_techniques/base.py +126 -0
  150. angr/exploration_techniques/bucketizer.py +1 -1
  151. angr/exploration_techniques/dfs.py +3 -1
  152. angr/exploration_techniques/director.py +2 -3
  153. angr/exploration_techniques/driller_core.py +1 -1
  154. angr/exploration_techniques/explorer.py +4 -2
  155. angr/exploration_techniques/lengthlimiter.py +2 -1
  156. angr/exploration_techniques/local_loop_seer.py +2 -1
  157. angr/exploration_techniques/loop_seer.py +5 -5
  158. angr/exploration_techniques/manual_mergepoint.py +2 -1
  159. angr/exploration_techniques/memory_watcher.py +3 -1
  160. angr/exploration_techniques/oppologist.py +4 -5
  161. angr/exploration_techniques/slicecutor.py +4 -2
  162. angr/exploration_techniques/spiller.py +1 -1
  163. angr/exploration_techniques/stochastic.py +2 -1
  164. angr/exploration_techniques/stub_stasher.py +2 -1
  165. angr/exploration_techniques/suggestions.py +3 -1
  166. angr/exploration_techniques/symbion.py +3 -1
  167. angr/exploration_techniques/tech_builder.py +2 -1
  168. angr/exploration_techniques/threading.py +2 -11
  169. angr/exploration_techniques/timeout.py +4 -2
  170. angr/exploration_techniques/tracer.py +4 -3
  171. angr/exploration_techniques/unique.py +3 -2
  172. angr/exploration_techniques/veritesting.py +1 -1
  173. angr/factory.py +36 -6
  174. angr/keyed_region.py +4 -4
  175. angr/knowledge_base.py +1 -1
  176. angr/knowledge_plugins/__init__.py +11 -11
  177. angr/knowledge_plugins/cfg/__init__.py +5 -5
  178. angr/knowledge_plugins/cfg/cfg_manager.py +2 -2
  179. angr/knowledge_plugins/cfg/cfg_model.py +8 -8
  180. angr/knowledge_plugins/cfg/cfg_node.py +19 -19
  181. angr/knowledge_plugins/cfg/indirect_jump.py +6 -6
  182. angr/knowledge_plugins/cfg/memory_data.py +5 -7
  183. angr/knowledge_plugins/functions/function.py +48 -52
  184. angr/knowledge_plugins/functions/function_parser.py +4 -4
  185. angr/knowledge_plugins/key_definitions/__init__.py +3 -3
  186. angr/knowledge_plugins/key_definitions/atoms.py +8 -8
  187. angr/knowledge_plugins/key_definitions/definition.py +1 -1
  188. angr/knowledge_plugins/key_definitions/live_definitions.py +30 -27
  189. angr/knowledge_plugins/labels.py +1 -1
  190. angr/knowledge_plugins/propagations/__init__.py +1 -1
  191. angr/knowledge_plugins/propagations/prop_value.py +2 -2
  192. angr/knowledge_plugins/propagations/propagation_model.py +7 -8
  193. angr/knowledge_plugins/propagations/states.py +44 -39
  194. angr/knowledge_plugins/variables/variable_access.py +2 -2
  195. angr/knowledge_plugins/variables/variable_manager.py +24 -10
  196. angr/knowledge_plugins/xrefs/xref.py +5 -8
  197. angr/misc/__init__.py +4 -4
  198. angr/misc/hookset.py +4 -5
  199. angr/misc/loggers.py +2 -2
  200. angr/misc/telemetry.py +1 -1
  201. angr/procedures/__init__.py +1 -1
  202. angr/procedures/cgc/fdwait.py +2 -2
  203. angr/procedures/definitions/__init__.py +2 -2
  204. angr/procedures/definitions/linux_kernel.py +0 -1
  205. angr/procedures/definitions/parse_syscalls_from_local_system.py +1 -1
  206. angr/procedures/definitions/parse_win32json.py +0 -1
  207. angr/procedures/ntdll/exceptions.py +1 -1
  208. angr/procedures/stubs/format_parser.py +3 -3
  209. angr/procedures/win32/dynamic_loading.py +1 -1
  210. angr/protos/__init__.py +3 -3
  211. angr/sim_manager.py +3 -5
  212. angr/sim_state.py +40 -42
  213. angr/sim_state_options.py +3 -3
  214. angr/sim_type.py +15 -14
  215. angr/sim_variable.py +42 -45
  216. angr/simos/__init__.py +4 -4
  217. angr/simos/cgc.py +1 -1
  218. angr/simos/simos.py +1 -1
  219. angr/simos/userland.py +1 -1
  220. angr/slicer.py +4 -7
  221. angr/state_plugins/__init__.py +34 -34
  222. angr/state_plugins/callstack.py +5 -12
  223. angr/state_plugins/heap/__init__.py +2 -2
  224. angr/state_plugins/heap/heap_brk.py +2 -4
  225. angr/state_plugins/heap/heap_ptmalloc.py +1 -1
  226. angr/state_plugins/jni_references.py +3 -2
  227. angr/state_plugins/scratch.py +1 -1
  228. angr/state_plugins/sim_action.py +1 -4
  229. angr/state_plugins/sim_event.py +1 -1
  230. angr/state_plugins/solver.py +7 -9
  231. angr/state_plugins/uc_manager.py +1 -1
  232. angr/state_plugins/view.py +2 -2
  233. angr/storage/__init__.py +1 -1
  234. angr/storage/file.py +10 -10
  235. angr/storage/memory_mixins/__init__.py +46 -46
  236. angr/storage/memory_mixins/default_filler_mixin.py +1 -3
  237. angr/storage/memory_mixins/javavm_memory_mixin.py +2 -2
  238. angr/storage/memory_mixins/name_resolution_mixin.py +2 -2
  239. angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +1 -3
  240. angr/storage/memory_mixins/paged_memory/pages/__init__.py +6 -6
  241. angr/storage/memory_mixins/paged_memory/pages/list_page.py +1 -1
  242. angr/storage/memory_mixins/paged_memory/pages/multi_values.py +1 -1
  243. angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +1 -1
  244. angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +2 -4
  245. angr/storage/memory_mixins/regioned_memory/__init__.py +3 -3
  246. angr/storage/memory_mixins/regioned_memory/region_data.py +5 -5
  247. angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +7 -9
  248. angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +4 -4
  249. angr/storage/memory_object.py +4 -4
  250. angr/utils/__init__.py +3 -3
  251. angr/utils/bits.py +12 -0
  252. angr/utils/dynamic_dictlist.py +1 -1
  253. angr/utils/graph.py +1 -1
  254. angr/utils/orderedset.py +4 -1
  255. angr/utils/segment_list.py +2 -2
  256. angr/utils/ssa/__init__.py +33 -8
  257. {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/METADATA +6 -6
  258. {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/RECORD +262 -263
  259. angr/analyses/propagator/engine_ail.py +0 -1562
  260. angr/storage/memory_mixins/__init__.pyi +0 -48
  261. {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/LICENSE +0 -0
  262. {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/WHEEL +0 -0
  263. {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/entry_points.txt +0 -0
  264. {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/top_level.txt +0 -0
@@ -231,7 +231,7 @@ class StackCanarySimplifier(OptimizationPass):
231
231
  negated = False
232
232
  condition = stmt.condition
233
233
  if isinstance(condition, ailment.Expr.BinaryOp) and (
234
- not negated and condition.op == "CmpEQ" or negated and condition.op == "CmpNE"
234
+ (not negated and condition.op == "CmpEQ") or (negated and condition.op == "CmpNE")
235
235
  ):
236
236
  pass
237
237
  else:
@@ -255,8 +255,10 @@ class StackCanarySimplifier(OptimizationPass):
255
255
  op0 = op0_v
256
256
 
257
257
  if not (
258
- self._is_stack_canary_load_expr(op0, self.project.arch.bits, canary_value_stack_offset)
259
- and self._is_random_number_load_expr(op1, self.project.arch.get_register_offset("fs"))
258
+ (
259
+ self._is_stack_canary_load_expr(op0, self.project.arch.bits, canary_value_stack_offset)
260
+ and self._is_random_number_load_expr(op1, self.project.arch.get_register_offset("fs"))
261
+ )
260
262
  or (
261
263
  self._is_stack_canary_load_expr(op1, self.project.arch.bits, canary_value_stack_offset)
262
264
  and self._is_random_number_load_expr(op0, self.project.arch.get_register_offset("fs"))
@@ -270,8 +272,10 @@ class StackCanarySimplifier(OptimizationPass):
270
272
  ):
271
273
  # a == b
272
274
  if not (
273
- self._is_stack_canary_load_expr(expr0, self.project.arch.bits, canary_value_stack_offset)
274
- and self._is_random_number_load_expr(expr1, self.project.arch.get_register_offset("fs"))
275
+ (
276
+ self._is_stack_canary_load_expr(expr0, self.project.arch.bits, canary_value_stack_offset)
277
+ and self._is_random_number_load_expr(expr1, self.project.arch.get_register_offset("fs"))
278
+ )
275
279
  or (
276
280
  self._is_stack_canary_load_expr(expr1, self.project.arch.bits, canary_value_stack_offset)
277
281
  and self._is_random_number_load_expr(expr0, self.project.arch.get_register_offset("fs"))
@@ -111,7 +111,7 @@ EXPR_OPTS: list[type[PeepholeOptimizationExprBase]] = [
111
111
  ]
112
112
 
113
113
  __all__ = (
114
+ "EXPR_OPTS",
114
115
  "MULTI_STMT_OPTS",
115
116
  "STMT_OPTS",
116
- "EXPR_OPTS",
117
117
  )
@@ -12,9 +12,9 @@ class PeepholeOptimizationStmtBase:
12
12
  """
13
13
 
14
14
  __slots__ = (
15
- "project",
16
- "kb",
17
15
  "func_addr",
16
+ "kb",
17
+ "project",
18
18
  )
19
19
  project: Project | None
20
20
  kb: KnowledgeBase | None
@@ -39,9 +39,9 @@ class PeepholeOptimizationMultiStmtBase:
39
39
  """
40
40
 
41
41
  __slots__ = (
42
- "project",
43
- "kb",
44
42
  "func_addr",
43
+ "kb",
44
+ "project",
45
45
  )
46
46
  project: Project | None
47
47
  kb: KnowledgeBase | None
@@ -66,9 +66,9 @@ class PeepholeOptimizationExprBase:
66
66
  """
67
67
 
68
68
  __slots__ = (
69
- "project",
70
- "kb",
71
69
  "func_addr",
70
+ "kb",
71
+ "project",
72
72
  )
73
73
  project: Project | None
74
74
  kb: KnowledgeBase | None
@@ -22,6 +22,7 @@ class RemoveNoopConversions(PeepholeOptimizationExprBase):
22
22
  and expr.to_bits < expr.from_bits
23
23
  and expr.from_bits == inner.to_bits
24
24
  and expr.is_signed == inner.is_signed
25
+ and expr.from_type == expr.to_type == inner.from_type == inner.to_type == Convert.TYPE_INT
25
26
  ):
26
27
  # extension then truncation (e.g., 1->64->1) can be removed, but truncation then extension cannot be
27
28
  # removed (e.g., the high 32 bits must be removed during 64->32->64)
@@ -31,6 +32,7 @@ class RemoveNoopConversions(PeepholeOptimizationExprBase):
31
32
  and expr.from_bits == inner.to_bits
32
33
  and inner.to_bits <= inner.from_bits
33
34
  and expr.is_signed == inner.is_signed
35
+ and expr.from_type == expr.to_type == inner.from_type == inner.to_type == Convert.TYPE_INT
34
36
  ):
35
37
  # merging two truncations into one
36
38
  return Convert(
@@ -29,8 +29,8 @@ class RewriteBitExtractions(PeepholeOptimizationExprBase):
29
29
  return ITE(
30
30
  expr.idx,
31
31
  bitoffset2exprs[bit_offset],
32
- Const(None, None, 1, expr.bits),
33
32
  Const(None, None, 0, expr.bits),
33
+ Const(None, None, 1, expr.bits),
34
34
  **expr.tags,
35
35
  )
36
36
 
@@ -15,6 +15,6 @@ DECOMPILATION_PRESETS = {
15
15
 
16
16
 
17
17
  __all__ = (
18
- "DecompilationPreset",
19
18
  "DECOMPILATION_PRESETS",
19
+ "DecompilationPreset",
20
20
  )
@@ -63,8 +63,8 @@ class ExpressionLocation(LocationBase):
63
63
  __slots__ = (
64
64
  "block_addr",
65
65
  "block_idx",
66
- "stmt_idx",
67
66
  "expr_idx",
67
+ "stmt_idx",
68
68
  )
69
69
 
70
70
  def __init__(self, block_addr, block_idx, stmt_idx, expr_idx):
@@ -94,8 +94,8 @@ class ExpressionLocation(LocationBase):
94
94
 
95
95
  class ConditionLocation(LocationBase):
96
96
  __slots__ = (
97
- "node_addr",
98
97
  "case_idx",
98
+ "node_addr",
99
99
  )
100
100
 
101
101
  def __init__(self, cond_node_addr, case_idx: int | None = None):
@@ -171,8 +171,8 @@ class ExpressionUseFinder(AILBlockWalker):
171
171
  """
172
172
 
173
173
  __slots__ = (
174
- "uses",
175
174
  "has_load",
175
+ "uses",
176
176
  )
177
177
 
178
178
  def __init__(self):
@@ -39,11 +39,11 @@ class ConditionalRegion:
39
39
  """
40
40
 
41
41
  __slots__ = (
42
- "variable",
43
- "op",
44
- "value",
45
42
  "node",
43
+ "op",
46
44
  "parent",
45
+ "value",
46
+ "variable",
47
47
  )
48
48
 
49
49
  def __init__(self, variable, op: CmpOp, value: int, node: ConditionNode | ailment.Block, parent=None):
@@ -63,9 +63,9 @@ class SwitchCaseRegion:
63
63
  """
64
64
 
65
65
  __slots__ = (
66
- "variable",
67
66
  "node",
68
67
  "parent",
68
+ "variable",
69
69
  )
70
70
 
71
71
  def __init__(self, variable, node: SwitchCaseNode, parent=None):
@@ -195,18 +195,14 @@ def is_simple_jump_node(node, case_addrs, targets: set[int] | None = None) -> bo
195
195
  targets.add(stmt.target.value)
196
196
  elif isinstance(stmt, ailment.Stmt.ConditionalJump):
197
197
  ok = False
198
- if (
199
- stmt.true_target is None
200
- or isinstance(stmt.true_target, ailment.Expr.Const)
201
- and stmt.true_target.value in case_addrs
198
+ if stmt.true_target is None or (
199
+ isinstance(stmt.true_target, ailment.Expr.Const) and stmt.true_target.value in case_addrs
202
200
  ):
203
201
  ok = True
204
202
  if stmt.true_target is not None and targets is not None:
205
203
  targets.add(stmt.true_target.value)
206
- if (
207
- stmt.false_target is None
208
- or isinstance(stmt.false_target, ailment.Expr.Const)
209
- and stmt.false_target.value in case_addrs
204
+ if stmt.false_target is None or (
205
+ isinstance(stmt.false_target, ailment.Expr.Const) and stmt.false_target.value in case_addrs
210
206
  ):
211
207
  ok = True
212
208
  if stmt.false_target is not None and targets is not None:
@@ -56,8 +56,7 @@ class RewritingAnalysis(ForwardAnalysis[RewritingState, NodeType, object, object
56
56
  self._rewrite_tmps = rewrite_tmps
57
57
  self._ail_manager = ail_manager
58
58
  self._engine_ail = SimEngineSSARewriting(
59
- self.project.arch,
60
- project=self.project,
59
+ self.project,
61
60
  sp_tracker=sp_tracker,
62
61
  bp_as_gpr=bp_as_gpr,
63
62
  udef_to_phiid=self._udef_to_phiid,
@@ -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)
@@ -372,13 +362,13 @@ class SimEngineSSARewriting(
372
362
  return ITE(
373
363
  expr.idx,
374
364
  expr.cond if new_cond is None else new_cond,
375
- expr.iftrue if new_iftrue is None else new_iftrue,
376
365
  expr.iffalse if new_iffalse is None else new_iffalse,
366
+ expr.iftrue if new_iftrue is None else new_iftrue,
377
367
  **expr.tags,
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)
384
+ return None
385
+
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):
394
393
  return None
395
394
 
396
- def _handle_DirtyExpression(self, expr: DirtyExpression) -> DirtyExpression | None:
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