angr 9.2.130__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 +361 -8
- 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/__init__.py +0 -3
- 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/__init__.py +5 -1
- angr/analyses/decompiler/peephole_optimizations/a_mul_const_sub_a.py +34 -0
- angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py +3 -1
- angr/analyses/decompiler/peephole_optimizations/bswap.py +10 -6
- angr/analyses/decompiler/peephole_optimizations/eager_eval.py +100 -19
- angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +17 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +42 -3
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +4 -2
- angr/analyses/decompiler/peephole_optimizations/rol_ror.py +37 -10
- angr/analyses/decompiler/peephole_optimizations/shl_to_mul.py +25 -0
- angr/analyses/decompiler/peephole_optimizations/utils.py +18 -0
- angr/analyses/decompiler/presets/fast.py +0 -2
- angr/analyses/decompiler/presets/full.py +0 -2
- angr/analyses/decompiler/ssailification/rewriting.py +1 -2
- angr/analyses/decompiler/ssailification/rewriting_engine.py +140 -57
- 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 +79 -16
- angr/analyses/decompiler/structuring/phoenix.py +40 -14
- 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 +38 -5
- angr/analyses/s_reaching_definitions/s_reaching_definitions.py +9 -5
- angr/analyses/typehoon/simple_solver.py +16 -7
- angr/analyses/typehoon/translator.py +8 -0
- angr/analyses/typehoon/typeconsts.py +10 -2
- angr/analyses/typehoon/typehoon.py +4 -1
- angr/analyses/typehoon/typevars.py +9 -7
- angr/analyses/variable_recovery/engine_ail.py +296 -256
- angr/analyses/variable_recovery/engine_base.py +137 -116
- 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 +14 -3
- 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 +17 -0
- angr/utils/formatting.py +4 -1
- angr/utils/orderedset.py +4 -1
- angr/utils/ssa/__init__.py +21 -3
- {angr-9.2.130.dist-info → angr-9.2.132.dist-info}/METADATA +6 -6
- {angr-9.2.130.dist-info → angr-9.2.132.dist-info}/RECORD +124 -123
- angr/analyses/decompiler/optimization_passes/multi_simplifier.py +0 -223
- angr/analyses/propagator/engine_ail.py +0 -1562
- angr/storage/memory_mixins/__init__.pyi +0 -48
- {angr-9.2.130.dist-info → angr-9.2.132.dist-info}/LICENSE +0 -0
- {angr-9.2.130.dist-info → angr-9.2.132.dist-info}/WHEEL +0 -0
- {angr-9.2.130.dist-info → angr-9.2.132.dist-info}/entry_points.txt +0 -0
- {angr-9.2.130.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,12 @@ 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:
|
|
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
|
|
133
|
+
elif abs_offset.op == "__mul__" and abs_offset.args[1].concrete:
|
|
134
134
|
offset = abs_offset.args[0]
|
|
135
|
-
elem_size =
|
|
135
|
+
elem_size = abs_offset.args[1].concrete_value
|
|
136
136
|
|
|
137
137
|
if base_addr is not None and offset is not None and elem_size is not None:
|
|
138
138
|
return base_addr, offset, elem_size
|
|
@@ -143,12 +143,9 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
143
143
|
#
|
|
144
144
|
|
|
145
145
|
def _ensure_variable_existence(
|
|
146
|
-
self, richr_addr: RichR, codeloc: CodeLocation, src_expr=None
|
|
147
|
-
) -> list[tuple[SimVariable, int]]
|
|
148
|
-
data
|
|
149
|
-
|
|
150
|
-
if data is None:
|
|
151
|
-
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
|
|
152
149
|
|
|
153
150
|
if self.state.is_stack_address(data):
|
|
154
151
|
# this is a stack address
|
|
@@ -206,7 +203,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
206
203
|
|
|
207
204
|
# write the variable back to stack
|
|
208
205
|
if vs is None:
|
|
209
|
-
top = self.state.top(self.arch.byte_width)
|
|
206
|
+
top = self.state.top(self.project.arch.byte_width)
|
|
210
207
|
top = self.state.annotate_with_variables(top, [(0, variable)])
|
|
211
208
|
vs = MultiValues(top)
|
|
212
209
|
self.state.stack_region.store(stack_addr, vs)
|
|
@@ -231,7 +228,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
231
228
|
existing_vars = [(variable, 0)]
|
|
232
229
|
|
|
233
230
|
else:
|
|
234
|
-
return
|
|
231
|
+
return []
|
|
235
232
|
|
|
236
233
|
# record all variables
|
|
237
234
|
for var, offset in existing_vars:
|
|
@@ -241,8 +238,8 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
241
238
|
|
|
242
239
|
return existing_vars
|
|
243
240
|
|
|
244
|
-
def _reference(self, richr: RichR, codeloc: CodeLocation, src=None):
|
|
245
|
-
data
|
|
241
|
+
def _reference(self, richr: RichR[claripy.ast.BV | claripy.ast.FP], codeloc: CodeLocation, src=None):
|
|
242
|
+
data = richr.data
|
|
246
243
|
|
|
247
244
|
if data is None:
|
|
248
245
|
return
|
|
@@ -257,7 +254,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
257
254
|
self.block.addr,
|
|
258
255
|
self.stmt_idx,
|
|
259
256
|
"memory",
|
|
260
|
-
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,
|
|
261
258
|
)
|
|
262
259
|
|
|
263
260
|
# find the correct variable
|
|
@@ -303,14 +300,17 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
303
300
|
:return:
|
|
304
301
|
"""
|
|
305
302
|
|
|
306
|
-
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
|
+
):
|
|
307
307
|
# only store the value. don't worry about variables.
|
|
308
308
|
v = MultiValues(richr.data)
|
|
309
309
|
self.state.register_region.store(offset, v)
|
|
310
310
|
return
|
|
311
311
|
|
|
312
312
|
codeloc: CodeLocation = self._codeloc()
|
|
313
|
-
data
|
|
313
|
+
data = richr.data
|
|
314
314
|
|
|
315
315
|
# lea
|
|
316
316
|
self._ensure_variable_existence(richr, codeloc)
|
|
@@ -326,7 +326,9 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
326
326
|
# next check if we are overwriting *part* of an existing variable that is not an input variable
|
|
327
327
|
addr_and_variables = set()
|
|
328
328
|
try:
|
|
329
|
-
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
|
+
)
|
|
330
332
|
for values in vs.values():
|
|
331
333
|
for value in values:
|
|
332
334
|
addr_and_variables.update(self.state.extract_variables(value))
|
|
@@ -368,8 +370,8 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
368
370
|
|
|
369
371
|
def _assign_to_vvar(
|
|
370
372
|
self,
|
|
371
|
-
vvar: ailment.
|
|
372
|
-
richr,
|
|
373
|
+
vvar: ailment.expression.VirtualVariable,
|
|
374
|
+
richr: RichR[claripy.ast.BV | claripy.ast.FP],
|
|
373
375
|
src=None,
|
|
374
376
|
dst=None,
|
|
375
377
|
create_variable: bool = True,
|
|
@@ -380,8 +382,8 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
380
382
|
vvar_id = vvar.varid
|
|
381
383
|
|
|
382
384
|
if (
|
|
383
|
-
vvar.category == ailment.
|
|
384
|
-
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)
|
|
385
387
|
or not create_variable
|
|
386
388
|
):
|
|
387
389
|
# only store the value. don't worry about variables.
|
|
@@ -389,7 +391,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
389
391
|
return
|
|
390
392
|
|
|
391
393
|
codeloc: CodeLocation = self._codeloc()
|
|
392
|
-
data
|
|
394
|
+
data = richr.data
|
|
393
395
|
|
|
394
396
|
# lea
|
|
395
397
|
self._ensure_variable_existence(richr, codeloc)
|
|
@@ -464,7 +466,9 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
464
466
|
self.state.add_type_constraint(typevars.Subtype(richr.typevar, typevar))
|
|
465
467
|
self.state.add_type_constraint(typevars.Subtype(typevar, typeconsts.int_type(variable.size * 8)))
|
|
466
468
|
|
|
467
|
-
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
|
|
468
472
|
"""
|
|
469
473
|
|
|
470
474
|
:param RichR addr:
|
|
@@ -473,16 +477,16 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
473
477
|
:return:
|
|
474
478
|
"""
|
|
475
479
|
|
|
476
|
-
addr
|
|
480
|
+
addr = richr_addr.data
|
|
477
481
|
stored = False
|
|
478
482
|
|
|
479
483
|
if addr.concrete:
|
|
480
484
|
# fully concrete. this is a global address
|
|
481
485
|
self._store_to_global(addr.concrete_value, data, size, stmt=stmt)
|
|
482
486
|
stored = True
|
|
483
|
-
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:
|
|
484
488
|
# we are storing to a concrete global address with an offset
|
|
485
|
-
base_addr, offset, elem_size =
|
|
489
|
+
base_addr, offset, elem_size = parsed
|
|
486
490
|
self._store_to_global(base_addr.concrete_value, data, size, stmt=stmt, offset=offset, elem_size=elem_size)
|
|
487
491
|
stored = True
|
|
488
492
|
else:
|
|
@@ -506,7 +510,9 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
506
510
|
# storing to a location specified by a pointer whose value cannot be determined at this point
|
|
507
511
|
self._store_to_variable(richr_addr, size, stmt=stmt)
|
|
508
512
|
|
|
509
|
-
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
|
+
):
|
|
510
516
|
if stmt is None:
|
|
511
517
|
existing_vars = self.variable_manager[self.func_addr].find_variables_by_stmt(
|
|
512
518
|
self.block.addr, self.stmt_idx, "memory"
|
|
@@ -578,7 +584,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
578
584
|
size: int,
|
|
579
585
|
stmt=None,
|
|
580
586
|
offset: claripy.ast.BV | None = None,
|
|
581
|
-
elem_size:
|
|
587
|
+
elem_size: int | None = None,
|
|
582
588
|
):
|
|
583
589
|
variable_manager = self.variable_manager["global"]
|
|
584
590
|
if stmt is None:
|
|
@@ -589,8 +595,8 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
589
595
|
if offset is None or elem_size is None:
|
|
590
596
|
# trivial case
|
|
591
597
|
abs_addr = addr
|
|
592
|
-
elif offset.concrete
|
|
593
|
-
abs_addr = addr + offset.concrete_value * elem_size
|
|
598
|
+
elif offset.concrete:
|
|
599
|
+
abs_addr = addr + offset.concrete_value * elem_size
|
|
594
600
|
else:
|
|
595
601
|
abs_addr = None
|
|
596
602
|
|
|
@@ -615,17 +621,17 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
615
621
|
|
|
616
622
|
if abs_addr is not None:
|
|
617
623
|
self.state.global_region.store(
|
|
618
|
-
addr, data_expr, endness=self.
|
|
624
|
+
addr, data_expr, endness=self.project.arch.memory_endness if stmt is None else stmt.endness
|
|
619
625
|
)
|
|
620
626
|
|
|
621
627
|
codeloc = CodeLocation(
|
|
622
628
|
self.block.addr, self.stmt_idx, ins_addr=self.ins_addr, block_idx=getattr(self.block, "idx", None)
|
|
623
629
|
)
|
|
624
|
-
values = None
|
|
630
|
+
values: MultiValues | None = None
|
|
625
631
|
if abs_addr is not None:
|
|
626
632
|
with contextlib.suppress(SimMemoryMissingError):
|
|
627
|
-
values
|
|
628
|
-
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
|
|
629
635
|
)
|
|
630
636
|
|
|
631
637
|
if values is not None:
|
|
@@ -646,8 +652,8 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
646
652
|
|
|
647
653
|
if offset is not None and elem_size is not None:
|
|
648
654
|
# it's an array!
|
|
649
|
-
if offset.concrete
|
|
650
|
-
concrete_offset = offset.concrete_value * elem_size
|
|
655
|
+
if offset.concrete:
|
|
656
|
+
concrete_offset = offset.concrete_value * elem_size
|
|
651
657
|
store_typevar = self._create_access_typevar(typevar, True, size, concrete_offset)
|
|
652
658
|
self.state.add_type_constraint(typevars.Subtype(store_typevar, typeconsts.TopType()))
|
|
653
659
|
else:
|
|
@@ -668,7 +674,9 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
668
674
|
self.state.add_type_constraint(typevars.Subtype(store_typevar, typeconsts.TopType()))
|
|
669
675
|
self.state.add_type_constraint(typevars.Subtype(data.typevar, store_typevar))
|
|
670
676
|
|
|
671
|
-
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
|
|
672
680
|
addr_variable = richr_addr.variable
|
|
673
681
|
codeloc = self._codeloc()
|
|
674
682
|
|
|
@@ -695,7 +703,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
695
703
|
self.state.typevars.add_type_variable(addr_variable, codeloc, typevar)
|
|
696
704
|
self.state.add_type_constraint(typevars.Subtype(store_typevar, typeconsts.TopType()))
|
|
697
705
|
|
|
698
|
-
def _load(self, richr_addr: RichR, size: int, expr=None):
|
|
706
|
+
def _load(self, richr_addr: RichR[claripy.ast.BV], size: int, expr=None):
|
|
699
707
|
"""
|
|
700
708
|
|
|
701
709
|
:param RichR richr_addr:
|
|
@@ -703,7 +711,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
703
711
|
:return:
|
|
704
712
|
"""
|
|
705
713
|
|
|
706
|
-
addr
|
|
714
|
+
addr = cast(claripy.ast.BV, richr_addr.data)
|
|
707
715
|
codeloc = CodeLocation(
|
|
708
716
|
self.block.addr, self.stmt_idx, ins_addr=self.ins_addr, block_idx=getattr(self.block, "idx", None)
|
|
709
717
|
)
|
|
@@ -734,14 +742,17 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
734
742
|
concrete_offset = stack_offset
|
|
735
743
|
dynamic_offset = None
|
|
736
744
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
self.state.
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
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
|
+
)
|
|
743
752
|
|
|
744
|
-
|
|
753
|
+
except SimMemoryMissingError:
|
|
754
|
+
values = None
|
|
755
|
+
else:
|
|
745
756
|
values = None
|
|
746
757
|
|
|
747
758
|
all_vars: set[tuple[int, SimVariable]] = set()
|
|
@@ -753,7 +764,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
753
764
|
var_offset = stack_offset - var_.offset
|
|
754
765
|
all_vars.add((var_offset, var_))
|
|
755
766
|
|
|
756
|
-
if not all_vars:
|
|
767
|
+
if not all_vars and concrete_offset is not None:
|
|
757
768
|
variables = self.variable_manager[self.func_addr].find_variables_by_stack_offset(concrete_offset)
|
|
758
769
|
if not variables:
|
|
759
770
|
variable = SimStackVariable(
|
|
@@ -767,28 +778,27 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
767
778
|
variables = {variable}
|
|
768
779
|
l.debug("Identified a new stack variable %s at %#x.", variable, self.ins_addr)
|
|
769
780
|
for variable in variables:
|
|
770
|
-
v = self.state.top(size * self.
|
|
781
|
+
v = self.state.top(size * self.project.arch.byte_width)
|
|
771
782
|
v = self.state.annotate_with_variables(v, [(0, variable)])
|
|
772
783
|
stack_addr = self.state.stack_addr_from_offset(concrete_offset)
|
|
773
|
-
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)
|
|
774
785
|
|
|
775
786
|
all_vars = {(0, variable) for variable in variables}
|
|
776
787
|
|
|
777
|
-
|
|
778
|
-
# overlapping variables
|
|
779
|
-
all_vars = list(all_vars)
|
|
788
|
+
all_vars_list = list(all_vars)
|
|
780
789
|
|
|
790
|
+
if len(all_vars_list) > 1:
|
|
781
791
|
# sort by some value so that the outcome here isn't random
|
|
782
|
-
|
|
792
|
+
cast(list[tuple[int, SimStackVariable]], all_vars_list).sort(
|
|
783
793
|
reverse=True,
|
|
784
794
|
key=lambda val: (val[0], val[1].offset, val[1].base, val[1].base_addr, val[1].size),
|
|
785
795
|
)
|
|
786
796
|
|
|
787
797
|
l.warning(
|
|
788
|
-
"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
|
|
789
799
|
)
|
|
790
800
|
|
|
791
|
-
var_offset, var = next(iter(
|
|
801
|
+
var_offset, var = next(iter(all_vars_list)) # won't fail
|
|
792
802
|
# calculate variable_offset
|
|
793
803
|
if dynamic_offset is None:
|
|
794
804
|
offset_into_variable = var_offset
|
|
@@ -835,8 +845,8 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
835
845
|
# | typevars.HasField(size * 8, 0)
|
|
836
846
|
# | )
|
|
837
847
|
|
|
838
|
-
r = self.state.top(size * self.
|
|
839
|
-
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)
|
|
840
850
|
return RichR(r, variable=var, typevar=typevar)
|
|
841
851
|
|
|
842
852
|
elif addr.concrete:
|
|
@@ -844,9 +854,9 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
844
854
|
v = self._load_from_global(addr.concrete_value, size, expr=expr)
|
|
845
855
|
typevar = v.typevar
|
|
846
856
|
|
|
847
|
-
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:
|
|
848
858
|
# Loading data from a memory address with an offset
|
|
849
|
-
base_addr, offset, elem_size =
|
|
859
|
+
base_addr, offset, elem_size = parsed
|
|
850
860
|
v = self._load_from_global(base_addr.concrete_value, size, expr=expr, offset=offset, elem_size=elem_size)
|
|
851
861
|
typevar = v.typevar
|
|
852
862
|
|
|
@@ -880,7 +890,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
880
890
|
typevar = self._create_access_typevar(richr_addr_typevar, False, size, offset)
|
|
881
891
|
self.state.add_type_constraint(typevars.Subtype(typevar, typeconsts.TopType()))
|
|
882
892
|
|
|
883
|
-
return RichR(self.state.top(size * self.
|
|
893
|
+
return RichR(self.state.top(size * self.project.arch.byte_width), typevar=typevar)
|
|
884
894
|
|
|
885
895
|
def _load_from_global(
|
|
886
896
|
self,
|
|
@@ -888,8 +898,8 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
888
898
|
size,
|
|
889
899
|
expr=None,
|
|
890
900
|
offset: claripy.ast.BV | None = None,
|
|
891
|
-
elem_size:
|
|
892
|
-
) -> RichR:
|
|
901
|
+
elem_size: int | None = None,
|
|
902
|
+
) -> RichR[claripy.ast.BV]:
|
|
893
903
|
variable_manager = self.variable_manager["global"]
|
|
894
904
|
if expr is None:
|
|
895
905
|
existing_vars = variable_manager.find_variables_by_stmt(self.block.addr, self.stmt_idx, "memory")
|
|
@@ -911,7 +921,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
911
921
|
if not existing_vars:
|
|
912
922
|
# is this address mapped?
|
|
913
923
|
if self.project.loader.find_object_containing(addr) is None:
|
|
914
|
-
return RichR(self.state.top(size * self.
|
|
924
|
+
return RichR(self.state.top(size * self.project.arch.byte_width))
|
|
915
925
|
variable = SimMemoryVariable(
|
|
916
926
|
addr,
|
|
917
927
|
size,
|
|
@@ -937,8 +947,8 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
937
947
|
|
|
938
948
|
if offset is not None and elem_size is not None:
|
|
939
949
|
# it's an array!
|
|
940
|
-
if offset.concrete
|
|
941
|
-
concrete_offset = offset.concrete_value * elem_size
|
|
950
|
+
if offset.concrete:
|
|
951
|
+
concrete_offset = offset.concrete_value * elem_size
|
|
942
952
|
load_typevar = self._create_access_typevar(typevar, True, size, concrete_offset)
|
|
943
953
|
self.state.add_type_constraint(typevars.Subtype(load_typevar, typeconsts.TopType()))
|
|
944
954
|
else:
|
|
@@ -948,7 +958,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
948
958
|
load_typevar = self._create_access_typevar(typevar, True, size, concrete_offset)
|
|
949
959
|
self.state.add_type_constraint(typevars.Subtype(load_typevar, typeconsts.TopType()))
|
|
950
960
|
|
|
951
|
-
return RichR(self.state.top(size * self.
|
|
961
|
+
return RichR(self.state.top(size * self.project.arch.byte_width), typevar=typevar)
|
|
952
962
|
|
|
953
963
|
def _read_from_register(self, offset, size, expr=None, force_variable_size=None, create_variable: bool = True):
|
|
954
964
|
"""
|
|
@@ -965,17 +975,17 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
965
975
|
except SimMemoryMissingError:
|
|
966
976
|
values = None
|
|
967
977
|
|
|
968
|
-
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):
|
|
969
979
|
# load values. don't worry about variables
|
|
970
980
|
if values is None:
|
|
971
|
-
r_value = self.state.top(size * self.arch.byte_width)
|
|
981
|
+
r_value = self.state.top(size * self.project.arch.byte_width)
|
|
972
982
|
else:
|
|
973
983
|
r_value = next(iter(next(iter(values.values()))))
|
|
974
984
|
return RichR(r_value, variable=None, typevar=None)
|
|
975
985
|
|
|
976
986
|
if not values:
|
|
977
987
|
# the value does not exist.
|
|
978
|
-
value = self.state.top(size * self.
|
|
988
|
+
value = self.state.top(size * self.project.arch.byte_width)
|
|
979
989
|
if create_variable:
|
|
980
990
|
# create a new variable if necessary
|
|
981
991
|
variable = SimRegisterVariable(
|
|
@@ -998,7 +1008,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
998
1008
|
self.variable_manager[self.func_addr].read_from(var, None, codeloc, atom=expr, overwrite=False)
|
|
999
1009
|
variable_set.add(var)
|
|
1000
1010
|
|
|
1001
|
-
if offset == self.arch.sp_offset:
|
|
1011
|
+
if offset == self.project.arch.sp_offset:
|
|
1002
1012
|
# ignore sp
|
|
1003
1013
|
typevar = None
|
|
1004
1014
|
var = None
|
|
@@ -1025,7 +1035,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
1025
1035
|
typevar = self.state.typevars[var]
|
|
1026
1036
|
|
|
1027
1037
|
r_value = (
|
|
1028
|
-
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)
|
|
1029
1039
|
) # fall back to top
|
|
1030
1040
|
if var is not None and var.size != size:
|
|
1031
1041
|
# ignore the variable and the associated type if we are only reading part of the variable
|
|
@@ -1033,22 +1043,26 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
1033
1043
|
return RichR(r_value, variable=var, typevar=typevar)
|
|
1034
1044
|
|
|
1035
1045
|
def _read_from_vvar(
|
|
1036
|
-
self,
|
|
1046
|
+
self,
|
|
1047
|
+
vvar: ailment.expression.VirtualVariable,
|
|
1048
|
+
expr=None,
|
|
1049
|
+
create_variable: bool = True,
|
|
1050
|
+
vvar_id: int | None = None,
|
|
1037
1051
|
):
|
|
1038
1052
|
codeloc = self._codeloc()
|
|
1039
1053
|
|
|
1040
1054
|
if vvar_id is None:
|
|
1041
1055
|
vvar_id = vvar.varid
|
|
1042
1056
|
|
|
1043
|
-
value: claripy.ast.
|
|
1057
|
+
value: claripy.ast.BV | None = self.vvar_region.get(vvar_id, None)
|
|
1044
1058
|
|
|
1045
1059
|
# fallback for register arguments
|
|
1046
1060
|
if value is None and vvar.was_reg:
|
|
1047
1061
|
return self._read_from_register(vvar.reg_offset, vvar.size, expr=vvar, create_variable=True)
|
|
1048
1062
|
|
|
1049
1063
|
if vvar.category == ailment.Expr.VirtualVariableCategory.REGISTER and vvar.oident in (
|
|
1050
|
-
self.arch.sp_offset,
|
|
1051
|
-
self.arch.ip_offset,
|
|
1064
|
+
self.project.arch.sp_offset,
|
|
1065
|
+
self.project.arch.ip_offset,
|
|
1052
1066
|
):
|
|
1053
1067
|
# load values. don't worry about variables
|
|
1054
1068
|
r_value = self.state.top(vvar.size) if value is None else value
|
|
@@ -1092,7 +1106,10 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
1092
1106
|
self.variable_manager[self.func_addr].read_from(var, None, codeloc, atom=expr, overwrite=False)
|
|
1093
1107
|
variable_set.add(var)
|
|
1094
1108
|
|
|
1095
|
-
if
|
|
1109
|
+
if (
|
|
1110
|
+
vvar.category == ailment.Expr.VirtualVariableCategory.REGISTER
|
|
1111
|
+
and vvar.oident == self.project.arch.sp_offset
|
|
1112
|
+
):
|
|
1096
1113
|
# ignore sp
|
|
1097
1114
|
typevar = None
|
|
1098
1115
|
var = None
|
|
@@ -1124,7 +1141,11 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
1124
1141
|
return RichR(value, variable=var, typevar=typevar)
|
|
1125
1142
|
|
|
1126
1143
|
def _create_access_typevar(
|
|
1127
|
-
self,
|
|
1144
|
+
self,
|
|
1145
|
+
typevar: typeconsts.TypeConstant | TypeVariable | DerivedTypeVariable,
|
|
1146
|
+
is_store: bool,
|
|
1147
|
+
size: int,
|
|
1148
|
+
offset: int,
|
|
1128
1149
|
) -> DerivedTypeVariable:
|
|
1129
1150
|
if isinstance(typevar, DerivedTypeVariable):
|
|
1130
1151
|
if isinstance(typevar.labels[-1], AddN):
|
|
@@ -1143,5 +1164,5 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
1143
1164
|
return DerivedTypeVariable(
|
|
1144
1165
|
typevar,
|
|
1145
1166
|
None,
|
|
1146
|
-
labels=(lbl, typevars.HasField(size * self.
|
|
1167
|
+
labels=(lbl, typevars.HasField(size * self.project.arch.byte_width, offset)),
|
|
1147
1168
|
)
|