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
angr/annocfg.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
  from collections import defaultdict
3
3
  import logging
4
+ from typing import Literal
4
5
 
5
6
  import networkx
6
7
 
@@ -30,7 +31,7 @@ class AnnotatedCFG:
30
31
  self._cfg = None
31
32
  self._target = None
32
33
 
33
- self._run_statement_whitelist: dict[int, list[int] | bool] = defaultdict(list)
34
+ self._run_statement_whitelist: dict[int, list[int] | Literal[True]] = defaultdict(list)
34
35
  self._exit_taken = defaultdict(list)
35
36
  self._addr_to_run = {}
36
37
  self._addr_to_last_stmt_id = {}
@@ -76,6 +77,7 @@ class AnnotatedCFG:
76
77
 
77
78
  def get_addr(self, run):
78
79
  if isinstance(run, CFGNode):
80
+ assert isinstance(run.addr, int)
79
81
  return run.addr
80
82
  if type(run) is int:
81
83
  return run
@@ -87,17 +89,18 @@ class AnnotatedCFG:
87
89
 
88
90
  def add_statements_to_whitelist(self, block, stmt_ids):
89
91
  addr = self.get_addr(block)
90
- if type(stmt_ids) is bool:
92
+ if stmt_ids is True:
91
93
  if type(self._run_statement_whitelist[addr]) is list and self._run_statement_whitelist[addr]:
92
94
  raise Exception("WTF")
93
95
  self._run_statement_whitelist[addr] = stmt_ids
94
96
  elif -1 in stmt_ids:
95
97
  self._run_statement_whitelist[addr] = True
96
98
  else:
97
- self._run_statement_whitelist[addr].extend(stmt_ids)
98
- self._run_statement_whitelist[addr] = sorted(
99
- set(self._run_statement_whitelist[addr]), key=lambda v: v if type(v) is int else float("inf")
100
- )
99
+ whitelist_lst = self._run_statement_whitelist[addr]
100
+ assert whitelist_lst is not True
101
+ whitelist = set(whitelist_lst)
102
+ whitelist.update(stmt_ids)
103
+ self._run_statement_whitelist[addr] = sorted(whitelist)
101
104
 
102
105
  def add_exit_to_whitelist(self, run_from, run_to):
103
106
  addr_from = self.get_addr(run_from)
@@ -135,17 +138,18 @@ class AnnotatedCFG:
135
138
  return self._addr_to_run[addr]
136
139
  return None
137
140
 
138
- def get_whitelisted_statements(self, addr):
141
+ def get_whitelisted_statements(self, addr) -> list[int] | None:
139
142
  """
140
143
  :returns: True if all statements are whitelisted
141
144
  """
142
145
  if addr in self._run_statement_whitelist:
143
- if self._run_statement_whitelist[addr] is True:
146
+ whitelist = self._run_statement_whitelist[addr]
147
+ if whitelist is True:
144
148
  return None # This is the default value used to say
145
149
  # we execute all statements in this basic block. A
146
150
  # little weird...
147
151
 
148
- return self._run_statement_whitelist[addr]
152
+ return whitelist
149
153
 
150
154
  return []
151
155
 
@@ -166,12 +170,12 @@ class AnnotatedCFG:
166
170
  return self._addr_to_last_stmt_id[addr]
167
171
  if addr in self._run_statement_whitelist:
168
172
  # is the default exit there? it equals to a negative number (-2 by default) so `max()` won't work.
169
- if self._run_statement_whitelist[addr] is True or (
170
- isinstance(self._run_statement_whitelist[addr], list)
171
- and DEFAULT_STATEMENT in self._run_statement_whitelist[addr]
173
+ whitelist = self._run_statement_whitelist[addr]
174
+ if whitelist is True or (
175
+ isinstance(self._run_statement_whitelist[addr], list) and DEFAULT_STATEMENT in whitelist
172
176
  ):
173
177
  return DEFAULT_STATEMENT
174
- return max(self._run_statement_whitelist[addr], key=lambda v: v if type(v) is int else float("inf"))
178
+ return max(whitelist, key=lambda v: v if type(v) is int else float("inf"))
175
179
  return None
176
180
 
177
181
  def get_loops(self):
@@ -224,8 +228,8 @@ class AnnotatedCFG:
224
228
  statements = vex_block.statements
225
229
  whitelist = self.get_whitelisted_statements(irsb_addr)
226
230
  for i in range(len(statements)):
227
- line = "+" if whitelist is True or i in whitelist else "-"
228
- line += "[% 3d] " % i
231
+ line = "+" if whitelist is None or i in whitelist else "-"
232
+ line += f"[{i: 3d}] "
229
233
  # We cannot get data returned by pp(). WTF?
230
234
  print(line, end="")
231
235
  statements[i].pp()
@@ -301,6 +305,7 @@ class AnnotatedCFG:
301
305
 
302
306
  def _detect_loops(self):
303
307
  temp_graph = networkx.DiGraph()
308
+ assert self._cfg is not None
304
309
  for source, target_list in self._cfg._edge_map.items():
305
310
  for target in target_list:
306
311
  temp_graph.add_edge(source, target)
angr/blade.py CHANGED
@@ -144,13 +144,13 @@ class Blade:
144
144
  else:
145
145
  stmt_str = str(stmt)
146
146
 
147
- block_str += "%02s %02d | %s\n" % ("+" if i in included_stmts else " ", i, stmt_str)
147
+ block_str += f"{'+' if i in included_stmts else ' '} {i:02d} | {stmt_str}\n"
148
148
 
149
149
  block_str += " + " if default_exit_included else " "
150
150
  if isinstance(block.next, pyvex.IRExpr.Const):
151
151
  block_str += f"Next: {block.next.con.value:#x}\n"
152
152
  elif isinstance(block.next, pyvex.IRExpr.RdTmp):
153
- block_str += "Next: t%d\n" % block.next.tmp
153
+ block_str += f"Next: t{block.next.tmp}\n"
154
154
  else:
155
155
  block_str += f"Next: {block.next!s}\n"
156
156
 
angr/block.py CHANGED
@@ -13,12 +13,9 @@ except ImportError:
13
13
 
14
14
  from .protos import primitives_pb2 as pb2
15
15
  from .serializable import Serializable
16
- from .engines.vex import VEXLifter
17
16
 
18
17
  l = logging.getLogger(name=__name__)
19
18
 
20
- DEFAULT_VEX_ENGINE = VEXLifter(None) # this is only used when Block is not initialized with a project
21
-
22
19
 
23
20
  class DisassemblerBlock:
24
21
  """
@@ -26,7 +23,7 @@ class DisassemblerBlock:
26
23
  instructions
27
24
  """
28
25
 
29
- __slots__ = ["addr", "insns", "thumb", "arch"]
26
+ __slots__ = ["addr", "arch", "insns", "thumb"]
30
27
 
31
28
  def __init__(self, addr, insns, thumb, arch):
32
29
  self.addr = addr
@@ -38,7 +35,7 @@ class DisassemblerBlock:
38
35
  print(str(self))
39
36
 
40
37
  def __str__(self):
41
- return "\n".join(map(str, self.insns))
38
+ return "\n".join(str(x) for x in self.insns)
42
39
 
43
40
  def __repr__(self):
44
41
  return f"<DisassemblerBlock for {self.addr:#x}>"
@@ -125,25 +122,25 @@ class Block(Serializable):
125
122
  BLOCK_MAX_SIZE = 4096
126
123
 
127
124
  __slots__ = [
128
- "_project",
129
125
  "_bytes",
130
- "_vex",
131
- "thumb",
132
- "_disassembly",
133
126
  "_capstone",
134
- "addr",
135
- "size",
136
- "arch",
137
- "_instructions",
138
- "_instruction_addrs",
139
- "_opt_level",
140
- "_vex_nostmt",
141
127
  "_collect_data_refs",
142
- "_strict_block_end",
143
- "_cross_insn_opt",
144
- "_load_from_ro_regions",
145
128
  "_const_prop",
129
+ "_cross_insn_opt",
130
+ "_disassembly",
146
131
  "_initial_regs",
132
+ "_instruction_addrs",
133
+ "_instructions",
134
+ "_load_from_ro_regions",
135
+ "_opt_level",
136
+ "_project",
137
+ "_strict_block_end",
138
+ "_vex",
139
+ "_vex_nostmt",
140
+ "addr",
141
+ "arch",
142
+ "size",
143
+ "thumb",
147
144
  ]
148
145
 
149
146
  def __init__(
@@ -280,7 +277,7 @@ class Block(Serializable):
280
277
  self.size = vex_block.size
281
278
 
282
279
  def __repr__(self):
283
- return "<Block for %#x, %d bytes>" % (self.addr, self.size)
280
+ return f"<Block for {self.addr:#x}, {self.size} bytes>"
284
281
 
285
282
  def __getstate__(self):
286
283
  return {k: getattr(self, k) for k in self.__slots__ if k not in {"_capstone", "_disassembly", "_project"}}
@@ -326,8 +323,6 @@ class Block(Serializable):
326
323
 
327
324
  @property
328
325
  def _vex_engine(self):
329
- if self._project is None:
330
- return DEFAULT_VEX_ENGINE
331
326
  return self._project.factory.default_engine
332
327
 
333
328
  @property
@@ -436,7 +431,7 @@ class Block(Serializable):
436
431
  return self._bytes
437
432
 
438
433
  @property
439
- def instructions(self):
434
+ def instructions(self) -> int:
440
435
  if not self._instructions and self._vex is None:
441
436
  # initialize from VEX
442
437
  _ = self.vex
@@ -457,7 +452,7 @@ class Block(Serializable):
457
452
 
458
453
  @classmethod
459
454
  def _get_cmsg(cls):
460
- return pb2.Block()
455
+ return pb2.Block() # pylint: disable=no-member
461
456
 
462
457
  def serialize_to_cmessage(self):
463
458
  obj = self._get_cmsg()
@@ -490,7 +485,7 @@ class SootBlock:
490
485
  @property
491
486
  def _soot_engine(self):
492
487
  if self._project is None:
493
- raise Exception("SHIIIIIIIT")
488
+ assert False, "This should be unreachable"
494
489
  return self._project.factory.default_engine
495
490
 
496
491
  @property
@@ -229,7 +229,7 @@ class SimFunctionArgument:
229
229
  :ivar bool is_fp: Whether loads from this location should return a floating point bitvector
230
230
  """
231
231
 
232
- def __init__(self, size, is_fp=False):
232
+ def __init__(self, size: int, is_fp: bool = False):
233
233
  self.size = size
234
234
  self.is_fp = is_fp
235
235
 
@@ -243,12 +243,12 @@ class SimFunctionArgument:
243
243
  if not isinstance(value, claripy.ast.Base) and self.size is None:
244
244
  raise TypeError("Only claripy objects may be stored through SimFunctionArgument when size is not provided")
245
245
  if self.size is not None and isinstance(value, claripy.ast.Base) and self.size * arch.byte_width < value.length:
246
- raise TypeError("%s doesn't fit in an argument of size %d" % (value, self.size))
246
+ raise TypeError(f"{value} doesn't fit in an argument of size {self.size}")
247
247
  if isinstance(value, int):
248
248
  value = claripy.BVV(value, self.size * arch.byte_width)
249
249
  if isinstance(value, float):
250
250
  if self.size not in (4, 8):
251
- raise ValueError("What do I do with a float %d bytes long" % self.size)
251
+ raise ValueError(f"What do I do with a float {self.size} bytes long")
252
252
  value = claripy.FPV(value, claripy.FSORT_FLOAT if self.size == 4 else claripy.FSORT_DOUBLE)
253
253
  return value.raw_to_bv()
254
254
 
@@ -468,7 +468,7 @@ class SimArrayArg(SimFunctionArgument):
468
468
 
469
469
  def set_value(self, state, value, **kwargs):
470
470
  if len(value) != len(self.locs):
471
- raise TypeError("Expected %d elements, got %d" % (len(self.locs), len(value)))
471
+ raise TypeError(f"Expected {len(self.locs)} elements, got {len(value)}")
472
472
  for subvalue, setter in zip(value, self.locs):
473
473
  setter.set_value(state, subvalue, **kwargs)
474
474
 
@@ -505,10 +505,10 @@ class ArgSession:
505
505
  """
506
506
 
507
507
  __slots__ = (
508
+ "both_iter",
508
509
  "cc",
509
510
  "fp_iter",
510
511
  "int_iter",
511
- "both_iter",
512
512
  )
513
513
 
514
514
  def __init__(self, cc):
@@ -1027,7 +1027,7 @@ class SimCC:
1027
1027
  raise TypeError(f"Type mismatch: Expected {ty}, got {type(arg)} (i.e. struct)")
1028
1028
  if type(arg) is not SimStructValue:
1029
1029
  if len(arg) != len(ty.fields):
1030
- raise TypeError("Wrong number of fields in struct, expected %d got %d" % (len(ty.fields), len(arg)))
1030
+ raise TypeError(f"Wrong number of fields in struct, expected {len(ty.fields)} got {len(arg)}")
1031
1031
  arg = SimStructValue(ty, arg)
1032
1032
  return SimStructValue(
1033
1033
  ty, [SimCC._standardize_value(arg[field], ty.fields[field], state, alloc) for field in ty.fields]
@@ -1063,7 +1063,7 @@ class SimCC:
1063
1063
  if len(arg) != ty.size:
1064
1064
  if arg.concrete:
1065
1065
  return claripy.BVV(arg.concrete_value, ty.size)
1066
- raise TypeError("Type mismatch of symbolic data: expected %s, got %d bits" % (ty, len(arg)))
1066
+ raise TypeError(f"Type mismatch of symbolic data: expected {ty}, got {len(arg)} bits")
1067
1067
  return arg
1068
1068
  if isinstance(ty, (SimTypeFloat)):
1069
1069
  raise TypeError(
@@ -2272,7 +2272,7 @@ def default_cc( # pylint:disable=unused-argument
2272
2272
  platform: str | None = "Linux",
2273
2273
  language: str | None = None,
2274
2274
  syscall: bool = False,
2275
- **kwargs,
2275
+ default: type[SimCC] | None = None,
2276
2276
  ) -> type[SimCC] | None:
2277
2277
  """
2278
2278
  Return the default calling convention for a given architecture, platform, and language combination.
@@ -2281,19 +2281,19 @@ def default_cc( # pylint:disable=unused-argument
2281
2281
  :param platform: The platform name (e.g., "Linux" or "Win32").
2282
2282
  :param language: The programming language name (e.g., "go").
2283
2283
  :param syscall: Return syscall convention (True), or normal calling convention (False, default).
2284
+ :param default: The default calling convention to return if nothing fits.
2284
2285
  :return: A default calling convention class if we can find one for the architecture, platform, and
2285
- language combination, or None if nothing fits.
2286
+ language combination, or the default if nothing fits.
2286
2287
  """
2287
2288
 
2288
2289
  if platform is None:
2289
2290
  platform = "Linux"
2290
2291
 
2291
- default = kwargs.get("default", ...)
2292
2292
  cc_map = SYSCALL_CC if syscall else DEFAULT_CC
2293
2293
 
2294
2294
  if arch in cc_map:
2295
2295
  if platform not in cc_map[arch]:
2296
- if default is not ...:
2296
+ if default is not None:
2297
2297
  return default
2298
2298
  if "Linux" in cc_map[arch]:
2299
2299
  return cc_map[arch]["Linux"]
@@ -2301,9 +2301,7 @@ def default_cc( # pylint:disable=unused-argument
2301
2301
 
2302
2302
  alias = unify_arch_name(arch)
2303
2303
  if alias not in cc_map or platform not in cc_map[alias]:
2304
- if default is not ...:
2305
- return default
2306
- return None
2304
+ return default
2307
2305
  return cc_map[alias][platform]
2308
2306
 
2309
2307
 
angr/code_location.py CHANGED
@@ -9,14 +9,14 @@ class CodeLocation:
9
9
  """
10
10
 
11
11
  __slots__ = (
12
+ "_hash",
12
13
  "block_addr",
13
- "stmt_idx",
14
- "sim_procedure",
15
- "ins_addr",
14
+ "block_idx",
16
15
  "context",
17
16
  "info",
18
- "block_idx",
19
- "_hash",
17
+ "ins_addr",
18
+ "sim_procedure",
19
+ "stmt_idx",
20
20
  )
21
21
 
22
22
  def __init__(
@@ -65,11 +65,7 @@ class CodeLocation:
65
65
  self.block_addr,
66
66
  )
67
67
  else:
68
- s = "<%s%#x[%d]" % (
69
- (f"{self.ins_addr:#x} id=") if self.ins_addr else "",
70
- self.block_addr,
71
- self.stmt_idx,
72
- )
68
+ s = f"<{(f'{self.ins_addr:#x} id=') if self.ins_addr else ''}{self.block_addr:#x}[{self.stmt_idx}]"
73
69
 
74
70
  if self.context is None:
75
71
  s += " contextless"
angr/codenode.py CHANGED
@@ -11,7 +11,7 @@ def repr_addr(addr):
11
11
 
12
12
 
13
13
  class CodeNode:
14
- __slots__ = ["addr", "size", "_graph", "thumb", "_hash"]
14
+ __slots__ = ["_graph", "_hash", "addr", "size", "thumb"]
15
15
 
16
16
  def __init__(self, addr: int, size: int, graph=None, thumb=False):
17
17
  self.addr: int = addr
@@ -75,7 +75,7 @@ class BlockNode(CodeNode):
75
75
  self.bytestr = bytestr
76
76
 
77
77
  def __repr__(self):
78
- return "<BlockNode at %s (size %d)>" % (repr_addr(self.addr), self.size)
78
+ return f"<BlockNode at {repr_addr(self.addr)} (size {self.size})>"
79
79
 
80
80
  def __getstate__(self):
81
81
  return (self.addr, self.size, self.bytestr, self.thumb)
@@ -94,7 +94,7 @@ class SootBlockNode(BlockNode):
94
94
  assert (stmts is None and size == 0) or (size == len(stmts))
95
95
 
96
96
  def __repr__(self):
97
- return "<SootBlockNode at %s (%d statements)>" % (repr_addr(self.addr), self.size)
97
+ return f"<SootBlockNode at {repr_addr(self.addr)} ({self.size} statements)>"
98
98
 
99
99
  def __getstate__(self):
100
100
  return self.addr, self.size, self.stmts
angr/engines/__init__.py CHANGED
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from .successors import SimSuccessors
4
- from .engine import SimEngine, SuccessorsMixin, TLSMixin
4
+ from .engine import SimEngine, SuccessorsMixin
5
5
 
6
6
  from .vex import HeavyVEXMixin, TrackActionsMixin, SimInspectMixin, HeavyResilienceMixin, SuperFastpathMixin
7
7
  from .procedure import ProcedureMixin, ProcedureEngine
@@ -26,29 +26,27 @@ class UberEngine(
26
26
  HeavyResilienceMixin,
27
27
  SootMixin,
28
28
  HeavyVEXMixin,
29
- TLSMixin,
30
29
  ):
31
30
  pass
32
31
 
33
32
 
34
33
  __all__ = [
35
- "SimSuccessors",
36
- "SimEngine",
37
- "SuccessorsMixin",
38
- "TLSMixin",
39
- "HeavyVEXMixin",
40
- "TrackActionsMixin",
41
- "SimInspectMixin",
42
34
  "HeavyResilienceMixin",
43
- "SuperFastpathMixin",
44
- "ProcedureMixin",
35
+ "HeavyVEXMixin",
36
+ "HooksMixin",
45
37
  "ProcedureEngine",
46
- "SimEngineUnicorn",
38
+ "ProcedureMixin",
39
+ "SimEngine",
40
+ "SimEngineConcrete",
47
41
  "SimEngineFailure",
48
42
  "SimEngineSyscall",
49
- "SimEngineConcrete",
50
- "HooksMixin",
43
+ "SimEngineUnicorn",
44
+ "SimInspectMixin",
45
+ "SimSuccessors",
51
46
  "SootMixin",
47
+ "SuccessorsMixin",
48
+ "SuperFastpathMixin",
49
+ "TrackActionsMixin",
52
50
  "UberEngine",
53
51
  ]
54
52
 
angr/engines/engine.py CHANGED
@@ -1,51 +1,57 @@
1
- # pylint: disable=no-self-use,unused-private-member
2
1
  from __future__ import annotations
3
2
 
3
+ from typing import Generic, TypeVar
4
4
  import abc
5
5
  import logging
6
- import threading
7
6
 
7
+ import claripy
8
8
  from archinfo.arch_soot import SootAddressDescriptor
9
9
 
10
10
  import angr
11
+ from angr.sim_state import SimState
11
12
  from angr import sim_options as o
12
13
  from angr.errors import SimException
13
14
  from angr.state_plugins.inspect import BP_AFTER, BP_BEFORE
14
-
15
15
  from .successors import SimSuccessors
16
16
 
17
+
17
18
  l = logging.getLogger(name=__name__)
18
19
 
19
20
 
20
- class SimEngineBase:
21
+ StateType = TypeVar("StateType")
22
+ ResultType = TypeVar("ResultType")
23
+ DataType_co = TypeVar("DataType_co", covariant=True)
24
+ HeavyState = SimState[int | SootAddressDescriptor, claripy.ast.BV | SootAddressDescriptor]
25
+
26
+
27
+ class SimEngineBase(Generic[StateType]):
21
28
  """
22
29
  Even more basey of a base class for SimEngine. Used as a base by mixins which want access to the project but for
23
30
  which having method `process` (contained in `SimEngine`) doesn't make sense
24
31
  """
25
32
 
26
- def __init__(self, project=None, **kwargs):
33
+ state: StateType
34
+
35
+ def __init__(self, project: angr.Project, **kwargs):
27
36
  if kwargs:
28
37
  raise TypeError("Unused initializer args: " + ", ".join(kwargs.keys()))
29
- self.project: angr.Project | None = project
30
- self.state = None
31
-
32
- __tls = ("state",)
38
+ self.project = project
39
+ self.arch = self.project.arch
33
40
 
34
41
  def __getstate__(self):
35
42
  return (self.project,)
36
43
 
37
44
  def __setstate__(self, state):
38
45
  self.project = state[0]
39
- self.state = None
40
46
 
41
47
 
42
- class SimEngine(SimEngineBase, metaclass=abc.ABCMeta):
48
+ class SimEngine(Generic[StateType, ResultType], SimEngineBase[StateType], metaclass=abc.ABCMeta):
43
49
  """
44
50
  A SimEngine is a class which understands how to perform execution on a state. This is a base class.
45
51
  """
46
52
 
47
53
  @abc.abstractmethod
48
- def process(self, state, **kwargs):
54
+ def process(self, state: StateType, **kwargs) -> ResultType:
49
55
  """
50
56
  The main entry point for an engine. Should take a state and return a result.
51
57
 
@@ -54,51 +60,7 @@ class SimEngine(SimEngineBase, metaclass=abc.ABCMeta):
54
60
  """
55
61
 
56
62
 
57
- class TLSMixin:
58
- """
59
- Mix this class into any class that defines __tls to make all of the attributes named in that list into
60
- thread-local properties.
61
-
62
- MAGIC MAGIC MAGIC
63
- """
64
-
65
- def __new__(cls, *args, **kwargs): # pylint:disable=unused-argument
66
- obj = super().__new__(cls)
67
- obj.__local = threading.local()
68
- return obj
69
-
70
- def __init_subclass__(cls, **kwargs):
71
- super().__init_subclass__(**kwargs)
72
-
73
- for subcls in cls.mro():
74
- for attr in subcls.__dict__.get(f"_{subcls.__name__}__tls", ()):
75
- if attr.startswith("__"):
76
- attr = f"_{subcls.__name__}{attr}"
77
-
78
- if hasattr(cls, attr):
79
- if type(getattr(cls, attr, None)) is not TLSProperty:
80
- raise Exception(f"Programming error: {attr} is both in __tls and __class__")
81
- else:
82
- setattr(cls, attr, TLSProperty(attr))
83
-
84
-
85
- class TLSProperty: # pylint:disable=missing-class-docstring
86
- def __init__(self, name):
87
- self.name = name
88
-
89
- def __get__(self, instance, owner):
90
- if instance is None:
91
- return self
92
- return getattr(instance._TLSMixin__local, self.name)
93
-
94
- def __set__(self, instance, value):
95
- setattr(instance._TLSMixin__local, self.name, value)
96
-
97
- def __delete__(self, instance):
98
- delattr(instance._TLSMixin__local, self.name)
99
-
100
-
101
- class SuccessorsMixin(SimEngine):
63
+ class SuccessorsMixin(SimEngine[HeavyState, SimSuccessors]):
102
64
  """
103
65
  A mixin for SimEngine which implements ``process`` to perform common operations related to symbolic execution
104
66
  and dispatches to a ``process_successors`` method to fill a SimSuccessors object with the results.
@@ -109,9 +71,7 @@ class SuccessorsMixin(SimEngine):
109
71
 
110
72
  self.successors: SimSuccessors | None = None
111
73
 
112
- __tls = ("successors",)
113
-
114
- def process(self, state, *args, **kwargs): # pylint:disable=unused-argument
74
+ def process(self, state: HeavyState, **kwargs) -> SimSuccessors: # pylint:disable=unused-argument
115
75
  """
116
76
  Perform execution with a state.
117
77
 
@@ -148,6 +108,7 @@ class SuccessorsMixin(SimEngine):
148
108
  new_state.register_plugin("history", old_state.history.make_child())
149
109
  new_state.history.recent_bbl_addrs.append(addr)
150
110
  if new_state.arch.unicorn_support:
111
+ assert isinstance(addr, int)
151
112
  new_state.scratch.executed_pages_set = {addr & ~0xFFF}
152
113
 
153
114
  self.successors = SimSuccessors(addr, old_state)
@@ -161,10 +122,12 @@ class SuccessorsMixin(SimEngine):
161
122
  except SimException as e:
162
123
  if o.EXCEPTION_HANDLING not in old_state.options:
163
124
  raise
125
+ assert old_state.project is not None
164
126
  old_state.project.simos.handle_exception(self.successors, self, e)
165
127
 
166
128
  new_state._inspect("engine_process", when=BP_AFTER, sim_successors=self.successors, address=addr)
167
129
  self.successors = new_state._inspect_getattr("sim_successors", self.successors)
130
+ assert self.successors is not None
168
131
 
169
132
  # downsizing
170
133
  if new_state.supports_inspect:
@@ -183,7 +146,7 @@ class SuccessorsMixin(SimEngine):
183
146
 
184
147
  return self.successors
185
148
 
186
- def process_successors(self, successors, **kwargs): # pylint:disable=unused-argument
149
+ def process_successors(self, successors, **kwargs): # pylint:disable=unused-argument,no-self-use
187
150
  """
188
151
  Implement this function to fill out the SimSuccessors object with the results of stepping state.
189
152
 
@@ -1,15 +1,23 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from .data import ArithmeticExpression, SpOffset, RegisterOffset
4
- from .engine import SimEngineLight, SimEngineLightVEXMixin, SimEngineLightAILMixin, SimEngineLightVEX, SimEngineLightAIL
4
+ from .engine import (
5
+ SimEngineLight,
6
+ SimEngineLightVEX,
7
+ SimEngineLightAIL,
8
+ SimEngineNostmtVEX,
9
+ SimEngineNostmtAIL,
10
+ SimEngineNoexprAIL,
11
+ )
5
12
 
6
13
  __all__ = (
7
14
  "ArithmeticExpression",
8
- "SpOffset",
9
15
  "RegisterOffset",
10
16
  "SimEngineLight",
11
- "SimEngineLightVEXMixin",
12
- "SimEngineLightAILMixin",
13
- "SimEngineLightVEX",
14
17
  "SimEngineLightAIL",
18
+ "SimEngineLightVEX",
19
+ "SimEngineNoexprAIL",
20
+ "SimEngineNostmtAIL",
21
+ "SimEngineNostmtVEX",
22
+ "SpOffset",
15
23
  )
@@ -332,8 +332,8 @@ class ArithmeticExpression:
332
332
  class RegisterOffset:
333
333
  __slots__ = (
334
334
  "_bits",
335
- "reg",
336
335
  "offset",
336
+ "reg",
337
337
  )
338
338
 
339
339
  def __init__(self, bits, reg, offset):