angr 9.2.131__py3-none-manylinux2014_aarch64.whl → 9.2.132__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.
- angr/__init__.py +1 -1
- angr/analyses/analysis.py +6 -2
- angr/analyses/cfg/cfg_emulated.py +5 -5
- angr/analyses/cfg/cfg_fast.py +2 -2
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +139 -94
- angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +1 -1
- angr/analyses/ddg.py +14 -11
- angr/analyses/decompiler/ail_simplifier.py +3 -2
- angr/analyses/decompiler/block_simplifier.py +10 -21
- angr/analyses/decompiler/clinic.py +108 -34
- angr/analyses/decompiler/condition_processor.py +12 -10
- angr/analyses/decompiler/dephication/graph_rewriting.py +1 -1
- angr/analyses/decompiler/dephication/rewriting_engine.py +169 -45
- angr/analyses/decompiler/dephication/seqnode_dephication.py +5 -4
- angr/analyses/decompiler/optimization_passes/const_derefs.py +1 -0
- angr/analyses/decompiler/optimization_passes/div_simplifier.py +41 -16
- angr/analyses/decompiler/optimization_passes/engine_base.py +261 -83
- angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +173 -35
- angr/analyses/decompiler/optimization_passes/mod_simplifier.py +5 -2
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +39 -19
- angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +2 -0
- angr/analyses/decompiler/ssailification/rewriting.py +1 -2
- angr/analyses/decompiler/ssailification/rewriting_engine.py +138 -55
- angr/analyses/decompiler/ssailification/ssailification.py +2 -1
- angr/analyses/decompiler/ssailification/traversal.py +4 -6
- angr/analyses/decompiler/ssailification/traversal_engine.py +125 -42
- angr/analyses/decompiler/structured_codegen/c.py +5 -3
- angr/analyses/decompiler/structuring/phoenix.py +26 -9
- angr/analyses/decompiler/structuring/structurer_nodes.py +9 -0
- angr/analyses/deobfuscator/irsb_reg_collector.py +29 -60
- angr/analyses/deobfuscator/string_obf_finder.py +2 -2
- angr/analyses/init_finder.py +47 -22
- angr/analyses/propagator/engine_base.py +21 -14
- angr/analyses/propagator/engine_vex.py +149 -179
- angr/analyses/propagator/propagator.py +10 -28
- angr/analyses/propagator/top_checker_mixin.py +211 -5
- angr/analyses/propagator/vex_vars.py +1 -1
- angr/analyses/reaching_definitions/dep_graph.py +1 -1
- angr/analyses/reaching_definitions/engine_ail.py +304 -329
- angr/analyses/reaching_definitions/engine_vex.py +243 -229
- angr/analyses/reaching_definitions/function_handler.py +3 -3
- angr/analyses/reaching_definitions/rd_state.py +37 -32
- angr/analyses/s_propagator.py +18 -3
- angr/analyses/s_reaching_definitions/s_reaching_definitions.py +9 -5
- angr/analyses/typehoon/simple_solver.py +7 -5
- angr/analyses/typehoon/translator.py +8 -0
- angr/analyses/typehoon/typeconsts.py +10 -2
- angr/analyses/typehoon/typevars.py +9 -7
- angr/analyses/variable_recovery/engine_ail.py +299 -259
- angr/analyses/variable_recovery/engine_base.py +135 -117
- angr/analyses/variable_recovery/engine_vex.py +175 -185
- angr/analyses/variable_recovery/irsb_scanner.py +49 -38
- angr/analyses/variable_recovery/variable_recovery.py +28 -5
- angr/analyses/variable_recovery/variable_recovery_base.py +32 -33
- angr/analyses/variable_recovery/variable_recovery_fast.py +2 -2
- angr/analyses/xrefs.py +46 -19
- angr/annocfg.py +19 -14
- angr/block.py +4 -9
- angr/calling_conventions.py +1 -1
- angr/engines/engine.py +30 -14
- angr/engines/light/__init__.py +11 -3
- angr/engines/light/engine.py +1003 -1185
- angr/engines/pcode/cc.py +2 -0
- angr/engines/successors.py +13 -9
- angr/engines/vex/claripy/datalayer.py +1 -1
- angr/engines/vex/claripy/irop.py +1 -1
- angr/engines/vex/light/slicing.py +2 -2
- angr/exploration_techniques/__init__.py +1 -124
- angr/exploration_techniques/base.py +126 -0
- angr/exploration_techniques/bucketizer.py +1 -1
- angr/exploration_techniques/dfs.py +3 -1
- angr/exploration_techniques/director.py +2 -3
- angr/exploration_techniques/driller_core.py +1 -1
- angr/exploration_techniques/explorer.py +4 -2
- angr/exploration_techniques/lengthlimiter.py +2 -1
- angr/exploration_techniques/local_loop_seer.py +2 -1
- angr/exploration_techniques/loop_seer.py +5 -5
- angr/exploration_techniques/manual_mergepoint.py +2 -1
- angr/exploration_techniques/memory_watcher.py +3 -1
- angr/exploration_techniques/oppologist.py +4 -5
- angr/exploration_techniques/slicecutor.py +4 -2
- angr/exploration_techniques/spiller.py +1 -1
- angr/exploration_techniques/stochastic.py +2 -1
- angr/exploration_techniques/stub_stasher.py +2 -1
- angr/exploration_techniques/suggestions.py +3 -1
- angr/exploration_techniques/symbion.py +3 -1
- angr/exploration_techniques/tech_builder.py +2 -1
- angr/exploration_techniques/threading.py +4 -7
- angr/exploration_techniques/timeout.py +4 -2
- angr/exploration_techniques/tracer.py +4 -3
- angr/exploration_techniques/unique.py +3 -2
- angr/exploration_techniques/veritesting.py +1 -1
- angr/knowledge_plugins/key_definitions/atoms.py +2 -2
- angr/knowledge_plugins/key_definitions/live_definitions.py +16 -13
- angr/knowledge_plugins/propagations/states.py +13 -8
- angr/knowledge_plugins/variables/variable_manager.py +23 -9
- angr/sim_manager.py +1 -3
- angr/sim_state.py +39 -41
- angr/sim_type.py +5 -0
- angr/sim_variable.py +29 -28
- angr/utils/bits.py +12 -0
- angr/utils/orderedset.py +4 -1
- angr/utils/ssa/__init__.py +21 -3
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/METADATA +6 -6
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/RECORD +109 -110
- angr/analyses/propagator/engine_ail.py +0 -1562
- angr/storage/memory_mixins/__init__.pyi +0 -48
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/LICENSE +0 -0
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/WHEEL +0 -0
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/entry_points.txt +0 -0
- {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
|
|
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
|
-
|
|
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:
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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):
|
|
89
|
+
def process(self, state, *args, **kwargs):
|
|
89
90
|
self.variable_manager = state.variable_manager
|
|
91
|
+
super().process(state, *args, **kwargs)
|
|
90
92
|
|
|
91
|
-
|
|
92
|
-
|
|
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
|
|
98
|
-
self
|
|
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.
|
|
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.
|
|
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]]
|
|
151
|
-
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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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.
|
|
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.
|
|
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
|
|
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(
|
|
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
|
|
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 =
|
|
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(
|
|
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:
|
|
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
|
|
596
|
-
abs_addr = addr + offset.concrete_value * elem_size
|
|
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.
|
|
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
|
|
631
|
-
abs_addr, size=size, endness=self.
|
|
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
|
|
653
|
-
concrete_offset = offset.concrete_value * elem_size
|
|
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(
|
|
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
|
|
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
|
-
|
|
741
|
-
|
|
742
|
-
self.state.
|
|
743
|
-
|
|
744
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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.",
|
|
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(
|
|
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.
|
|
842
|
-
r = self.state.annotate_with_variables(r,
|
|
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 =
|
|
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.
|
|
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:
|
|
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.
|
|
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
|
|
944
|
-
concrete_offset = offset.concrete_value * elem_size
|
|
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.
|
|
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.
|
|
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,
|
|
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.
|
|
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
|
|
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,
|
|
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.
|
|
1167
|
+
labels=(lbl, typevars.HasField(size * self.project.arch.byte_width, offset)),
|
|
1150
1168
|
)
|