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
@@ -28,7 +28,7 @@ class Loop:
28
28
  break
29
29
 
30
30
  def __repr__(self):
31
- return "<Loop @ %s, %d blocks>" % (self.entry.addr, len(self.body_nodes))
31
+ return f"<Loop @ {self.entry.addr}, {len(self.body_nodes)} blocks>"
32
32
 
33
33
 
34
34
  class LoopFinder(Analysis):
@@ -1,9 +1,14 @@
1
1
  from __future__ import annotations
2
- from typing import TYPE_CHECKING
2
+ from typing import TYPE_CHECKING, Generic
3
3
  import logging
4
4
 
5
+
6
+ from angr.engines.light.engine import BlockType, DataType_co, StateType
7
+
5
8
  from angr.engines.light import SimEngineLight
6
9
  from angr.errors import SimEngineError
10
+ from angr.project import Project
11
+ from angr.misc.testing import is_testing
7
12
 
8
13
  if TYPE_CHECKING:
9
14
  from angr.analyses.reaching_definitions.reaching_definitions import ReachingDefinitionsModel
@@ -11,22 +16,22 @@ if TYPE_CHECKING:
11
16
  l = logging.getLogger(name=__name__)
12
17
 
13
18
 
14
- class SimEnginePropagatorBase(SimEngineLight): # pylint:disable=abstract-method
19
+ class SimEnginePropagatorBaseMixin(
20
+ Generic[StateType, DataType_co, BlockType], SimEngineLight[StateType, DataType_co, BlockType, StateType]
21
+ ): # pylint:disable=abstract-method
15
22
  def __init__(
16
23
  self,
24
+ project: Project,
17
25
  stack_pointer_tracker=None,
18
- project=None,
19
26
  propagate_tmps=True,
20
- arch=None,
21
27
  reaching_definitions: ReachingDefinitionsModel | None = None,
22
28
  immediate_stmt_removal: bool = False,
23
29
  bp_as_gpr: bool = False,
24
30
  ):
25
- super().__init__()
31
+ super().__init__(project)
26
32
 
27
33
  # Used in the VEX engine
28
- self._project = project
29
- self.arch = arch
34
+ self.arch = project.arch
30
35
  self.base_state = None
31
36
  self._load_callback = None
32
37
  self._propagate_tmps: bool = propagate_tmps
@@ -40,15 +45,17 @@ class SimEnginePropagatorBase(SimEngineLight): # pylint:disable=abstract-method
40
45
 
41
46
  self._multi_occurrence_registers = None
42
47
 
43
- def process(self, state, *args, **kwargs):
44
- self.project = kwargs.pop("project", None)
45
- self.base_state = kwargs.pop("base_state", None)
46
- self._load_callback = kwargs.pop("load_callback", None)
48
+ def process(
49
+ self, state: StateType, *, block: BlockType | None = None, base_state=None, load_callback=None, **kwargs
50
+ ) -> StateType:
51
+ self.base_state = base_state
52
+ self._load_callback = load_callback
47
53
  try:
48
- self._process(state, None, block=kwargs.pop("block", None))
54
+ result_state = super().process(state, block=block, **kwargs)
49
55
  except SimEngineError as ex:
50
- if kwargs.pop("fail_fast", False) is True:
56
+ if kwargs.pop("fail_fast", is_testing) is True:
51
57
  raise ex
52
58
  l.error(ex, exc_info=True)
59
+ result_state = state
53
60
 
54
- return self.state
61
+ return result_state
@@ -1,39 +1,52 @@
1
+ # pylint: disable=missing-class-docstring
1
2
  from __future__ import annotations
2
- from typing import TYPE_CHECKING
3
+ from typing import cast
3
4
  import logging
4
5
 
5
6
  import claripy
6
7
  import pyvex
7
- import archinfo
8
8
 
9
+ from angr.engines.vex.claripy.datalayer import value
9
10
  from angr.knowledge_plugins.propagations.states import RegisterAnnotation, RegisterComparisonAnnotation
10
- from angr.engines.light import SimEngineLightVEXMixin
11
+ from angr.engines.light import SimEngineNostmtVEX
11
12
  from angr.calling_conventions import DEFAULT_CC, SYSCALL_CC, default_cc, SimRegArg
12
- from .values import Top, Bottom
13
- from .engine_base import SimEnginePropagatorBase
14
- from .top_checker_mixin import TopCheckerMixin
13
+ from angr.analyses.propagator.propagator import PropagatorVEXState
14
+ from angr.block import Block
15
+ from .engine_base import SimEnginePropagatorBaseMixin
16
+ from .top_checker_mixin import ClaripyDataVEXEngineMixin
15
17
  from .vex_vars import VEXReg, VEXTmp, VEXMemVar
16
18
 
17
- if TYPE_CHECKING:
18
- from angr.analyses.propagator.propagator import PropagatorVEXState
19
-
20
19
 
21
20
  _l = logging.getLogger(name=__name__)
22
21
 
22
+ dirty_handler = SimEngineNostmtVEX[PropagatorVEXState, claripy.ast.BV, PropagatorVEXState].dirty_handler
23
+ binop_handler = SimEngineNostmtVEX[PropagatorVEXState, claripy.ast.BV, PropagatorVEXState].binop_handler
24
+
23
25
 
24
26
  class SimEnginePropagatorVEX(
25
- TopCheckerMixin,
26
- SimEngineLightVEXMixin,
27
- SimEnginePropagatorBase,
27
+ ClaripyDataVEXEngineMixin[PropagatorVEXState, claripy.ast.BV, PropagatorVEXState, None],
28
+ SimEnginePropagatorBaseMixin[PropagatorVEXState, claripy.ast.BV, Block],
29
+ SimEngineNostmtVEX[PropagatorVEXState, claripy.ast.BV, PropagatorVEXState],
28
30
  ):
29
- state: PropagatorVEXState
31
+ @dirty_handler
32
+ def _handle_dirty_noop(self, expr):
33
+ if expr.tmp not in (-1, 0xFFFFFFFF):
34
+ self.tmps[expr.tmp] = self._top(pyvex.get_type_size(self.tyenv.lookup(expr.tmp)))
35
+
36
+ _handle_dirty_riscv_dirtyhelper_CSR_rw = _handle_dirty_noop
37
+ _handle_dirty_riscv_dirtyhelper_CSR_s = _handle_dirty_noop
38
+ _handle_dirty_riscv_dirtyhelper_CSR_c = _handle_dirty_noop
39
+ _handle_dirty_riscv_dirtyhelper_mret = _handle_dirty_noop
30
40
 
31
41
  #
32
42
  # Private methods
33
43
  #
34
44
 
35
- def _process_block_end(self):
36
- super()._process_block_end()
45
+ def _process_block_end(self, stmt_result, whitelist):
46
+ return self.state
47
+
48
+ def _process_block(self, whitelist=None):
49
+ result = super()._process_block(whitelist)
37
50
  if self.block.vex.jumpkind == "Ijk_Call" and self.arch.call_pushes_ret:
38
51
  # pop ret from the stack
39
52
  sp_offset = self.arch.sp_offset
@@ -43,56 +56,35 @@ class SimEnginePropagatorVEX(
43
56
 
44
57
  if self.block.vex.jumpkind == "Ijk_Call" or self.block.vex.jumpkind.startswith("Ijk_Sys"):
45
58
  self._handle_return_from_call()
59
+ return result
46
60
 
47
- def _allow_loading(self, addr, size):
48
- if type(addr) in (Top, Bottom):
61
+ def _allow_loading(self, addr: claripy.ast.BV, size):
62
+ if self._is_top(addr):
49
63
  return False
50
64
  if self._load_callback is None:
51
65
  return True
52
66
  return self._load_callback(addr, size)
53
67
 
54
- def _expr(self, expr):
55
- v = super()._expr(expr)
56
-
57
- if (
58
- v is not None
59
- and type(v) not in {Bottom, Top}
60
- and v is not expr
61
- and type(expr) is pyvex.IRExpr.Get
62
- and expr.offset
63
- not in (
64
- self.arch.sp_offset,
65
- self.arch.ip_offset,
66
- )
67
- ):
68
- # Record the replacement
69
- self.state.add_replacement(
70
- self._codeloc(block_only=False), VEXReg(expr.offset, expr.result_size(self.tyenv) // 8), v
71
- )
72
- return v
73
-
74
- def _load_data(self, addr, size, endness):
75
- if isinstance(addr, claripy.ast.Base):
76
- sp_offset = self.extract_offset_to_sp(addr)
77
- if sp_offset is not None:
78
- # Local variable
79
- return self.state.load_local_variable(sp_offset, size, endness)
80
- if addr.op == "BVV":
81
- addr = addr.args[0]
82
- # Try loading from the state
83
- if self._allow_loading(addr, size):
84
- if self.base_state is not None:
85
- _l.debug("Loading %d bytes from %x.", size, addr)
86
- data = self.base_state.memory.load(addr, size, endness=endness)
87
- if not data.symbolic:
88
- return data
89
- else:
90
- try:
91
- val = self.project.loader.memory.unpack_word(addr, size=size, endness=endness)
92
- return claripy.BVV(val, size * self.arch.byte_width)
93
- except KeyError:
94
- return None
95
- return None
68
+ def _load_data(self, addr: claripy.ast.BV, size, endness) -> claripy.ast.BV:
69
+ sp_offset = self.extract_offset_to_sp(addr)
70
+ if sp_offset is not None:
71
+ # Local variable
72
+ return self.state.load_local_variable(sp_offset, size, endness)
73
+ if addr.op == "BVV" and self._allow_loading(addr, size):
74
+ # Try loading from the state
75
+ addr_int = cast(int, addr.args[0])
76
+ if self.base_state is not None:
77
+ _l.debug("Loading %d bytes from %x.", size, addr_int)
78
+ data = self.base_state.memory.load(addr, size, endness=endness)
79
+ if not data.symbolic:
80
+ return data
81
+ else:
82
+ try:
83
+ val = self.project.loader.memory.unpack_word(addr_int, size=size, endness=endness)
84
+ return claripy.BVV(val, size * self.arch.byte_width)
85
+ except KeyError:
86
+ pass
87
+ return self._top(size * self.arch.byte_width)
96
88
 
97
89
  #
98
90
  # Function handlers
@@ -101,7 +93,7 @@ class SimEnginePropagatorVEX(
101
93
  def _handle_function(self, addr):
102
94
  if self.arch.name == "X86" and isinstance(addr, claripy.ast.Base) and addr.op == "BVV":
103
95
  try:
104
- b = self._project.loader.memory.load(addr.args[0], 4)
96
+ b = self.project.loader.memory.load(addr.args[0], 4)
105
97
  except KeyError:
106
98
  return
107
99
  except TypeError:
@@ -124,6 +116,7 @@ class SimEnginePropagatorVEX(
124
116
  platform=self.project.simos.name if self.project.simos is not None else None,
125
117
  syscall=syscall,
126
118
  ) # don't instantiate the class for speed
119
+ assert cc is not None
127
120
  if isinstance(cc.RETURN_VAL, SimRegArg):
128
121
  offset, size = self.arch.registers[cc.RETURN_VAL.reg_name]
129
122
  self.state.store_register(offset, size, self.state.top(size * self.arch.byte_width))
@@ -135,70 +128,48 @@ class SimEnginePropagatorVEX(
135
128
  #
136
129
  # VEX statement handlers
137
130
  #
138
- def _handle_Dirty(self, stmt):
139
- # For RISCV CSR and mret operations, the Dirty statement is skipped.
140
- if archinfo.arch_riscv64.is_riscv_arch(self.project.arch):
141
- helper = str(stmt.cee)
142
- if helper in (
143
- "riscv_dirtyhelper_CSR_rw",
144
- "riscv_dirtyhelper_CSR_s",
145
- "riscv_dirtyhelper_CSR_c",
146
- "riscv_dirtyhelper_mret",
147
- ):
148
- pass
149
- else:
150
- self.l.warning("Unimplemented Dirty node for current architecture.")
151
-
152
- def _handle_WrTmp(self, stmt):
153
- super()._handle_WrTmp(stmt)
154
131
 
132
+ def _handle_stmt_WrTmp(self, stmt):
133
+ self.tmps[stmt.tmp] = self._expr(stmt.data)
155
134
  if stmt.tmp in self.tmps:
156
135
  self.state.add_replacement(self._codeloc(block_only=True), VEXTmp(stmt.tmp), self.tmps[stmt.tmp])
157
136
 
158
- def _handle_Put(self, stmt):
137
+ def _handle_stmt_Put(self, stmt):
159
138
  size = stmt.data.result_size(self.tyenv) // self.arch.byte_width
160
139
  data = self._expr(stmt.data)
161
140
 
162
- if not (data is None or self.state.is_top(data)) or self.state._store_tops:
163
- if data is None:
164
- # make sure it's a top
165
- data = self.state.top(size * self.arch.byte_width)
141
+ if not self._is_top(data) or self.state._store_tops:
166
142
  self.state.store_register(stmt.offset, size, data)
167
143
  self.state.add_replacement(self._codeloc(block_only=False), VEXReg(stmt.offset, size), data)
168
144
 
169
- def _handle_PutI(self, stmt):
145
+ def _handle_stmt_PutI(self, stmt):
170
146
  self._expr(stmt.data)
171
147
 
172
- def _store_data(self, addr, data, size, endness):
173
- # pylint: disable=unused-argument,no-self-use
174
- if isinstance(addr, claripy.ast.Base):
175
- sp_offset = self.extract_offset_to_sp(addr)
176
- if sp_offset is not None:
177
- # Local variables
178
- self.state.store_local_variable(sp_offset, size, data, endness)
179
- elif addr.op == "BVV":
180
- # a memory address
181
- addr = addr.args[0]
182
- variable = VEXMemVar(addr, size)
183
- self.state.add_replacement(self._codeloc(block_only=False), variable, data)
184
-
185
- def _handle_Store(self, stmt):
186
- addr = self._expr(stmt.addr)
148
+ def _store_data(self, addr: claripy.ast.BV, data: claripy.ast.Bits, size: int, endness: str):
149
+ sp_offset = self.extract_offset_to_sp(addr)
150
+ if sp_offset is not None:
151
+ # Local variables
152
+ self.state.store_local_variable(sp_offset, size, data, endness)
153
+ elif addr.op == "BVV":
154
+ # a memory address
155
+ addr_int = cast(int, addr.args[0])
156
+ variable = VEXMemVar(addr_int, size)
157
+ self.state.add_replacement(self._codeloc(block_only=False), variable, data)
158
+
159
+ def _handle_stmt_Store(self, stmt):
160
+ addr = self._expr_bv(stmt.addr)
187
161
  if self.state.is_top(addr):
188
162
  return
189
163
  size = stmt.data.result_size(self.tyenv) // self.arch.byte_width
190
164
  data = self._expr(stmt.data)
191
165
 
192
- if not (data is None or self.state.is_top(data)) or self.state._store_tops:
193
- if data is None:
194
- # make sure it's a top
195
- data = self.state.top(size * self.arch.byte_width)
166
+ if not self.state.is_top(data) or self.state._store_tops:
196
167
  self._store_data(addr, data, size, self.arch.memory_endness)
197
168
 
198
- def _handle_LoadG(self, stmt):
169
+ def _handle_stmt_LoadG(self, stmt):
199
170
  guard = self._expr(stmt.guard)
200
171
  if guard is True:
201
- addr = self._expr(stmt.addr)
172
+ addr = self._expr_bv(stmt.addr)
202
173
  if addr is not None:
203
174
  self.tmps[stmt.dst] = self._load_data(
204
175
  addr, stmt.alt.result_size(self.tyenv) // 8, self.arch.memory_endness
@@ -207,121 +178,120 @@ class SimEnginePropagatorVEX(
207
178
  data = self._expr(stmt.alt)
208
179
  self.tmps[stmt.dst] = data
209
180
  else:
210
- self.tmps[stmt.dst] = None
181
+ self.tmps[stmt.dst] = self._top(stmt.alt.result_size(self.tyenv))
211
182
 
212
183
  # add replacement
213
- if self.tmps.get(stmt.dst):
184
+ if not self._is_top(self.tmps[stmt.dst]):
214
185
  self.state.add_replacement(self._codeloc(block_only=True), VEXTmp(stmt.dst), self.tmps[stmt.dst])
215
186
 
216
- def _handle_StoreG(self, stmt):
217
- guard = self._expr(stmt.guard)
187
+ def _handle_stmt_StoreG(self, stmt):
188
+ guard = self._expr_bv(stmt.guard)
218
189
  data = self._expr(stmt.data)
219
- if guard is True:
220
- addr = self._expr(stmt.addr)
221
- if addr is not None:
222
- self._store_data(addr, data, stmt.data.result_size(self.tyenv) // 8, self.arch.memory_endness)
223
-
224
- # elif guard is False:
225
- # data = self._expr(stmt.alt)
226
- # self.tmps[stmt.dst] = data
227
- # else:
228
- # self.tmps[stmt.dst] = None
190
+ if (guard != 0).is_true():
191
+ addr = self._expr_bv(stmt.addr)
192
+ self._store_data(addr, data, stmt.data.result_size(self.tyenv) // 8, self.arch.memory_endness)
229
193
 
230
- def _handle_LLSC(self, stmt: pyvex.IRStmt.LLSC):
194
+ def _handle_stmt_LLSC(self, stmt):
231
195
  if stmt.storedata is None:
232
196
  # load-link
233
- addr = self._expr(stmt.addr)
197
+ addr = self._expr_bv(stmt.addr)
234
198
  size = self.tyenv.sizeof(stmt.result) // self.arch.byte_width
235
199
  data = self._load_data(addr, size, stmt.endness)
236
- if data is not None:
237
- self.tmps[stmt.result] = data
200
+ self.tmps[stmt.result] = data
238
201
  if stmt.result in self.tmps:
239
202
  self.state.add_replacement(self._codeloc(block_only=True), VEXTmp(stmt.result), self.tmps[stmt.result])
240
203
  else:
241
204
  # store-conditional
242
205
  storedata = self._expr(stmt.storedata)
243
- if storedata is not None:
244
- addr = self._expr(stmt.addr)
245
- size = storedata.size() // self.arch.byte_width
246
- self._store_data(addr, storedata, size, stmt.endness)
206
+ addr = self._expr_bv(stmt.addr)
207
+ size = storedata.size() // self.arch.byte_width
208
+ self._store_data(addr, storedata, size, stmt.endness)
247
209
 
248
- self.tmps[stmt.result] = 1
210
+ self.tmps[stmt.result] = claripy.BVV(1, 1)
249
211
  self.state.add_replacement(self._codeloc(block_only=True), VEXTmp(stmt.result), self.tmps[stmt.result])
250
212
 
251
- def _handle_CmpEQ(self, expr):
252
- arg0, arg1 = self._expr(expr.args[0]), self._expr(expr.args[1])
253
- if arg1 is not None and arg1.concrete and arg0 is not None and len(arg0.annotations) == 1:
254
- anno = arg0.annotations[0]
213
+ @binop_handler
214
+ def _handle_binop_CmpEQ(self, expr):
215
+ lhs, rhs = self._expr(expr.args[0]), self._expr(expr.args[1])
216
+ if rhs.concrete and len(lhs.annotations) == 1:
217
+ anno = lhs.annotations[0]
218
+ if isinstance(anno, RegisterAnnotation):
219
+ cmp_anno = RegisterComparisonAnnotation(anno.offset, anno.size, "eq", rhs.concrete_value)
220
+ bits = pyvex.get_type_size(pyvex.get_op_retty(expr.op))
221
+ return self.state.top(bits).annotate(cmp_anno)
222
+ if lhs.concrete and len(rhs.annotations) == 1:
223
+ anno = rhs.annotations[0]
255
224
  if isinstance(anno, RegisterAnnotation):
256
- cmp_anno = RegisterComparisonAnnotation(anno.offset, anno.size, "eq", arg1.concrete_value)
257
- bits = expr.result_size(self.tyenv)
225
+ cmp_anno = RegisterComparisonAnnotation(anno.offset, anno.size, "eq", lhs.concrete_value)
226
+ bits = pyvex.get_type_size(pyvex.get_op_retty(expr.op))
258
227
  return self.state.top(bits).annotate(cmp_anno)
259
- return super()._handle_CmpEQ(expr)
228
+ return super()._handle_binop_CmpEQ(expr)
260
229
 
261
230
  #
262
231
  # Expression handlers
263
232
  #
264
233
 
265
- def _handle_Get(self, expr):
234
+ def _handle_expr_Get(self, expr):
266
235
  size = expr.result_size(self.tyenv) // self.arch.byte_width
267
- return self.state.load_register(expr.offset, size)
236
+ result = self.state.load_register(expr.offset, size)
237
+ if not self._is_top(result) and expr.offset not in (
238
+ self.arch.sp_offset,
239
+ self.arch.ip_offset,
240
+ ):
241
+ # Record the replacement
242
+ self.state.add_replacement(
243
+ self._codeloc(block_only=False), VEXReg(expr.offset, expr.result_size(self.tyenv) // 8), result
244
+ )
245
+ return result
268
246
 
269
- def _handle_GetI(self, expr):
247
+ def _handle_expr_GetI(self, expr):
270
248
  return self.state.top(expr.result_size(self.tyenv))
271
249
 
272
- def _handle_Load(self, expr):
273
- addr = self._expr(expr.addr)
274
- if addr is None or type(addr) in (Top, Bottom):
275
- return None
250
+ def _handle_expr_ITE(self, expr):
251
+ return self.state.top(expr.result_size(self.tyenv))
252
+
253
+ def _handle_expr_GSPTR(self, expr):
254
+ return self.state.top(expr.result_size(self.tyenv))
255
+
256
+ def _handle_expr_VECRET(self, expr):
257
+ return self.state.top(expr.result_size(self.tyenv))
258
+
259
+ def _handle_expr_RdTmp(self, expr):
260
+ try:
261
+ return self.tmps[expr.tmp]
262
+ except KeyError:
263
+ return self._top(pyvex.get_type_size(self.tyenv.lookup(expr.tmp)))
264
+
265
+ def _handle_expr_Const(self, expr):
266
+ result = value(expr.con.type, expr.con.value)
267
+ if isinstance(result, claripy.ast.FP):
268
+ return self._top(expr.con.size)
269
+ return result
270
+
271
+ def _handle_expr_Load(self, expr):
272
+ addr = self._expr_bv(expr.addr)
276
273
  size = expr.result_size(self.tyenv) // self.arch.byte_width
277
274
  return self._load_data(addr, size, expr.endness)
278
275
 
279
- def _handle_CCall(self, expr):
280
- return None
281
-
282
- def _handle_Binop(self, expr: pyvex.IRExpr.Binop):
276
+ def _handle_expr_Binop(self, expr):
283
277
  if not self.state.do_binops:
284
- return self.state.top(expr.result_size(self.tyenv))
278
+ return self._top(expr.result_size(self.tyenv))
285
279
 
286
- return super()._handle_Binop(expr)
287
- # print(expr.op, r)
280
+ return super()._handle_expr_Binop(expr)
288
281
 
289
- def _handle_Triop(self, expr: pyvex.IRExpr.Triop):
282
+ def _handle_expr_Triop(self, expr):
290
283
  if not self.state.do_binops:
291
- return self.state.top(expr.result_size(self.tyenv))
292
-
293
- return super()._handle_Triop(expr)
294
-
295
- def _handle_Conversion(self, expr):
296
- expr_ = self._expr(expr.args[0])
297
- to_size = expr.result_size(self.tyenv)
298
- if expr_ is None:
299
- return self._top(to_size)
300
- if self._is_top(expr_):
301
- return self._top(to_size).annotate(*expr_.annotations)
302
-
303
- if isinstance(expr_, claripy.ast.Base) and expr_.op == "BVV":
304
- if expr_.size() > to_size:
305
- # truncation
306
- return expr_[to_size - 1 : 0]
307
- if expr_.size() < to_size:
308
- # extension
309
- return claripy.ZeroExt(to_size - expr_.size(), expr_)
310
- return expr_
311
-
312
- return self._top(to_size)
313
-
314
- def _handle_Exit(self, stmt):
284
+ return self._top(expr.result_size(self.tyenv))
285
+
286
+ return super()._handle_expr_Triop(expr)
287
+
288
+ def _handle_stmt_Exit(self, stmt: pyvex.stmt.Exit):
315
289
  guard = self._expr(stmt.guard)
316
- if guard is not None and len(guard.annotations) == 1:
317
- dst = self._expr(stmt.dst)
318
- if dst is not None and dst.concrete:
290
+ if len(guard.annotations) == 1:
291
+ dst = value(stmt.dst.type, stmt.dst.value)
292
+ if dst.concrete:
319
293
  anno = guard.annotations[0]
320
294
  if isinstance(anno, RegisterComparisonAnnotation) and anno.cmp_op == "eq":
321
295
  v = (anno.offset, anno.size, anno.value)
322
296
  if v not in self.state.block_initial_reg_values[self.block.addr, dst.concrete_value]:
323
297
  self.state.block_initial_reg_values[self.block.addr, dst.concrete_value].append(v)
324
-
325
- super()._handle_Exit(stmt)
326
-
327
- _handle_CmpF = _handle_CmpEQ
@@ -119,13 +119,19 @@ class OutdatedDefinitionWalker(AILBlockWalker):
119
119
  super()._handle_Load(expr_idx, expr, stmt_idx, stmt, block)
120
120
  # then if the address expression is up-to-date, we check the global store
121
121
  if not self.out_dated and (
122
- self.state.global_stores
123
- and not all(
124
- self._check_store_precedes_load(CodeLocation(store_block_addr, store_stmt_idx), self.expr_defat)
125
- for store_block_addr, store_stmt_idx, addr, store in self.state.global_stores
122
+ (
123
+ self.state.global_stores
124
+ and not all(
125
+ self._check_store_precedes_load(CodeLocation(store_block_addr, store_stmt_idx), self.expr_defat)
126
+ for store_block_addr, store_stmt_idx, addr, store in self.state.global_stores
127
+ )
128
+ )
129
+ or (
130
+ self.state.last_stack_store is not None
131
+ and not self._check_store_precedes_load(
132
+ CodeLocation(*self.state.last_stack_store[:2]), self.expr_defat
133
+ )
126
134
  )
127
- or self.state.last_stack_store is not None
128
- and not self._check_store_precedes_load(CodeLocation(*self.state.last_stack_store[:2]), self.expr_defat)
129
135
  ):
130
136
  self.out_dated = True
131
137
 
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  from typing import Any, TYPE_CHECKING
4
4
  import logging
5
5
  import time
6
+ import contextlib
6
7
 
7
8
  import claripy
8
9
  import ailment
@@ -17,8 +18,6 @@ from angr import sim_options
17
18
  from angr.analyses import register_analysis
18
19
  from angr.analyses.analysis import Analysis
19
20
  from .engine_vex import SimEnginePropagatorVEX
20
- from .engine_ail import SimEnginePropagatorAIL
21
- import contextlib
22
21
 
23
22
  if TYPE_CHECKING:
24
23
  from angr.analyses.reaching_definitions.reaching_definitions import ReachingDefinitionsModel
@@ -165,21 +164,12 @@ class PropagatorAnalysis(ForwardAnalysis, Analysis): # pylint:disable=abstract-
165
164
  if the_func is not None:
166
165
  bp_as_gpr = the_func.info.get("bp_as_gpr", False)
167
166
 
168
- self._engine_vex = SimEnginePropagatorVEX(
167
+ # pyright says pylint is wrong about this
168
+ self._engine_vex = SimEnginePropagatorVEX( # pylint: disable=abstract-class-instantiated
169
169
  project=self.project,
170
- arch=self.project.arch,
171
170
  reaching_definitions=self._reaching_definitions,
172
171
  bp_as_gpr=bp_as_gpr,
173
172
  )
174
- self._engine_ail = SimEnginePropagatorAIL(
175
- arch=self.project.arch,
176
- stack_pointer_tracker=self._stack_pointer_tracker,
177
- # We only propagate tmps within the same block. This is because the lifetime of tmps is one block only.
178
- propagate_tmps=block is not None,
179
- reaching_definitions=self._reaching_definitions,
180
- immediate_stmt_removal=self._immediate_stmt_removal,
181
- bp_as_gpr=bp_as_gpr,
182
- )
183
173
 
184
174
  # optimization: skip state copying for the initial state
185
175
  self._initial_state = None
@@ -240,8 +230,7 @@ class PropagatorAnalysis(ForwardAnalysis, Analysis): # pylint:disable=abstract-
240
230
  pass
241
231
 
242
232
  def _initial_abstract_state(self, node):
243
- cls = PropagatorAILState if isinstance(node, ailment.Block) else PropagatorVEXState
244
- self._initial_state = cls.initial_state(
233
+ self._initial_state = PropagatorVEXState.initial_state(
245
234
  self.project,
246
235
  rda=self._reaching_definitions,
247
236
  only_consts=self._only_consts,
@@ -262,19 +251,12 @@ class PropagatorAnalysis(ForwardAnalysis, Analysis): # pylint:disable=abstract-
262
251
  def _run_on_node(self, node, state):
263
252
  self._analyzed_states += 1
264
253
 
265
- if isinstance(node, ailment.Block):
266
- block = node
267
- block_key = (node.addr, node.idx)
268
- engine = self._engine_ail
269
- else:
270
- block = self.project.factory.block(
271
- node.addr, node.size, opt_level=1, cross_insn_opt=self._vex_cross_insn_opt
272
- )
273
- block_key = node.addr
274
- engine = self._engine_vex
275
- if block.size == 0:
276
- # maybe the block is not decodeable
277
- return False, state
254
+ block = self.project.factory.block(node.addr, node.size, opt_level=1, cross_insn_opt=self._vex_cross_insn_opt)
255
+ block_key = node.addr
256
+ engine = self._engine_vex
257
+ if block.size == 0:
258
+ # maybe the block is not decodeable
259
+ return False, state
278
260
 
279
261
  if state is not self._initial_state:
280
262
  # make a copy of the state if it's not the initial state