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
@@ -306,7 +306,8 @@ class PhoenixStructurer(StructurerBase):
306
306
  and isinstance(head_block.nodes[0], Block)
307
307
  and head_block.nodes[0].statements
308
308
  and isinstance(first_nonlabel_nonphi_statement(head_block.nodes[0]), ConditionalJump)
309
- or isinstance(head_block, Block)
309
+ ) or (
310
+ isinstance(head_block, Block)
310
311
  and head_block.statements
311
312
  and isinstance(first_nonlabel_nonphi_statement(head_block), ConditionalJump)
312
313
  ):
@@ -1569,6 +1570,15 @@ class PhoenixStructurer(StructurerBase):
1569
1570
 
1570
1571
  return case_and_entry_addrs
1571
1572
 
1573
+ def _is_switch_cases_address_loaded_from_memory_head_or_jumpnode(self, graph, node) -> bool:
1574
+ jump_tables = self.kb.cfgs["CFGFast"].jump_tables
1575
+ if node.addr in jump_tables:
1576
+ return True
1577
+ for succ in graph.successors(node):
1578
+ if succ.addr in jump_tables:
1579
+ return True
1580
+ return node in self.switch_case_known_heads
1581
+
1572
1582
  # other acyclic schemas
1573
1583
 
1574
1584
  def _match_acyclic_sequence(self, graph, full_graph, start_node) -> bool:
@@ -1578,14 +1588,12 @@ class PhoenixStructurer(StructurerBase):
1578
1588
  succs = list(graph.successors(start_node))
1579
1589
  if len(succs) == 1:
1580
1590
  end_node = succs[0]
1581
- jump_tables = self.kb.cfgs["CFGFast"].jump_tables
1582
1591
  if (
1583
1592
  full_graph.out_degree[start_node] == 1
1584
1593
  and full_graph.in_degree[end_node] == 1
1585
1594
  and not full_graph.has_edge(end_node, start_node)
1586
- and end_node.addr not in jump_tables
1587
- and end_node not in self.switch_case_known_heads
1588
- and start_node not in self.switch_case_known_heads
1595
+ and not self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(full_graph, end_node)
1596
+ and not self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(full_graph, start_node)
1589
1597
  and end_node not in self.dowhile_known_tail_nodes
1590
1598
  ):
1591
1599
  # merge two blocks
@@ -1606,7 +1614,9 @@ class PhoenixStructurer(StructurerBase):
1606
1614
  succs = list(full_graph.successors(start_node))
1607
1615
  if len(succs) == 2:
1608
1616
  left, right = succs
1609
- if left in self.switch_case_known_heads or right in self.switch_case_known_heads:
1617
+ if self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(
1618
+ full_graph, left
1619
+ ) or self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(full_graph, right):
1610
1620
  # structure the switch-case first before we wrap them into an ITE. give up
1611
1621
  return False
1612
1622
 
@@ -1738,10 +1748,8 @@ class PhoenixStructurer(StructurerBase):
1738
1748
  and right not in graph
1739
1749
  and full_graph.in_degree[left] == 1
1740
1750
  and (
1741
- full_graph.in_degree[right] == 2
1742
- and left_succs == [right]
1743
- or full_graph.in_degree[right] == 1
1744
- and not left_succs
1751
+ (full_graph.in_degree[right] == 2 and left_succs == [right])
1752
+ or (full_graph.in_degree[right] == 1 and not left_succs)
1745
1753
  )
1746
1754
  ):
1747
1755
  edge_cond_left = self.cond_proc.recover_edge_condition(full_graph, start_node, left)
@@ -2039,7 +2047,9 @@ class PhoenixStructurer(StructurerBase):
2039
2047
  left, right = right, left
2040
2048
 
2041
2049
  # ensure left and right nodes are not the head of a switch-case construct
2042
- if left in self.switch_case_known_heads or right in self.switch_case_known_heads:
2050
+ if self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(
2051
+ full_graph, left
2052
+ ) or self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(full_graph, right):
2043
2053
  return None
2044
2054
 
2045
2055
  if (
@@ -2086,7 +2096,9 @@ class PhoenixStructurer(StructurerBase):
2086
2096
  left, right = right, left
2087
2097
 
2088
2098
  # ensure left and right nodes are not the head of a switch-case construct
2089
- if left in self.switch_case_known_heads or right in self.switch_case_known_heads:
2099
+ if self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(
2100
+ full_graph, left
2101
+ ) or self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(full_graph, right):
2090
2102
  return None
2091
2103
 
2092
2104
  if (
@@ -2127,7 +2139,9 @@ class PhoenixStructurer(StructurerBase):
2127
2139
  left, successor = successor, left
2128
2140
 
2129
2141
  # ensure left and successor nodes are not the head of a switch-case construct
2130
- if left in self.switch_case_known_heads or successor in self.switch_case_known_heads:
2142
+ if self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(
2143
+ full_graph, left
2144
+ ) or self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(full_graph, successor):
2131
2145
  return None
2132
2146
 
2133
2147
  if (
@@ -2175,7 +2189,9 @@ class PhoenixStructurer(StructurerBase):
2175
2189
  left, else_node = else_node, left
2176
2190
 
2177
2191
  # ensure left and else nodes are not the head of a switch-case construct
2178
- if left in self.switch_case_known_heads or else_node in self.switch_case_known_heads:
2192
+ if self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(
2193
+ full_graph, left
2194
+ ) or self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(full_graph, else_node):
2179
2195
  return None
2180
2196
 
2181
2197
  if (
@@ -2367,17 +2383,19 @@ class PhoenixStructurer(StructurerBase):
2367
2383
  and last_stmt.target.value == dst_addr
2368
2384
  and (dst_idx is ... or last_stmt.target_idx == dst_idx)
2369
2385
  )
2370
- or isinstance(last_stmt, ConditionalJump)
2371
- and (
2372
- (
2373
- isinstance(last_stmt.true_target, Const)
2374
- and last_stmt.true_target.value == dst_addr
2375
- and (dst_idx is ... or last_stmt.true_target_idx == dst_idx)
2376
- )
2377
- or (
2378
- isinstance(last_stmt.false_target, Const)
2379
- and last_stmt.false_target.value == dst_addr
2380
- and (dst_idx is ... or last_stmt.false_target_idx == dst_idx)
2386
+ or (
2387
+ isinstance(last_stmt, ConditionalJump)
2388
+ and (
2389
+ (
2390
+ isinstance(last_stmt.true_target, Const)
2391
+ and last_stmt.true_target.value == dst_addr
2392
+ and (dst_idx is ... or last_stmt.true_target_idx == dst_idx)
2393
+ )
2394
+ or (
2395
+ isinstance(last_stmt.false_target, Const)
2396
+ and last_stmt.false_target.value == dst_addr
2397
+ and (dst_idx is ... or last_stmt.false_target_idx == dst_idx)
2398
+ )
2381
2399
  )
2382
2400
  )
2383
2401
  or (
@@ -2414,10 +2432,8 @@ class PhoenixStructurer(StructurerBase):
2414
2432
 
2415
2433
  def _handle_BreakNode(break_node: BreakNode, parent=None, **kwargs): # pylint:disable=unused-argument
2416
2434
  walker.block_id += 1
2417
- if (
2418
- break_node.target == dst_addr
2419
- or isinstance(break_node.target, Const)
2420
- and break_node.target.value == dst_addr
2435
+ if break_node.target == dst_addr or (
2436
+ isinstance(break_node.target, Const) and break_node.target.value == dst_addr
2421
2437
  ):
2422
2438
  # FIXME: idx is ignored
2423
2439
  walker.parent_and_block.append((walker.block_id, parent, break_node))
@@ -150,7 +150,7 @@ class StructurerBase(Analysis):
150
150
  if isinstance(stmt, ailment.Stmt.Jump):
151
151
  targets = extract_jump_targets(stmt)
152
152
  for t in targets:
153
- if t in cases or default is not None and t == default.addr:
153
+ if t in cases or (default is not None and t == default.addr):
154
154
  # the node after switch cannot be one of the nodes in the switch-case construct
155
155
  continue
156
156
  goto_addrs[t] += 1
@@ -863,7 +863,7 @@ class StructurerBase(Analysis):
863
863
  addr = node_0.addr if node_0.addr is not None else node_1.addr
864
864
 
865
865
  # fix the last block of node_0 and remove useless goto statements
866
- if isinstance(node_0, SequenceNode) and node_0.nodes or isinstance(node_0, MultiNode) and node_0.nodes:
866
+ if (isinstance(node_0, SequenceNode) and node_0.nodes) or (isinstance(node_0, MultiNode) and node_0.nodes):
867
867
  last_node = node_0.nodes[-1]
868
868
  elif isinstance(node_0, ailment.Block):
869
869
  last_node = node_0
@@ -17,9 +17,9 @@ class EmptyBlockNotice(Exception):
17
17
 
18
18
  class MultiNode:
19
19
  __slots__ = (
20
- "nodes",
21
20
  "addr",
22
21
  "idx",
22
+ "nodes",
23
23
  )
24
24
 
25
25
  def __init__(self, nodes, addr=None, idx=None):
@@ -48,7 +48,7 @@ class MultiNode:
48
48
  addrs.append(node.addr)
49
49
  s = f": {min(addrs):#x}-{max(addrs):#x}"
50
50
 
51
- return "<MultiNode %#x of %d nodes%s>" % (self.addr, len(self.nodes), s)
51
+ return f"<MultiNode {self.addr:#x} of {len(self.nodes)} nodes{s}>"
52
52
 
53
53
  def __hash__(self):
54
54
  # changing self.nodes does not change the hash, which enables in-place editing
@@ -110,8 +110,8 @@ class SequenceNode(BaseNode):
110
110
 
111
111
  def __repr__(self):
112
112
  if self.addr is None:
113
- return "<SequenceNode, %d nodes>" % len(self.nodes)
114
- return "<SequenceNode %#x, %d nodes>" % (self.addr, len(self.nodes))
113
+ return f"<SequenceNode, {len(self.nodes)} nodes>"
114
+ return f"<SequenceNode {self.addr:#x}, {len(self.nodes)} nodes>"
115
115
 
116
116
  def add_node(self, node):
117
117
  self.nodes.append(node)
@@ -192,11 +192,11 @@ class CodeNode(BaseNode):
192
192
  class ConditionNode(BaseNode):
193
193
  __slots__ = (
194
194
  "addr",
195
+ "condition",
196
+ "false_node",
195
197
  "node",
196
198
  "reaching_condition",
197
- "condition",
198
199
  "true_node",
199
- "false_node",
200
200
  )
201
201
 
202
202
  def __init__(self, addr, reaching_condition, condition, true_node, false_node=None):
@@ -238,13 +238,13 @@ class CascadingConditionNode(BaseNode):
238
238
 
239
239
  class LoopNode(BaseNode):
240
240
  __slots__ = (
241
- "sort",
241
+ "_addr",
242
+ "_continue_addr",
242
243
  "condition",
243
- "sequence_node",
244
244
  "initializer",
245
245
  "iterator",
246
- "_addr",
247
- "_continue_addr",
246
+ "sequence_node",
247
+ "sort",
248
248
  )
249
249
 
250
250
  def __init__(
@@ -351,10 +351,10 @@ class ConditionalBreakNode(BreakNode):
351
351
 
352
352
  class SwitchCaseNode(BaseNode):
353
353
  __slots__ = (
354
- "switch_expr",
354
+ "addr",
355
355
  "cases",
356
356
  "default_node",
357
- "addr",
357
+ "switch_expr",
358
358
  )
359
359
 
360
360
  def __init__(self, switch_expr, cases: OrderedDict[int | tuple[int, ...], SequenceNode], default_node, addr=None):
@@ -370,7 +370,7 @@ class IncompleteSwitchCaseNode(BaseNode):
370
370
  into a SwitchCaseNode by the end of structuring. Only used in Phoenix structurer.
371
371
  """
372
372
 
373
- __slots__ = ("addr", "head", "cases")
373
+ __slots__ = ("addr", "cases", "head")
374
374
 
375
375
  def __init__(self, addr, head, cases: list):
376
376
  self.addr = addr
@@ -388,7 +388,7 @@ class IncompleteSwitchCaseHeadStatement(ailment.statement.Statement):
388
388
  Describes a switch-case head. This is only created by LoweredSwitchSimplifier.
389
389
  """
390
390
 
391
- __slots__ = ("addr", "switch_variable", "case_addrs", "_case_addrs_str")
391
+ __slots__ = ("_case_addrs_str", "addr", "case_addrs", "switch_variable")
392
392
 
393
393
  def __init__(self, idx, switch_variable, case_addrs, **kwargs):
394
394
  super().__init__(idx, **kwargs)
@@ -411,3 +411,12 @@ class IncompleteSwitchCaseHeadStatement(ailment.statement.Statement):
411
411
  return ailment.utils.stable_hash(
412
412
  (IncompleteSwitchCaseHeadStatement, self.idx, self.switch_variable, self._case_addrs_str)
413
413
  )
414
+
415
+ def replace(self, old_expr, new_expr):
416
+ return self
417
+
418
+ def likes(self, other):
419
+ return self == other
420
+
421
+ def matches(self, other):
422
+ return self == other
@@ -10,9 +10,9 @@ from .api_obf_peephole_optimizer import APIObfType1PeepholeOptimizer
10
10
 
11
11
 
12
12
  __all__ = (
13
- "StringObfuscationFinder",
13
+ "APIObfType1PeepholeOptimizer",
14
+ "APIObfuscationFinder",
14
15
  "StringObfType1PeepholeOptimizer",
15
16
  "StringObfType3Rewriter",
16
- "APIObfuscationFinder",
17
- "APIObfType1PeepholeOptimizer",
17
+ "StringObfuscationFinder",
18
18
  )
@@ -1,85 +1,54 @@
1
- # pylint:disable=no-self-use,unused-argument,attribute-defined-outside-init
1
+ # pylint:disable=no-self-use,unused-argument
2
2
  from __future__ import annotations
3
3
 
4
- import pyvex
4
+ from angr.engines.light import SimEngineNostmtVEX
5
5
 
6
- from angr.engines.light import SimEngineLightVEXMixin
7
6
 
8
-
9
- class IRSBRegisterCollector(SimEngineLightVEXMixin):
7
+ class IRSBRegisterCollector(SimEngineNostmtVEX[None, None, None]):
10
8
  """
11
9
  Scan the VEX IRSB to collect all registers that are read.
12
10
  """
13
11
 
14
- def __init__(self, block, *args, **kwargs):
12
+ def __init__(self, *args, **kwargs):
15
13
  super().__init__(*args, **kwargs)
16
14
 
17
- self.block = block
18
15
  self.reg_reads: set[tuple[int, int]] = set()
19
16
 
20
- def process(self):
21
- self.tmps = {}
22
- self.tyenv = self.block.vex.tyenv
23
-
24
- self._process_Stmt()
25
-
26
- self.stmt_idx = None
27
- self.ins_addr = None
28
-
29
- def _handle_Put(self, stmt):
30
- pass
31
-
32
- def _handle_Load(self, expr):
33
- pass
17
+ def _top(self, bits):
18
+ return None
34
19
 
35
- def _handle_Store(self, stmt):
36
- pass
20
+ def _is_top(self, expr):
21
+ return True
37
22
 
38
- def _handle_LoadG(self, stmt):
39
- pass
40
-
41
- def _handle_LLSC(self, stmt: pyvex.IRStmt.LLSC):
42
- pass
43
-
44
- def _handle_StoreG(self, stmt):
45
- pass
46
-
47
- def _handle_Get(self, expr: pyvex.IRExpr.Get):
23
+ def _handle_expr_Get(self, expr):
48
24
  self.reg_reads.add((expr.offset, expr.result_size(self.tyenv)))
49
25
 
50
- def _handle_RdTmp(self, expr):
51
- pass
52
-
53
- def _handle_Conversion(self, expr: pyvex.IRExpr.Unop):
54
- pass
26
+ def _handle_stmt_WrTmp(self, stmt):
27
+ self._expr(stmt.data)
55
28
 
56
- def _handle_16HLto32(self, expr):
57
- pass
29
+ def _handle_conversion(self, from_size, to_size, signed, operand):
30
+ return None
58
31
 
59
- def _handle_Cmp_v(self, expr, _vector_size, _vector_count):
60
- pass
32
+ def _process_block_end(self, stmt_result, whitelist):
33
+ return None
61
34
 
62
- _handle_CmpEQ_v = _handle_Cmp_v
63
- _handle_CmpNE_v = _handle_Cmp_v
64
- _handle_CmpLE_v = _handle_Cmp_v
65
- _handle_CmpLT_v = _handle_Cmp_v
66
- _handle_CmpGE_v = _handle_Cmp_v
67
- _handle_CmpGT_v = _handle_Cmp_v
35
+ def _handle_expr_VECRET(self, expr):
36
+ return None
68
37
 
69
- def _handle_ExpCmpNE64(self, expr):
70
- pass
38
+ def _handle_expr_GSPTR(self, expr):
39
+ return None
71
40
 
72
- def _handle_CCall(self, expr):
73
- pass
41
+ def _handle_expr_RdTmp(self, expr):
42
+ return None
74
43
 
75
- def _handle_function(self, func_addr):
76
- pass
44
+ def _handle_expr_GetI(self, expr):
45
+ return None
77
46
 
78
- def _handle_Unop(self, expr):
79
- pass
47
+ def _handle_expr_Load(self, expr):
48
+ return None
80
49
 
81
- def _handle_Binop(self, expr: pyvex.IRExpr.Binop):
82
- pass
50
+ def _handle_expr_ITE(self, expr):
51
+ return None
83
52
 
84
- def _handle_Triop(self, expr: pyvex.IRExpr.Triop):
85
- pass
53
+ def _handle_expr_Const(self, expr):
54
+ return None
@@ -669,8 +669,8 @@ class StringObfuscationFinder(Analysis):
669
669
  # take a look at the call-site block to see what registers are used
670
670
  reg_reads = set()
671
671
  for block_addr in blocks_at_callsite:
672
- reg_collector = IRSBRegisterCollector(self.project.factory.block(block_addr))
673
- reg_collector.process()
672
+ reg_collector = IRSBRegisterCollector(self.project)
673
+ reg_collector.process(state=None, block=self.project.factory.block(block_addr))
674
674
  reg_reads |= set(reg_collector.reg_reads)
675
675
 
676
676
  # run constant propagation to track constant registers
@@ -44,7 +44,7 @@ class StringObfType3Rewriter(OptimizationPass):
44
44
 
45
45
  @staticmethod
46
46
  def is_call_or_call_assignment(stmt) -> bool:
47
- return isinstance(stmt, Call) or isinstance(stmt, Assignment) and isinstance(stmt.src, Call)
47
+ return isinstance(stmt, Call) or (isinstance(stmt, Assignment) and isinstance(stmt.src, Call))
48
48
 
49
49
  def _analyze(self, cache=None):
50
50
 
@@ -119,9 +119,9 @@ class Label(DisassemblyPiece):
119
119
  class IROp(DisassemblyPiece):
120
120
  __slots__ = (
121
121
  "addr",
122
- "seq",
123
- "obj",
124
122
  "irsb",
123
+ "obj",
124
+ "seq",
125
125
  )
126
126
 
127
127
  addr: int
@@ -444,7 +444,7 @@ class SootExpressionTarget(SootExpression):
444
444
  self.target_stmt_idx = target_stmt_idx
445
445
 
446
446
  def _render(self, formatting=None):
447
- return ["Goto %d" % self.target_stmt_idx]
447
+ return [f"Goto {self.target_stmt_idx}"]
448
448
 
449
449
 
450
450
  class SootExpressionStaticFieldRef(SootExpression):
@@ -898,7 +898,7 @@ class Value(OperandPiece):
898
898
  return [f"{self.val:#x}"]
899
899
  if style[0] == "dec":
900
900
  if self.render_with_sign:
901
- return ["%+d" % self.val]
901
+ return [f"{self.val:+d}"]
902
902
  return [str(self.val)]
903
903
  if style[0] == "label":
904
904
  labeloffset = style[1]
@@ -4,8 +4,8 @@ from .forward_analysis import ForwardAnalysis
4
4
  from .visitors import CallGraphVisitor, FunctionGraphVisitor, LoopVisitor, SingleNodeGraphVisitor
5
5
 
6
6
  __all__ = (
7
- "ForwardAnalysis",
8
7
  "CallGraphVisitor",
8
+ "ForwardAnalysis",
9
9
  "FunctionGraphVisitor",
10
10
  "LoopVisitor",
11
11
  "SingleNodeGraphVisitor",
@@ -16,14 +16,14 @@ class GraphVisitor(Generic[NodeType]):
16
16
  """
17
17
 
18
18
  __slots__ = (
19
- "_sorted_nodes",
20
- "_worklist",
21
- "_nodes_set",
22
- "_node_to_index",
23
- "_reached_fixedpoint",
24
- "_back_edges_by_src",
25
19
  "_back_edges_by_dst",
20
+ "_back_edges_by_src",
21
+ "_node_to_index",
22
+ "_nodes_set",
26
23
  "_pending_nodes",
24
+ "_reached_fixedpoint",
25
+ "_sorted_nodes",
26
+ "_worklist",
27
27
  )
28
28
 
29
29
  def __init__(self):
@@ -1,33 +1,36 @@
1
1
  from __future__ import annotations
2
2
  from collections import defaultdict
3
+ from typing import cast
3
4
 
4
5
  from cle.loader import MetaELF
5
- from cle.backends import Section, Segment
6
6
  import pyvex
7
7
  import claripy
8
8
 
9
9
  from angr.analyses import visitors, ForwardAnalysis
10
- from angr.engines.light import SimEngineLight, SimEngineLightVEXMixin
10
+ from angr.code_location import CodeLocation
11
+ from angr.engines.light import SimEngineNostmtVEX
11
12
  from . import register_analysis, PropagatorAnalysis
12
13
  from .analysis import Analysis
13
14
  from .propagator.vex_vars import VEXTmp
14
15
 
15
16
 
16
- class SimEngineInitFinderVEX(
17
- SimEngineLightVEXMixin,
18
- SimEngineLight,
19
- ):
17
+ class SimEngineInitFinderVEX(SimEngineNostmtVEX[None, claripy.ast.Base | int | None, None]):
20
18
  """
21
19
  The VEX engine class for InitFinder.
22
20
  """
23
21
 
24
22
  def __init__(self, project, replacements, overlay, pointers_only=False):
25
- super().__init__()
26
- self.project = project
27
- self.replacements = replacements
23
+ super().__init__(project)
24
+ self.replacements: dict[CodeLocation, dict[int, claripy.ast.Base | int]] = replacements
28
25
  self.overlay = overlay
29
26
  self.pointers_only = pointers_only
30
27
 
28
+ def _top(self, bits):
29
+ return None
30
+
31
+ def _is_top(self, expr):
32
+ return expr is None
33
+
31
34
  #
32
35
  # Utils
33
36
  #
@@ -38,18 +41,19 @@ class SimEngineInitFinderVEX(
38
41
  return True
39
42
  return bool(isinstance(expr, int))
40
43
 
41
- def _is_addr_uninitialized(self, addr):
44
+ def _is_addr_uninitialized(self, addr: int | claripy.ast.Base):
42
45
  # is it writing to a global, uninitialized region?
43
46
 
44
47
  if isinstance(addr, claripy.ast.Base):
45
- addr = addr.args[0]
48
+ assert addr.op == "BVV"
49
+ addr = cast(int, addr.args[0])
46
50
 
47
51
  obj = self.project.loader.find_object_containing(addr)
48
52
  if obj is not None:
49
53
  if not obj.has_memory:
50
54
  # Objects without memory are definitely uninitialized
51
55
  return True
52
- section: Section = obj.find_section_containing(addr)
56
+ section = obj.find_section_containing(addr)
53
57
  if section is not None:
54
58
  return section.name in {
55
59
  ".bss",
@@ -58,7 +62,7 @@ class SimEngineInitFinderVEX(
58
62
  if isinstance(obj, MetaELF):
59
63
  # for ELFs, if p_memsz >= p_filesz, the extra bytes are considered NOBITS
60
64
  # https://docs.oracle.com/cd/E19120-01/open.solaris/819-0690/gjpww/index.html
61
- segment: Segment = obj.find_segment_containing(addr)
65
+ segment = obj.find_segment_containing(addr)
62
66
  if segment is not None and segment.memsize > segment.filesize:
63
67
  return segment.vaddr + segment.filesize <= addr < segment.vaddr + segment.memsize
64
68
  return False
@@ -71,6 +75,9 @@ class SimEngineInitFinderVEX(
71
75
  return self.project.loader.find_object_containing(addr) is not None
72
76
  return False
73
77
 
78
+ def _process_block_end(self, stmt_result, whitelist):
79
+ return None
80
+
74
81
  #
75
82
  # Statement handlers
76
83
  #
@@ -78,15 +85,15 @@ class SimEngineInitFinderVEX(
78
85
  def _handle_function(self, *args, **kwargs):
79
86
  pass
80
87
 
81
- def _handle_WrTmp(self, stmt):
88
+ def _handle_stmt_WrTmp(self, stmt):
82
89
  # Don't do anything since constant propagation has already processed it
83
90
  return
84
91
 
85
- def _handle_Put(self, stmt):
92
+ def _handle_stmt_Put(self, stmt):
86
93
  # Don't do anything since constant propagation has already processed it
87
94
  return
88
95
 
89
- def _handle_Store(self, stmt):
96
+ def _handle_stmt_Store(self, stmt):
90
97
  blockloc = self._codeloc(block_only=True)
91
98
 
92
99
  if type(stmt.addr) is pyvex.IRExpr.RdTmp:
@@ -107,7 +114,7 @@ class SimEngineInitFinderVEX(
107
114
  if not self.pointers_only or self._is_pointer(data_v):
108
115
  self.overlay.store(addr_v, data_v, endness=self.project.arch.memory_endness)
109
116
 
110
- def _handle_StoreG(self, stmt):
117
+ def _handle_stmt_StoreG(self, stmt):
111
118
  blockloc = self._codeloc(block_only=True)
112
119
  repl = self.replacements[blockloc]
113
120
 
@@ -144,16 +151,16 @@ class SimEngineInitFinderVEX(
144
151
  # Expression handlers
145
152
  #
146
153
 
147
- def _handle_Get(self, expr):
154
+ def _handle_expr_Get(self, expr):
148
155
  return None
149
156
 
150
- def _handle_Load(self, expr):
157
+ def _handle_expr_Load(self, expr):
151
158
  return None
152
159
 
153
- def _handle_LoadG(self, stmt):
160
+ def _handle_stmt_LoadG(self, stmt):
154
161
  return None
155
162
 
156
- def _handle_RdTmp(self, expr):
163
+ def _handle_expr_RdTmp(self, expr):
157
164
  blockloc = self._codeloc(block_only=True)
158
165
 
159
166
  tmp = VEXTmp(expr.tmp)
@@ -161,6 +168,24 @@ class SimEngineInitFinderVEX(
161
168
  return self.replacements[blockloc][tmp]
162
169
  return None
163
170
 
171
+ def _handle_expr_VECRET(self, expr):
172
+ return None
173
+
174
+ def _handle_expr_GSPTR(self, expr):
175
+ return None
176
+
177
+ def _handle_expr_GetI(self, expr):
178
+ return None
179
+
180
+ def _handle_expr_ITE(self, expr):
181
+ return None
182
+
183
+ def _handle_conversion(self, from_size, to_size, signed, operand):
184
+ return None
185
+
186
+ def _handle_expr_Const(self, expr):
187
+ return None
188
+
164
189
 
165
190
  class InitializationFinder(ForwardAnalysis, Analysis): # pylint:disable=abstract-method
166
191
  """
@@ -238,7 +263,7 @@ class InitializationFinder(ForwardAnalysis, Analysis): # pylint:disable=abstrac
238
263
  return None
239
264
 
240
265
  def _merge_states(self, node, *states):
241
- return None
266
+ return None, False
242
267
 
243
268
  def _run_on_node(self, node, state):
244
269
  block = self.project.factory.block(node.addr, node.size, opt_level=1, cross_insn_opt=False)
@@ -19,7 +19,7 @@ class VariableTypes:
19
19
 
20
20
 
21
21
  class AnnotatedVariable:
22
- __slots__ = ["variable", "type"]
22
+ __slots__ = ["type", "variable"]
23
23
 
24
24
  def __init__(self, variable, type_):
25
25
  self.variable = variable