angr 9.2.131__py3-none-win_amd64.whl → 9.2.132__py3-none-win_amd64.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 (112) hide show
  1. angr/__init__.py +1 -1
  2. angr/analyses/analysis.py +6 -2
  3. angr/analyses/cfg/cfg_emulated.py +5 -5
  4. angr/analyses/cfg/cfg_fast.py +2 -2
  5. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +139 -94
  6. angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +1 -1
  7. angr/analyses/ddg.py +14 -11
  8. angr/analyses/decompiler/ail_simplifier.py +3 -2
  9. angr/analyses/decompiler/block_simplifier.py +10 -21
  10. angr/analyses/decompiler/clinic.py +108 -34
  11. angr/analyses/decompiler/condition_processor.py +12 -10
  12. angr/analyses/decompiler/dephication/graph_rewriting.py +1 -1
  13. angr/analyses/decompiler/dephication/rewriting_engine.py +169 -45
  14. angr/analyses/decompiler/dephication/seqnode_dephication.py +5 -4
  15. angr/analyses/decompiler/optimization_passes/const_derefs.py +1 -0
  16. angr/analyses/decompiler/optimization_passes/div_simplifier.py +41 -16
  17. angr/analyses/decompiler/optimization_passes/engine_base.py +261 -83
  18. angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +173 -35
  19. angr/analyses/decompiler/optimization_passes/mod_simplifier.py +5 -2
  20. angr/analyses/decompiler/optimization_passes/optimization_pass.py +39 -19
  21. angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +2 -0
  22. angr/analyses/decompiler/ssailification/rewriting.py +1 -2
  23. angr/analyses/decompiler/ssailification/rewriting_engine.py +138 -55
  24. angr/analyses/decompiler/ssailification/ssailification.py +2 -1
  25. angr/analyses/decompiler/ssailification/traversal.py +4 -6
  26. angr/analyses/decompiler/ssailification/traversal_engine.py +125 -42
  27. angr/analyses/decompiler/structured_codegen/c.py +5 -3
  28. angr/analyses/decompiler/structuring/phoenix.py +26 -9
  29. angr/analyses/decompiler/structuring/structurer_nodes.py +9 -0
  30. angr/analyses/deobfuscator/irsb_reg_collector.py +29 -60
  31. angr/analyses/deobfuscator/string_obf_finder.py +2 -2
  32. angr/analyses/init_finder.py +47 -22
  33. angr/analyses/propagator/engine_base.py +21 -14
  34. angr/analyses/propagator/engine_vex.py +149 -179
  35. angr/analyses/propagator/propagator.py +10 -28
  36. angr/analyses/propagator/top_checker_mixin.py +211 -5
  37. angr/analyses/propagator/vex_vars.py +1 -1
  38. angr/analyses/reaching_definitions/dep_graph.py +1 -1
  39. angr/analyses/reaching_definitions/engine_ail.py +304 -329
  40. angr/analyses/reaching_definitions/engine_vex.py +243 -229
  41. angr/analyses/reaching_definitions/function_handler.py +3 -3
  42. angr/analyses/reaching_definitions/rd_state.py +37 -32
  43. angr/analyses/s_propagator.py +18 -3
  44. angr/analyses/s_reaching_definitions/s_reaching_definitions.py +9 -5
  45. angr/analyses/typehoon/simple_solver.py +7 -5
  46. angr/analyses/typehoon/translator.py +8 -0
  47. angr/analyses/typehoon/typeconsts.py +10 -2
  48. angr/analyses/typehoon/typevars.py +9 -7
  49. angr/analyses/variable_recovery/engine_ail.py +299 -259
  50. angr/analyses/variable_recovery/engine_base.py +135 -117
  51. angr/analyses/variable_recovery/engine_vex.py +175 -185
  52. angr/analyses/variable_recovery/irsb_scanner.py +49 -38
  53. angr/analyses/variable_recovery/variable_recovery.py +28 -5
  54. angr/analyses/variable_recovery/variable_recovery_base.py +32 -33
  55. angr/analyses/variable_recovery/variable_recovery_fast.py +2 -2
  56. angr/analyses/xrefs.py +46 -19
  57. angr/annocfg.py +19 -14
  58. angr/block.py +4 -9
  59. angr/calling_conventions.py +1 -1
  60. angr/engines/engine.py +30 -14
  61. angr/engines/light/__init__.py +11 -3
  62. angr/engines/light/engine.py +1003 -1185
  63. angr/engines/pcode/cc.py +2 -0
  64. angr/engines/successors.py +13 -9
  65. angr/engines/vex/claripy/datalayer.py +1 -1
  66. angr/engines/vex/claripy/irop.py +1 -1
  67. angr/engines/vex/light/slicing.py +2 -2
  68. angr/exploration_techniques/__init__.py +1 -124
  69. angr/exploration_techniques/base.py +126 -0
  70. angr/exploration_techniques/bucketizer.py +1 -1
  71. angr/exploration_techniques/dfs.py +3 -1
  72. angr/exploration_techniques/director.py +2 -3
  73. angr/exploration_techniques/driller_core.py +1 -1
  74. angr/exploration_techniques/explorer.py +4 -2
  75. angr/exploration_techniques/lengthlimiter.py +2 -1
  76. angr/exploration_techniques/local_loop_seer.py +2 -1
  77. angr/exploration_techniques/loop_seer.py +5 -5
  78. angr/exploration_techniques/manual_mergepoint.py +2 -1
  79. angr/exploration_techniques/memory_watcher.py +3 -1
  80. angr/exploration_techniques/oppologist.py +4 -5
  81. angr/exploration_techniques/slicecutor.py +4 -2
  82. angr/exploration_techniques/spiller.py +1 -1
  83. angr/exploration_techniques/stochastic.py +2 -1
  84. angr/exploration_techniques/stub_stasher.py +2 -1
  85. angr/exploration_techniques/suggestions.py +3 -1
  86. angr/exploration_techniques/symbion.py +3 -1
  87. angr/exploration_techniques/tech_builder.py +2 -1
  88. angr/exploration_techniques/threading.py +4 -7
  89. angr/exploration_techniques/timeout.py +4 -2
  90. angr/exploration_techniques/tracer.py +4 -3
  91. angr/exploration_techniques/unique.py +3 -2
  92. angr/exploration_techniques/veritesting.py +1 -1
  93. angr/knowledge_plugins/key_definitions/atoms.py +2 -2
  94. angr/knowledge_plugins/key_definitions/live_definitions.py +16 -13
  95. angr/knowledge_plugins/propagations/states.py +13 -8
  96. angr/knowledge_plugins/variables/variable_manager.py +23 -9
  97. angr/lib/angr_native.dll +0 -0
  98. angr/sim_manager.py +1 -3
  99. angr/sim_state.py +39 -41
  100. angr/sim_type.py +5 -0
  101. angr/sim_variable.py +29 -28
  102. angr/utils/bits.py +12 -0
  103. angr/utils/orderedset.py +4 -1
  104. angr/utils/ssa/__init__.py +21 -3
  105. {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/METADATA +6 -6
  106. {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/RECORD +110 -111
  107. angr/analyses/propagator/engine_ail.py +0 -1562
  108. angr/storage/memory_mixins/__init__.pyi +0 -48
  109. {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/LICENSE +0 -0
  110. {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/WHEEL +0 -0
  111. {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/entry_points.txt +0 -0
  112. {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/top_level.txt +0 -0
@@ -1,21 +1,22 @@
1
1
  from __future__ import annotations
2
- from typing import Any, TYPE_CHECKING
2
+ from typing import Any, TYPE_CHECKING, Generic, TypeVar, cast
3
3
  import contextlib
4
4
  import logging
5
5
 
6
6
  import ailment
7
7
  import claripy
8
8
 
9
+ from angr.analyses.variable_recovery.variable_recovery_base import VariableRecoveryStateBase
10
+ from angr.engines.light.engine import BlockType
9
11
  from angr.storage.memory_mixins.paged_memory.pages.multi_values import MultiValues
10
12
  from angr.engines.light import SimEngineLight, ArithmeticExpression
11
- from angr.errors import SimEngineError, SimMemoryMissingError
13
+ from angr.errors import SimMemoryMissingError
12
14
  from angr.sim_variable import SimVariable, SimStackVariable, SimRegisterVariable, SimMemoryVariable
13
15
  from angr.code_location import CodeLocation
14
16
  from angr.analyses.typehoon import typevars, typeconsts
15
17
  from angr.analyses.typehoon.typevars import TypeVariable, DerivedTypeVariable, AddN, SubN, Load, Store
16
18
 
17
19
  if TYPE_CHECKING:
18
- from .variable_recovery_base import VariableRecoveryStateBase
19
20
  from angr.knowledge_plugins.variables.variable_manager import VariableManager
20
21
 
21
22
  #
@@ -24,8 +25,10 @@ if TYPE_CHECKING:
24
25
 
25
26
  l = logging.getLogger(name=__name__)
26
27
 
28
+ RichRT_co = TypeVar("RichRT_co", bound=claripy.ast.Bits, covariant=True)
27
29
 
28
- class RichR:
30
+
31
+ class RichR(Generic[RichRT_co]):
29
32
  """
30
33
  A rich representation of calculation results. The variable recovery data domain.
31
34
  """
@@ -39,44 +42,42 @@ class RichR:
39
42
 
40
43
  def __init__(
41
44
  self,
42
- data: claripy.ast.Base,
45
+ data: RichRT_co,
43
46
  variable=None,
44
- typevar: typevars.TypeVariable | None = None,
45
- type_constraints=None,
47
+ typevar: typeconsts.TypeConstant | typevars.TypeVariable | None = None,
48
+ type_constraints: set[typevars.TypeConstraint] | None = None,
46
49
  ):
47
- self.data: claripy.ast.Base = data
50
+ self.data = data
48
51
  self.variable = variable
49
52
  self.typevar = typevar
50
53
  self.type_constraints = type_constraints
51
54
 
52
55
  @property
53
- def bits(self):
54
- if self.data is not None and not isinstance(self.data, (int, float)):
55
- if isinstance(self.data, claripy.ast.Base):
56
- return self.data.size()
57
- return self.data.bits
58
- if self.variable is not None:
59
- return self.variable.bits
60
- return None
56
+ def bits(self) -> int:
57
+ return self.data.size()
61
58
 
62
59
  def __repr__(self):
63
60
  return f"R{{{self.data!r}}}"
64
61
 
65
62
 
66
- class SimEngineVRBase(SimEngineLight):
63
+ VRStateType = TypeVar("VRStateType", bound=VariableRecoveryStateBase)
64
+
65
+
66
+ class SimEngineVRBase(
67
+ Generic[VRStateType, BlockType],
68
+ SimEngineLight[VRStateType, RichR[claripy.ast.BV | claripy.ast.FP], BlockType, None],
69
+ ):
67
70
  """
68
71
  The base class for variable recovery analyses. Contains methods for basic interactions with the state, like loading
69
72
  and storing data.
70
73
  """
71
74
 
72
- state: VariableRecoveryStateBase
75
+ variable_manager: VariableManager
73
76
 
74
77
  def __init__(self, project, kb):
75
- super().__init__()
78
+ super().__init__(project)
76
79
 
77
- self.project = project
78
80
  self.kb = kb
79
- self.variable_manager: VariableManager | None = None
80
81
  self.vvar_region: dict[int, Any] = {}
81
82
 
82
83
  @property
@@ -85,41 +86,37 @@ class SimEngineVRBase(SimEngineLight):
85
86
  return None
86
87
  return self.state.function.addr
87
88
 
88
- def process(self, state, *args, **kwargs): # pylint:disable=unused-argument
89
+ def process(self, state, *args, **kwargs):
89
90
  self.variable_manager = state.variable_manager
91
+ super().process(state, *args, **kwargs)
90
92
 
91
- try:
92
- self._process(state, None, block=kwargs.pop("block", None))
93
- except SimEngineError as e:
94
- if kwargs.pop("fail_fast", False) is True:
95
- raise e
93
+ def _top(self, bits):
94
+ return RichR(self.state.top(bits))
96
95
 
97
- def _process(
98
- self, state, successors, block=None, func_addr=None
99
- ): # pylint:disable=unused-argument,arguments-differ,arguments-renamed
100
- super()._process(state, successors, block=block)
96
+ def _is_top(self, expr):
97
+ return self.state.is_top(expr.data)
101
98
 
102
99
  #
103
100
  # Address parsing
104
101
  #
105
102
 
106
103
  @staticmethod
107
- def _addr_has_concrete_base(addr: claripy.ast.BV) -> bool:
104
+ def _addr_has_concrete_base(addr: claripy.ast.Bits) -> bool:
108
105
  if addr.op == "__add__" and len(addr.args) == 2:
109
- if addr.args[0].concrete:
106
+ if cast(claripy.ast.BV, addr.args[0]).concrete:
110
107
  return True
111
- if addr.args[1].concrete:
108
+ if cast(claripy.ast.BV, addr.args[1]).concrete:
112
109
  return True
113
110
  return False
114
111
 
115
112
  @staticmethod
116
- def _parse_offsetted_addr(addr: claripy.ast.BV) -> tuple[claripy.ast.BV, claripy.ast.BV, claripy.ast.BV] | None:
113
+ def _parse_offsetted_addr(addr: claripy.ast.Bits) -> tuple[claripy.ast.BV, claripy.ast.BV, int] | None:
117
114
  if addr.op == "__add__" and len(addr.args) == 2:
118
115
  concrete_base, byte_offset = None, None
119
- if addr.args[0].concrete:
120
- concrete_base, byte_offset = addr.args
121
- elif addr.args[1].concrete:
122
- concrete_base, byte_offset = addr.args[1], addr.args[0]
116
+ if cast(claripy.ast.BV, addr.args[0]).concrete:
117
+ concrete_base, byte_offset = cast(tuple[claripy.ast.BV, claripy.ast.BV], addr.args)
118
+ elif cast(claripy.ast.BV, addr.args[1]).concrete:
119
+ concrete_base, byte_offset = cast(tuple[claripy.ast.BV, claripy.ast.BV], (addr.args[1], addr.args[0]))
123
120
  if concrete_base is None or byte_offset is None:
124
121
  return None
125
122
  base_addr = concrete_base
@@ -130,9 +127,9 @@ class SimEngineVRBase(SimEngineLight):
130
127
  elem_size = 1
131
128
  else:
132
129
  abs_offset = byte_offset
133
- if abs_offset.op == "__lshift__" and abs_offset.args[1].concrete:
134
- offset = abs_offset.args[0]
135
- elem_size = 2 ** abs_offset.args[1].concrete_value
130
+ if abs_offset.op == "__lshift__" and cast(claripy.ast.BV, abs_offset.args[1]).concrete:
131
+ offset = cast(claripy.ast.BV, abs_offset.args[0])
132
+ elem_size = 2 ** cast(claripy.ast.BV, abs_offset.args[1]).concrete_value
136
133
  elif abs_offset.op == "__mul__" and abs_offset.args[1].concrete:
137
134
  offset = abs_offset.args[0]
138
135
  elem_size = abs_offset.args[1].concrete_value
@@ -146,12 +143,9 @@ class SimEngineVRBase(SimEngineLight):
146
143
  #
147
144
 
148
145
  def _ensure_variable_existence(
149
- self, richr_addr: RichR, codeloc: CodeLocation, src_expr=None
150
- ) -> list[tuple[SimVariable, int]] | None:
151
- data: claripy.ast.Base = richr_addr.data
152
-
153
- if data is None:
154
- return None
146
+ self, richr_addr: RichR[claripy.ast.BV | claripy.ast.FP], codeloc: CodeLocation, src_expr=None
147
+ ) -> list[tuple[SimVariable, int]]:
148
+ data = richr_addr.data
155
149
 
156
150
  if self.state.is_stack_address(data):
157
151
  # this is a stack address
@@ -209,7 +203,7 @@ class SimEngineVRBase(SimEngineLight):
209
203
 
210
204
  # write the variable back to stack
211
205
  if vs is None:
212
- top = self.state.top(self.arch.byte_width)
206
+ top = self.state.top(self.project.arch.byte_width)
213
207
  top = self.state.annotate_with_variables(top, [(0, variable)])
214
208
  vs = MultiValues(top)
215
209
  self.state.stack_region.store(stack_addr, vs)
@@ -234,7 +228,7 @@ class SimEngineVRBase(SimEngineLight):
234
228
  existing_vars = [(variable, 0)]
235
229
 
236
230
  else:
237
- return None
231
+ return []
238
232
 
239
233
  # record all variables
240
234
  for var, offset in existing_vars:
@@ -244,8 +238,8 @@ class SimEngineVRBase(SimEngineLight):
244
238
 
245
239
  return existing_vars
246
240
 
247
- def _reference(self, richr: RichR, codeloc: CodeLocation, src=None):
248
- data: claripy.ast.Base = richr.data
241
+ def _reference(self, richr: RichR[claripy.ast.BV | claripy.ast.FP], codeloc: CodeLocation, src=None):
242
+ data = richr.data
249
243
 
250
244
  if data is None:
251
245
  return
@@ -260,7 +254,7 @@ class SimEngineVRBase(SimEngineLight):
260
254
  self.block.addr,
261
255
  self.stmt_idx,
262
256
  "memory",
263
- block_idx=self.block.idx if isinstance(self.block, ailment.Block) else None,
257
+ block_idx=cast(ailment.Block, self.block).idx if isinstance(self.block, ailment.Block) else None,
264
258
  )
265
259
 
266
260
  # find the correct variable
@@ -306,14 +300,17 @@ class SimEngineVRBase(SimEngineLight):
306
300
  :return:
307
301
  """
308
302
 
309
- if offset in (self.arch.ip_offset, self.arch.sp_offset, self.arch.lr_offset) or not create_variable:
303
+ if (
304
+ offset in (self.project.arch.ip_offset, self.project.arch.sp_offset, self.project.arch.lr_offset)
305
+ or not create_variable
306
+ ):
310
307
  # only store the value. don't worry about variables.
311
308
  v = MultiValues(richr.data)
312
309
  self.state.register_region.store(offset, v)
313
310
  return
314
311
 
315
312
  codeloc: CodeLocation = self._codeloc()
316
- data: claripy.ast.Base = richr.data
313
+ data = richr.data
317
314
 
318
315
  # lea
319
316
  self._ensure_variable_existence(richr, codeloc)
@@ -329,7 +326,9 @@ class SimEngineVRBase(SimEngineLight):
329
326
  # next check if we are overwriting *part* of an existing variable that is not an input variable
330
327
  addr_and_variables = set()
331
328
  try:
332
- vs: MultiValues = self.state.register_region.load(offset, size=size, endness=self.arch.register_endness)
329
+ vs: MultiValues = self.state.register_region.load(
330
+ offset, size=size, endness=self.project.arch.register_endness
331
+ )
333
332
  for values in vs.values():
334
333
  for value in values:
335
334
  addr_and_variables.update(self.state.extract_variables(value))
@@ -371,8 +370,8 @@ class SimEngineVRBase(SimEngineLight):
371
370
 
372
371
  def _assign_to_vvar(
373
372
  self,
374
- vvar: ailment.Expr.VirtualVariable,
375
- richr,
373
+ vvar: ailment.expression.VirtualVariable,
374
+ richr: RichR[claripy.ast.BV | claripy.ast.FP],
376
375
  src=None,
377
376
  dst=None,
378
377
  create_variable: bool = True,
@@ -383,8 +382,8 @@ class SimEngineVRBase(SimEngineLight):
383
382
  vvar_id = vvar.varid
384
383
 
385
384
  if (
386
- vvar.category == ailment.Expr.VirtualVariableCategory.REGISTER
387
- and vvar.oident in (self.arch.ip_offset, self.arch.sp_offset, self.arch.lr_offset)
385
+ vvar.category == ailment.expression.VirtualVariableCategory.REGISTER
386
+ and vvar.oident in (self.project.arch.ip_offset, self.project.arch.sp_offset, self.project.arch.lr_offset)
388
387
  or not create_variable
389
388
  ):
390
389
  # only store the value. don't worry about variables.
@@ -392,7 +391,7 @@ class SimEngineVRBase(SimEngineLight):
392
391
  return
393
392
 
394
393
  codeloc: CodeLocation = self._codeloc()
395
- data: claripy.ast.Base = richr.data
394
+ data = richr.data
396
395
 
397
396
  # lea
398
397
  self._ensure_variable_existence(richr, codeloc)
@@ -467,7 +466,9 @@ class SimEngineVRBase(SimEngineLight):
467
466
  self.state.add_type_constraint(typevars.Subtype(richr.typevar, typevar))
468
467
  self.state.add_type_constraint(typevars.Subtype(typevar, typeconsts.int_type(variable.size * 8)))
469
468
 
470
- def _store(self, richr_addr: RichR, data: RichR, size, stmt=None): # pylint:disable=unused-argument
469
+ def _store(
470
+ self, richr_addr: RichR[claripy.ast.BV], data: RichR[claripy.ast.BV | claripy.ast.FP], size, stmt=None
471
+ ): # pylint:disable=unused-argument
471
472
  """
472
473
 
473
474
  :param RichR addr:
@@ -476,16 +477,16 @@ class SimEngineVRBase(SimEngineLight):
476
477
  :return:
477
478
  """
478
479
 
479
- addr: claripy.ast.Base = richr_addr.data
480
+ addr = richr_addr.data
480
481
  stored = False
481
482
 
482
483
  if addr.concrete:
483
484
  # fully concrete. this is a global address
484
485
  self._store_to_global(addr.concrete_value, data, size, stmt=stmt)
485
486
  stored = True
486
- elif self._addr_has_concrete_base(addr) and self._parse_offsetted_addr(addr) is not None:
487
+ elif self._addr_has_concrete_base(addr) and (parsed := self._parse_offsetted_addr(addr)) is not None:
487
488
  # we are storing to a concrete global address with an offset
488
- base_addr, offset, elem_size = self._parse_offsetted_addr(addr)
489
+ base_addr, offset, elem_size = parsed
489
490
  self._store_to_global(base_addr.concrete_value, data, size, stmt=stmt, offset=offset, elem_size=elem_size)
490
491
  stored = True
491
492
  else:
@@ -509,7 +510,9 @@ class SimEngineVRBase(SimEngineLight):
509
510
  # storing to a location specified by a pointer whose value cannot be determined at this point
510
511
  self._store_to_variable(richr_addr, size, stmt=stmt)
511
512
 
512
- def _store_to_stack(self, stack_offset, data: RichR, size, offset=0, stmt=None, endness=None):
513
+ def _store_to_stack(
514
+ self, stack_offset, data: RichR[claripy.ast.BV | claripy.ast.FP], size, offset=0, stmt=None, endness=None
515
+ ):
513
516
  if stmt is None:
514
517
  existing_vars = self.variable_manager[self.func_addr].find_variables_by_stmt(
515
518
  self.block.addr, self.stmt_idx, "memory"
@@ -581,7 +584,7 @@ class SimEngineVRBase(SimEngineLight):
581
584
  size: int,
582
585
  stmt=None,
583
586
  offset: claripy.ast.BV | None = None,
584
- elem_size: claripy.ast.BV | None = None,
587
+ elem_size: int | None = None,
585
588
  ):
586
589
  variable_manager = self.variable_manager["global"]
587
590
  if stmt is None:
@@ -592,8 +595,8 @@ class SimEngineVRBase(SimEngineLight):
592
595
  if offset is None or elem_size is None:
593
596
  # trivial case
594
597
  abs_addr = addr
595
- elif offset.concrete and elem_size.concrete:
596
- abs_addr = addr + offset.concrete_value * elem_size.concrete_value
598
+ elif offset.concrete:
599
+ abs_addr = addr + offset.concrete_value * elem_size
597
600
  else:
598
601
  abs_addr = None
599
602
 
@@ -618,17 +621,17 @@ class SimEngineVRBase(SimEngineLight):
618
621
 
619
622
  if abs_addr is not None:
620
623
  self.state.global_region.store(
621
- addr, data_expr, endness=self.state.arch.memory_endness if stmt is None else stmt.endness
624
+ addr, data_expr, endness=self.project.arch.memory_endness if stmt is None else stmt.endness
622
625
  )
623
626
 
624
627
  codeloc = CodeLocation(
625
628
  self.block.addr, self.stmt_idx, ins_addr=self.ins_addr, block_idx=getattr(self.block, "idx", None)
626
629
  )
627
- values = None
630
+ values: MultiValues | None = None
628
631
  if abs_addr is not None:
629
632
  with contextlib.suppress(SimMemoryMissingError):
630
- values: MultiValues = self.state.global_region.load(
631
- abs_addr, size=size, endness=self.state.arch.memory_endness if stmt is None else stmt.endness
633
+ values = self.state.global_region.load(
634
+ abs_addr, size=size, endness=self.project.arch.memory_endness if stmt is None else stmt.endness
632
635
  )
633
636
 
634
637
  if values is not None:
@@ -649,8 +652,8 @@ class SimEngineVRBase(SimEngineLight):
649
652
 
650
653
  if offset is not None and elem_size is not None:
651
654
  # it's an array!
652
- if offset.concrete and elem_size.concrete:
653
- concrete_offset = offset.concrete_value * elem_size.concrete_value
655
+ if offset.concrete:
656
+ concrete_offset = offset.concrete_value * elem_size
654
657
  store_typevar = self._create_access_typevar(typevar, True, size, concrete_offset)
655
658
  self.state.add_type_constraint(typevars.Subtype(store_typevar, typeconsts.TopType()))
656
659
  else:
@@ -671,7 +674,9 @@ class SimEngineVRBase(SimEngineLight):
671
674
  self.state.add_type_constraint(typevars.Subtype(store_typevar, typeconsts.TopType()))
672
675
  self.state.add_type_constraint(typevars.Subtype(data.typevar, store_typevar))
673
676
 
674
- def _store_to_variable(self, richr_addr: RichR, size: int, stmt=None): # pylint:disable=unused-argument
677
+ def _store_to_variable(
678
+ self, richr_addr: RichR[claripy.ast.BV], size: int, stmt=None
679
+ ): # pylint:disable=unused-argument
675
680
  addr_variable = richr_addr.variable
676
681
  codeloc = self._codeloc()
677
682
 
@@ -698,7 +703,7 @@ class SimEngineVRBase(SimEngineLight):
698
703
  self.state.typevars.add_type_variable(addr_variable, codeloc, typevar)
699
704
  self.state.add_type_constraint(typevars.Subtype(store_typevar, typeconsts.TopType()))
700
705
 
701
- def _load(self, richr_addr: RichR, size: int, expr=None):
706
+ def _load(self, richr_addr: RichR[claripy.ast.BV], size: int, expr=None):
702
707
  """
703
708
 
704
709
  :param RichR richr_addr:
@@ -706,7 +711,7 @@ class SimEngineVRBase(SimEngineLight):
706
711
  :return:
707
712
  """
708
713
 
709
- addr: claripy.ast.Base = richr_addr.data
714
+ addr = cast(claripy.ast.BV, richr_addr.data)
710
715
  codeloc = CodeLocation(
711
716
  self.block.addr, self.stmt_idx, ins_addr=self.ins_addr, block_idx=getattr(self.block, "idx", None)
712
717
  )
@@ -737,14 +742,17 @@ class SimEngineVRBase(SimEngineLight):
737
742
  concrete_offset = stack_offset
738
743
  dynamic_offset = None
739
744
 
740
- try:
741
- values: MultiValues | None = self.state.stack_region.load(
742
- self.state.stack_addr_from_offset(concrete_offset),
743
- size=size,
744
- endness=self.state.arch.memory_endness,
745
- )
745
+ if concrete_offset is not None:
746
+ try:
747
+ values: MultiValues | None = self.state.stack_region.load(
748
+ self.state.stack_addr_from_offset(concrete_offset),
749
+ size=size,
750
+ endness=self.project.arch.memory_endness,
751
+ )
746
752
 
747
- except SimMemoryMissingError:
753
+ except SimMemoryMissingError:
754
+ values = None
755
+ else:
748
756
  values = None
749
757
 
750
758
  all_vars: set[tuple[int, SimVariable]] = set()
@@ -756,7 +764,7 @@ class SimEngineVRBase(SimEngineLight):
756
764
  var_offset = stack_offset - var_.offset
757
765
  all_vars.add((var_offset, var_))
758
766
 
759
- if not all_vars:
767
+ if not all_vars and concrete_offset is not None:
760
768
  variables = self.variable_manager[self.func_addr].find_variables_by_stack_offset(concrete_offset)
761
769
  if not variables:
762
770
  variable = SimStackVariable(
@@ -770,28 +778,27 @@ class SimEngineVRBase(SimEngineLight):
770
778
  variables = {variable}
771
779
  l.debug("Identified a new stack variable %s at %#x.", variable, self.ins_addr)
772
780
  for variable in variables:
773
- v = self.state.top(size * self.state.arch.byte_width)
781
+ v = self.state.top(size * self.project.arch.byte_width)
774
782
  v = self.state.annotate_with_variables(v, [(0, variable)])
775
783
  stack_addr = self.state.stack_addr_from_offset(concrete_offset)
776
- self.state.stack_region.store(stack_addr, v, endness=self.state.arch.memory_endness)
784
+ self.state.stack_region.store(stack_addr, v, endness=self.project.arch.memory_endness)
777
785
 
778
786
  all_vars = {(0, variable) for variable in variables}
779
787
 
780
- if len(all_vars) > 1:
781
- # overlapping variables
782
- all_vars = list(all_vars)
788
+ all_vars_list = list(all_vars)
783
789
 
790
+ if len(all_vars_list) > 1:
784
791
  # sort by some value so that the outcome here isn't random
785
- all_vars.sort(
792
+ cast(list[tuple[int, SimStackVariable]], all_vars_list).sort(
786
793
  reverse=True,
787
794
  key=lambda val: (val[0], val[1].offset, val[1].base, val[1].base_addr, val[1].size),
788
795
  )
789
796
 
790
797
  l.warning(
791
- "Reading memory with overlapping variables: %s. Ignoring all but the first one.", all_vars
798
+ "Reading memory with overlapping variables: %s. Ignoring all but the first one.", all_vars_list
792
799
  )
793
800
 
794
- var_offset, var = next(iter(all_vars)) # won't fail
801
+ var_offset, var = next(iter(all_vars_list)) # won't fail
795
802
  # calculate variable_offset
796
803
  if dynamic_offset is None:
797
804
  offset_into_variable = var_offset
@@ -838,8 +845,8 @@ class SimEngineVRBase(SimEngineLight):
838
845
  # | typevars.HasField(size * 8, 0)
839
846
  # | )
840
847
 
841
- r = self.state.top(size * self.state.arch.byte_width)
842
- r = self.state.annotate_with_variables(r, list(all_vars))
848
+ r = self.state.top(size * self.project.arch.byte_width)
849
+ r = self.state.annotate_with_variables(r, all_vars_list)
843
850
  return RichR(r, variable=var, typevar=typevar)
844
851
 
845
852
  elif addr.concrete:
@@ -847,9 +854,9 @@ class SimEngineVRBase(SimEngineLight):
847
854
  v = self._load_from_global(addr.concrete_value, size, expr=expr)
848
855
  typevar = v.typevar
849
856
 
850
- elif self._addr_has_concrete_base(addr) and self._parse_offsetted_addr(addr) is not None:
857
+ elif self._addr_has_concrete_base(addr) and (parsed := self._parse_offsetted_addr(addr)) is not None:
851
858
  # Loading data from a memory address with an offset
852
- base_addr, offset, elem_size = self._parse_offsetted_addr(addr)
859
+ base_addr, offset, elem_size = parsed
853
860
  v = self._load_from_global(base_addr.concrete_value, size, expr=expr, offset=offset, elem_size=elem_size)
854
861
  typevar = v.typevar
855
862
 
@@ -883,7 +890,7 @@ class SimEngineVRBase(SimEngineLight):
883
890
  typevar = self._create_access_typevar(richr_addr_typevar, False, size, offset)
884
891
  self.state.add_type_constraint(typevars.Subtype(typevar, typeconsts.TopType()))
885
892
 
886
- return RichR(self.state.top(size * self.state.arch.byte_width), typevar=typevar)
893
+ return RichR(self.state.top(size * self.project.arch.byte_width), typevar=typevar)
887
894
 
888
895
  def _load_from_global(
889
896
  self,
@@ -891,8 +898,8 @@ class SimEngineVRBase(SimEngineLight):
891
898
  size,
892
899
  expr=None,
893
900
  offset: claripy.ast.BV | None = None,
894
- elem_size: claripy.ast.BV | None = None,
895
- ) -> RichR:
901
+ elem_size: int | None = None,
902
+ ) -> RichR[claripy.ast.BV]:
896
903
  variable_manager = self.variable_manager["global"]
897
904
  if expr is None:
898
905
  existing_vars = variable_manager.find_variables_by_stmt(self.block.addr, self.stmt_idx, "memory")
@@ -914,7 +921,7 @@ class SimEngineVRBase(SimEngineLight):
914
921
  if not existing_vars:
915
922
  # is this address mapped?
916
923
  if self.project.loader.find_object_containing(addr) is None:
917
- return RichR(self.state.top(size * self.state.arch.byte_width))
924
+ return RichR(self.state.top(size * self.project.arch.byte_width))
918
925
  variable = SimMemoryVariable(
919
926
  addr,
920
927
  size,
@@ -940,8 +947,8 @@ class SimEngineVRBase(SimEngineLight):
940
947
 
941
948
  if offset is not None and elem_size is not None:
942
949
  # it's an array!
943
- if offset.concrete and elem_size.concrete:
944
- concrete_offset = offset.concrete_value * elem_size.concrete_value
950
+ if offset.concrete:
951
+ concrete_offset = offset.concrete_value * elem_size
945
952
  load_typevar = self._create_access_typevar(typevar, True, size, concrete_offset)
946
953
  self.state.add_type_constraint(typevars.Subtype(load_typevar, typeconsts.TopType()))
947
954
  else:
@@ -951,7 +958,7 @@ class SimEngineVRBase(SimEngineLight):
951
958
  load_typevar = self._create_access_typevar(typevar, True, size, concrete_offset)
952
959
  self.state.add_type_constraint(typevars.Subtype(load_typevar, typeconsts.TopType()))
953
960
 
954
- return RichR(self.state.top(size * self.state.arch.byte_width), typevar=typevar)
961
+ return RichR(self.state.top(size * self.project.arch.byte_width), typevar=typevar)
955
962
 
956
963
  def _read_from_register(self, offset, size, expr=None, force_variable_size=None, create_variable: bool = True):
957
964
  """
@@ -968,17 +975,17 @@ class SimEngineVRBase(SimEngineLight):
968
975
  except SimMemoryMissingError:
969
976
  values = None
970
977
 
971
- if offset in (self.arch.sp_offset, self.arch.ip_offset):
978
+ if offset in (self.project.arch.sp_offset, self.project.arch.ip_offset):
972
979
  # load values. don't worry about variables
973
980
  if values is None:
974
- r_value = self.state.top(size * self.arch.byte_width)
981
+ r_value = self.state.top(size * self.project.arch.byte_width)
975
982
  else:
976
983
  r_value = next(iter(next(iter(values.values()))))
977
984
  return RichR(r_value, variable=None, typevar=None)
978
985
 
979
986
  if not values:
980
987
  # the value does not exist.
981
- value = self.state.top(size * self.state.arch.byte_width)
988
+ value = self.state.top(size * self.project.arch.byte_width)
982
989
  if create_variable:
983
990
  # create a new variable if necessary
984
991
  variable = SimRegisterVariable(
@@ -1001,7 +1008,7 @@ class SimEngineVRBase(SimEngineLight):
1001
1008
  self.variable_manager[self.func_addr].read_from(var, None, codeloc, atom=expr, overwrite=False)
1002
1009
  variable_set.add(var)
1003
1010
 
1004
- if offset == self.arch.sp_offset:
1011
+ if offset == self.project.arch.sp_offset:
1005
1012
  # ignore sp
1006
1013
  typevar = None
1007
1014
  var = None
@@ -1028,7 +1035,7 @@ class SimEngineVRBase(SimEngineLight):
1028
1035
  typevar = self.state.typevars[var]
1029
1036
 
1030
1037
  r_value = (
1031
- next(iter(value_list[0])) if len(value_list) == 1 else self.state.top(size * self.arch.byte_width)
1038
+ next(iter(value_list[0])) if len(value_list) == 1 else self.state.top(size * self.project.arch.byte_width)
1032
1039
  ) # fall back to top
1033
1040
  if var is not None and var.size != size:
1034
1041
  # ignore the variable and the associated type if we are only reading part of the variable
@@ -1036,22 +1043,26 @@ class SimEngineVRBase(SimEngineLight):
1036
1043
  return RichR(r_value, variable=var, typevar=typevar)
1037
1044
 
1038
1045
  def _read_from_vvar(
1039
- self, vvar: ailment.Expr.VirtualVariable, expr=None, create_variable: bool = True, vvar_id: int | None = None
1046
+ self,
1047
+ vvar: ailment.expression.VirtualVariable,
1048
+ expr=None,
1049
+ create_variable: bool = True,
1050
+ vvar_id: int | None = None,
1040
1051
  ):
1041
1052
  codeloc = self._codeloc()
1042
1053
 
1043
1054
  if vvar_id is None:
1044
1055
  vvar_id = vvar.varid
1045
1056
 
1046
- value: claripy.ast.Base | None = self.vvar_region.get(vvar_id, None)
1057
+ value: claripy.ast.BV | None = self.vvar_region.get(vvar_id, None)
1047
1058
 
1048
1059
  # fallback for register arguments
1049
1060
  if value is None and vvar.was_reg:
1050
1061
  return self._read_from_register(vvar.reg_offset, vvar.size, expr=vvar, create_variable=True)
1051
1062
 
1052
1063
  if vvar.category == ailment.Expr.VirtualVariableCategory.REGISTER and vvar.oident in (
1053
- self.arch.sp_offset,
1054
- self.arch.ip_offset,
1064
+ self.project.arch.sp_offset,
1065
+ self.project.arch.ip_offset,
1055
1066
  ):
1056
1067
  # load values. don't worry about variables
1057
1068
  r_value = self.state.top(vvar.size) if value is None else value
@@ -1095,7 +1106,10 @@ class SimEngineVRBase(SimEngineLight):
1095
1106
  self.variable_manager[self.func_addr].read_from(var, None, codeloc, atom=expr, overwrite=False)
1096
1107
  variable_set.add(var)
1097
1108
 
1098
- if vvar.category == ailment.Expr.VirtualVariableCategory.REGISTER and vvar.oident == self.arch.sp_offset:
1109
+ if (
1110
+ vvar.category == ailment.Expr.VirtualVariableCategory.REGISTER
1111
+ and vvar.oident == self.project.arch.sp_offset
1112
+ ):
1099
1113
  # ignore sp
1100
1114
  typevar = None
1101
1115
  var = None
@@ -1127,7 +1141,11 @@ class SimEngineVRBase(SimEngineLight):
1127
1141
  return RichR(value, variable=var, typevar=typevar)
1128
1142
 
1129
1143
  def _create_access_typevar(
1130
- self, typevar: TypeVariable | DerivedTypeVariable, is_store: bool, size: int, offset: int
1144
+ self,
1145
+ typevar: typeconsts.TypeConstant | TypeVariable | DerivedTypeVariable,
1146
+ is_store: bool,
1147
+ size: int,
1148
+ offset: int,
1131
1149
  ) -> DerivedTypeVariable:
1132
1150
  if isinstance(typevar, DerivedTypeVariable):
1133
1151
  if isinstance(typevar.labels[-1], AddN):
@@ -1146,5 +1164,5 @@ class SimEngineVRBase(SimEngineLight):
1146
1164
  return DerivedTypeVariable(
1147
1165
  typevar,
1148
1166
  None,
1149
- labels=(lbl, typevars.HasField(size * self.state.arch.byte_width, offset)),
1167
+ labels=(lbl, typevars.HasField(size * self.project.arch.byte_width, offset)),
1150
1168
  )