angr 9.2.139__py3-none-manylinux2014_x86_64.whl → 9.2.141__py3-none-manylinux2014_x86_64.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/calling_convention/calling_convention.py +136 -53
- angr/analyses/calling_convention/fact_collector.py +44 -18
- angr/analyses/calling_convention/utils.py +3 -1
- angr/analyses/cfg/cfg_base.py +13 -0
- angr/analyses/cfg/cfg_fast.py +11 -0
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +9 -8
- angr/analyses/decompiler/ail_simplifier.py +115 -72
- angr/analyses/decompiler/callsite_maker.py +24 -11
- angr/analyses/decompiler/clinic.py +78 -43
- angr/analyses/decompiler/decompiler.py +18 -7
- angr/analyses/decompiler/expression_narrower.py +1 -1
- angr/analyses/decompiler/optimization_passes/const_prop_reverter.py +8 -7
- angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +3 -1
- angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +21 -2
- angr/analyses/decompiler/optimization_passes/ite_region_converter.py +21 -13
- angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +84 -15
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +92 -11
- angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +53 -9
- angr/analyses/decompiler/peephole_optimizations/eager_eval.py +44 -7
- angr/analyses/decompiler/region_identifier.py +6 -4
- angr/analyses/decompiler/region_simplifiers/expr_folding.py +287 -122
- angr/analyses/decompiler/region_simplifiers/region_simplifier.py +31 -13
- angr/analyses/decompiler/ssailification/rewriting.py +23 -15
- angr/analyses/decompiler/ssailification/rewriting_engine.py +105 -24
- angr/analyses/decompiler/ssailification/ssailification.py +22 -14
- angr/analyses/decompiler/structured_codegen/c.py +73 -137
- angr/analyses/decompiler/structuring/dream.py +22 -18
- angr/analyses/decompiler/structuring/phoenix.py +158 -41
- angr/analyses/decompiler/structuring/recursive_structurer.py +1 -0
- angr/analyses/decompiler/structuring/structurer_base.py +37 -10
- angr/analyses/decompiler/structuring/structurer_nodes.py +4 -1
- angr/analyses/decompiler/utils.py +106 -21
- angr/analyses/deobfuscator/api_obf_finder.py +8 -5
- angr/analyses/deobfuscator/api_obf_type2_finder.py +18 -10
- angr/analyses/deobfuscator/string_obf_finder.py +105 -18
- angr/analyses/forward_analysis/forward_analysis.py +1 -1
- angr/analyses/propagator/top_checker_mixin.py +6 -6
- angr/analyses/reaching_definitions/__init__.py +2 -1
- angr/analyses/reaching_definitions/dep_graph.py +1 -12
- angr/analyses/reaching_definitions/engine_vex.py +36 -31
- angr/analyses/reaching_definitions/function_handler.py +15 -2
- angr/analyses/reaching_definitions/rd_state.py +1 -37
- angr/analyses/reaching_definitions/reaching_definitions.py +13 -24
- angr/analyses/s_propagator.py +6 -41
- angr/analyses/s_reaching_definitions/s_rda_model.py +7 -1
- angr/analyses/s_reaching_definitions/s_rda_view.py +43 -25
- angr/analyses/stack_pointer_tracker.py +36 -22
- angr/analyses/typehoon/simple_solver.py +45 -7
- angr/analyses/typehoon/typeconsts.py +18 -5
- angr/analyses/variable_recovery/engine_ail.py +1 -1
- angr/analyses/variable_recovery/engine_base.py +7 -5
- angr/analyses/variable_recovery/engine_vex.py +20 -4
- angr/block.py +69 -107
- angr/callable.py +14 -7
- angr/calling_conventions.py +30 -11
- angr/distributed/__init__.py +1 -1
- angr/engines/__init__.py +7 -8
- angr/engines/engine.py +1 -120
- angr/engines/failure.py +2 -2
- angr/engines/hook.py +2 -2
- angr/engines/light/engine.py +2 -2
- angr/engines/pcode/engine.py +2 -14
- angr/engines/procedure.py +2 -2
- angr/engines/soot/engine.py +2 -2
- angr/engines/soot/statements/switch.py +1 -1
- angr/engines/successors.py +124 -11
- angr/engines/syscall.py +2 -2
- angr/engines/unicorn.py +3 -3
- angr/engines/vex/heavy/heavy.py +3 -15
- angr/factory.py +12 -22
- angr/knowledge_plugins/key_definitions/atoms.py +8 -4
- angr/knowledge_plugins/key_definitions/live_definitions.py +41 -103
- angr/knowledge_plugins/variables/variable_manager.py +7 -5
- angr/sim_type.py +19 -17
- angr/simos/simos.py +3 -1
- angr/state_plugins/plugin.py +19 -4
- angr/storage/memory_mixins/memory_mixin.py +1 -1
- angr/storage/memory_mixins/paged_memory/pages/multi_values.py +10 -5
- angr/utils/ssa/__init__.py +119 -4
- angr/utils/types.py +48 -0
- {angr-9.2.139.dist-info → angr-9.2.141.dist-info}/METADATA +6 -6
- {angr-9.2.139.dist-info → angr-9.2.141.dist-info}/RECORD +87 -86
- {angr-9.2.139.dist-info → angr-9.2.141.dist-info}/LICENSE +0 -0
- {angr-9.2.139.dist-info → angr-9.2.141.dist-info}/WHEEL +0 -0
- {angr-9.2.139.dist-info → angr-9.2.141.dist-info}/entry_points.txt +0 -0
- {angr-9.2.139.dist-info → angr-9.2.141.dist-info}/top_level.txt +0 -0
angr/engines/vex/heavy/heavy.py
CHANGED
|
@@ -3,7 +3,7 @@ import logging
|
|
|
3
3
|
import claripy
|
|
4
4
|
import pyvex
|
|
5
5
|
|
|
6
|
-
from angr.engines.
|
|
6
|
+
from angr.engines.successors import SuccessorsEngine
|
|
7
7
|
from angr.engines.vex.light import VEXMixin
|
|
8
8
|
from angr.engines.vex.lifter import VEXLifter
|
|
9
9
|
from angr.engines.vex.claripy.datalayer import ClaripyDataMixin, symbol
|
|
@@ -57,7 +57,7 @@ class SimStateStorageMixin(VEXMixin):
|
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
# pylint:disable=arguments-differ
|
|
60
|
-
class HeavyVEXMixin(
|
|
60
|
+
class HeavyVEXMixin(SuccessorsEngine, ClaripyDataMixin, SimStateStorageMixin, VEXMixin, VEXLifter):
|
|
61
61
|
"""
|
|
62
62
|
Execution engine based on VEX, Valgrind's IR.
|
|
63
63
|
|
|
@@ -83,7 +83,6 @@ class HeavyVEXMixin(SuccessorsMixin, ClaripyDataMixin, SimStateStorageMixin, VEX
|
|
|
83
83
|
self,
|
|
84
84
|
successors,
|
|
85
85
|
irsb=None,
|
|
86
|
-
insn_text=None,
|
|
87
86
|
insn_bytes=None,
|
|
88
87
|
thumb=False,
|
|
89
88
|
size=None,
|
|
@@ -99,21 +98,10 @@ class HeavyVEXMixin(SuccessorsMixin, ClaripyDataMixin, SimStateStorageMixin, VEX
|
|
|
99
98
|
extra_stop_points=extra_stop_points,
|
|
100
99
|
num_inst=num_inst,
|
|
101
100
|
size=size,
|
|
102
|
-
insn_text=insn_text,
|
|
103
101
|
insn_bytes=insn_bytes,
|
|
104
102
|
**kwargs,
|
|
105
103
|
)
|
|
106
104
|
|
|
107
|
-
if insn_text is not None:
|
|
108
|
-
if insn_bytes is not None:
|
|
109
|
-
raise errors.SimEngineError("You cannot provide both 'insn_bytes' and 'insn_text'!")
|
|
110
|
-
|
|
111
|
-
insn_bytes = self.project.arch.asm(insn_text, addr=successors.addr, thumb=thumb)
|
|
112
|
-
if insn_bytes is None:
|
|
113
|
-
raise errors.AngrAssemblyError(
|
|
114
|
-
"Assembling failed. Please make sure keystone is installed, and the assembly string is correct."
|
|
115
|
-
)
|
|
116
|
-
|
|
117
105
|
successors.sort = "IRSB"
|
|
118
106
|
successors.description = "IRSB"
|
|
119
107
|
self.state.history.recent_block_count = 1
|
|
@@ -137,9 +125,9 @@ class HeavyVEXMixin(SuccessorsMixin, ClaripyDataMixin, SimStateStorageMixin, VEX
|
|
|
137
125
|
|
|
138
126
|
if irsb is None:
|
|
139
127
|
irsb = self.lift_vex(
|
|
128
|
+
insn_bytes=insn_bytes,
|
|
140
129
|
addr=addr,
|
|
141
130
|
state=self.state,
|
|
142
|
-
insn_bytes=insn_bytes,
|
|
143
131
|
thumb=thumb,
|
|
144
132
|
size=size,
|
|
145
133
|
num_inst=num_inst,
|
angr/factory.py
CHANGED
|
@@ -7,10 +7,11 @@ from typing import overload, TYPE_CHECKING
|
|
|
7
7
|
import archinfo
|
|
8
8
|
from archinfo.arch_soot import ArchSoot, SootAddressDescriptor
|
|
9
9
|
|
|
10
|
+
from .knowledge_plugins.functions import Function
|
|
10
11
|
from .sim_state import SimState
|
|
11
12
|
from .calling_conventions import default_cc, SimRegArg, SimStackArg, PointerWrapper, SimCCUnknown
|
|
12
13
|
from .callable import Callable
|
|
13
|
-
from .errors import
|
|
14
|
+
from .errors import AngrError
|
|
14
15
|
from .engines import UberEngine, ProcedureEngine
|
|
15
16
|
from .sim_type import SimTypeFunction, SimTypeInt
|
|
16
17
|
from .codenode import HookNode, SyscallNode
|
|
@@ -236,7 +237,7 @@ class AngrObjectFactory:
|
|
|
236
237
|
|
|
237
238
|
def callable(
|
|
238
239
|
self,
|
|
239
|
-
addr,
|
|
240
|
+
addr: int | Function,
|
|
240
241
|
prototype=None,
|
|
241
242
|
concrete_only=False,
|
|
242
243
|
perform_merge=True,
|
|
@@ -245,22 +246,28 @@ class AngrObjectFactory:
|
|
|
245
246
|
cc=None,
|
|
246
247
|
add_options=None,
|
|
247
248
|
remove_options=None,
|
|
249
|
+
step_limit: int | None = None,
|
|
248
250
|
):
|
|
249
251
|
"""
|
|
250
252
|
A Callable is a representation of a function in the binary that can be interacted with like a native python
|
|
251
253
|
function.
|
|
252
254
|
|
|
253
|
-
:param addr: The address of the function to use
|
|
254
|
-
|
|
255
|
+
:param addr: The address of the function to use. If you pass in the function object, we will take
|
|
256
|
+
its addr.
|
|
257
|
+
:param prototype: The prototype of the call to use, as a string or a SimTypeFunction
|
|
255
258
|
:param concrete_only: Throw an exception if the execution splits into multiple states
|
|
256
259
|
:param perform_merge: Merge all result states into one at the end (only relevant if concrete_only=False)
|
|
257
260
|
:param base_state: The state from which to do these runs
|
|
258
261
|
:param toc: The address of the table of contents for ppc64
|
|
259
262
|
:param cc: The SimCC to use for a calling convention
|
|
263
|
+
:param step_limit: The maximum number of blocks that Callable will execute before pruning the path.
|
|
260
264
|
:returns: A Callable object that can be used as a interface for executing guest code like a
|
|
261
265
|
python function.
|
|
262
266
|
:rtype: angr.callable.Callable
|
|
263
267
|
"""
|
|
268
|
+
if isinstance(addr, Function):
|
|
269
|
+
addr = addr.addr
|
|
270
|
+
|
|
264
271
|
return Callable(
|
|
265
272
|
self.project,
|
|
266
273
|
addr=addr,
|
|
@@ -272,6 +279,7 @@ class AngrObjectFactory:
|
|
|
272
279
|
cc=cc,
|
|
273
280
|
add_options=add_options,
|
|
274
281
|
remove_options=remove_options,
|
|
282
|
+
step_limit=step_limit,
|
|
275
283
|
)
|
|
276
284
|
|
|
277
285
|
def cc(self):
|
|
@@ -300,7 +308,6 @@ class AngrObjectFactory:
|
|
|
300
308
|
size=None,
|
|
301
309
|
max_size=None,
|
|
302
310
|
byte_string=None,
|
|
303
|
-
vex=None,
|
|
304
311
|
thumb=False,
|
|
305
312
|
backup_state=None,
|
|
306
313
|
extra_stop_points=None,
|
|
@@ -308,7 +315,6 @@ class AngrObjectFactory:
|
|
|
308
315
|
num_inst=None,
|
|
309
316
|
traceflags=0,
|
|
310
317
|
insn_bytes=None,
|
|
311
|
-
insn_text=None, # backward compatibility
|
|
312
318
|
strict_block_end=None,
|
|
313
319
|
collect_data_refs=False,
|
|
314
320
|
cross_insn_opt=True,
|
|
@@ -326,7 +332,6 @@ class AngrObjectFactory:
|
|
|
326
332
|
size=None,
|
|
327
333
|
max_size=None,
|
|
328
334
|
byte_string=None,
|
|
329
|
-
vex=None,
|
|
330
335
|
thumb=False,
|
|
331
336
|
backup_state=None,
|
|
332
337
|
extra_stop_points=None,
|
|
@@ -334,7 +339,6 @@ class AngrObjectFactory:
|
|
|
334
339
|
num_inst=None,
|
|
335
340
|
traceflags=0,
|
|
336
341
|
insn_bytes=None,
|
|
337
|
-
insn_text=None, # backward compatibility
|
|
338
342
|
strict_block_end=None,
|
|
339
343
|
collect_data_refs=False,
|
|
340
344
|
load_from_ro_regions=False,
|
|
@@ -349,7 +353,6 @@ class AngrObjectFactory:
|
|
|
349
353
|
size=None,
|
|
350
354
|
max_size=None,
|
|
351
355
|
byte_string=None,
|
|
352
|
-
vex=None,
|
|
353
356
|
thumb=False,
|
|
354
357
|
backup_state=None,
|
|
355
358
|
extra_stop_points=None,
|
|
@@ -357,7 +360,6 @@ class AngrObjectFactory:
|
|
|
357
360
|
num_inst=None,
|
|
358
361
|
traceflags=0,
|
|
359
362
|
insn_bytes=None,
|
|
360
|
-
insn_text=None, # backward compatibility
|
|
361
363
|
strict_block_end=None,
|
|
362
364
|
collect_data_refs=False,
|
|
363
365
|
cross_insn_opt=True,
|
|
@@ -369,27 +371,15 @@ class AngrObjectFactory:
|
|
|
369
371
|
if isinstance(self.project.arch, ArchSoot) and isinstance(addr, SootAddressDescriptor):
|
|
370
372
|
return SootBlock(addr, arch=self.project.arch, project=self.project)
|
|
371
373
|
|
|
372
|
-
if insn_bytes is not None and insn_text is not None:
|
|
373
|
-
raise AngrError("You cannot provide both 'insn_bytes' and 'insn_text'!")
|
|
374
|
-
|
|
375
374
|
if insn_bytes is not None:
|
|
376
375
|
byte_string = insn_bytes
|
|
377
376
|
|
|
378
|
-
if insn_text is not None:
|
|
379
|
-
byte_string = self.project.arch.asm(insn_text, addr=addr, as_bytes=True, thumb=thumb)
|
|
380
|
-
if byte_string is None:
|
|
381
|
-
# assembly failed
|
|
382
|
-
raise AngrAssemblyError(
|
|
383
|
-
"Assembling failed. Please make sure keystone is installed, and the assembly string is correct."
|
|
384
|
-
)
|
|
385
|
-
|
|
386
377
|
return Block(
|
|
387
378
|
addr,
|
|
388
379
|
project=self.project,
|
|
389
380
|
size=size,
|
|
390
381
|
max_size=max_size,
|
|
391
382
|
byte_string=byte_string,
|
|
392
|
-
vex=vex,
|
|
393
383
|
extra_stop_points=extra_stop_points,
|
|
394
384
|
thumb=thumb,
|
|
395
385
|
backup_state=backup_state,
|
|
@@ -3,7 +3,7 @@ from enum import Enum, auto
|
|
|
3
3
|
|
|
4
4
|
import claripy
|
|
5
5
|
import ailment
|
|
6
|
-
from archinfo import Arch, RegisterOffset
|
|
6
|
+
from archinfo import Arch, Endness, RegisterOffset
|
|
7
7
|
|
|
8
8
|
from angr.calling_conventions import SimFunctionArgument, SimRegArg, SimStackArg
|
|
9
9
|
from angr.engines.light import SpOffset
|
|
@@ -123,7 +123,7 @@ class Atom:
|
|
|
123
123
|
register = reg
|
|
124
124
|
|
|
125
125
|
@staticmethod
|
|
126
|
-
def mem(addr: SpOffset | HeapAddress | int, size: int, endness:
|
|
126
|
+
def mem(addr: SpOffset | HeapAddress | int, size: int, endness: Endness | None = None) -> MemoryLocation:
|
|
127
127
|
"""
|
|
128
128
|
Create a MemoryLocation atom,
|
|
129
129
|
|
|
@@ -251,7 +251,11 @@ class VirtualVariable(Atom):
|
|
|
251
251
|
)
|
|
252
252
|
|
|
253
253
|
def __init__(
|
|
254
|
-
self,
|
|
254
|
+
self,
|
|
255
|
+
varid: int,
|
|
256
|
+
size: int,
|
|
257
|
+
category: ailment.Expr.VirtualVariableCategory,
|
|
258
|
+
oident: str | int | tuple | None = None,
|
|
255
259
|
):
|
|
256
260
|
super().__init__(size)
|
|
257
261
|
|
|
@@ -310,7 +314,7 @@ class MemoryLocation(Atom):
|
|
|
310
314
|
"endness",
|
|
311
315
|
)
|
|
312
316
|
|
|
313
|
-
def __init__(self, addr: SpOffset | HeapAddress | int, size: int, endness:
|
|
317
|
+
def __init__(self, addr: SpOffset | HeapAddress | int, size: int, endness: Endness | None = None):
|
|
314
318
|
"""
|
|
315
319
|
:param int addr: The address of the beginning memory location slice.
|
|
316
320
|
:param int size: The size of the represented memory location, in bytes.
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
from typing import Any, TYPE_CHECKING, cast, overload
|
|
3
|
+
from collections import defaultdict
|
|
3
4
|
from collections.abc import Iterable, Generator
|
|
5
|
+
from enum import Enum, auto
|
|
4
6
|
import weakref
|
|
5
7
|
import logging
|
|
6
|
-
from enum import Enum, auto
|
|
7
|
-
|
|
8
|
-
from collections import defaultdict
|
|
9
8
|
|
|
10
9
|
import claripy
|
|
11
10
|
from claripy.annotation import Annotation
|
|
12
11
|
import archinfo
|
|
13
12
|
|
|
14
|
-
from angr.misc.ux import deprecated
|
|
15
13
|
from angr.errors import SimMemoryMissingError, SimMemoryError
|
|
16
14
|
from angr.storage.memory_mixins import MultiValuedMemory
|
|
17
15
|
from angr.storage.memory_mixins.paged_memory.pages.multi_values import MVType, MultiValues
|
|
18
16
|
from angr.knowledge_plugins.key_definitions.definition import A
|
|
19
17
|
from angr.engines.light import SpOffset
|
|
20
18
|
from angr.code_location import CodeLocation, ExternalCodeLocation
|
|
19
|
+
from angr.utils.constants import is_alignment_mask
|
|
21
20
|
from .atoms import Atom, Register, MemoryLocation, Tmp, ConstantSrc
|
|
22
21
|
from .definition import Definition, Tag
|
|
23
22
|
from .heap_address import HeapAddress
|
|
23
|
+
from .undefined import Undefined
|
|
24
24
|
from .uses import Uses
|
|
25
25
|
|
|
26
26
|
if TYPE_CHECKING:
|
|
@@ -207,26 +207,6 @@ class LiveDefinitions:
|
|
|
207
207
|
|
|
208
208
|
self.uses_by_codeloc: dict[CodeLocation, set[Definition]] = defaultdict(set)
|
|
209
209
|
|
|
210
|
-
@property
|
|
211
|
-
@deprecated("registers")
|
|
212
|
-
def register_definitions(self) -> MultiValuedMemory:
|
|
213
|
-
return self.registers
|
|
214
|
-
|
|
215
|
-
@property
|
|
216
|
-
@deprecated("stack")
|
|
217
|
-
def stack_definitions(self) -> MultiValuedMemory:
|
|
218
|
-
return self.stack
|
|
219
|
-
|
|
220
|
-
@property
|
|
221
|
-
@deprecated("memory")
|
|
222
|
-
def memory_definitions(self) -> MultiValuedMemory:
|
|
223
|
-
return self.memory
|
|
224
|
-
|
|
225
|
-
@property
|
|
226
|
-
@deprecated("heap")
|
|
227
|
-
def heap_definitions(self) -> MultiValuedMemory:
|
|
228
|
-
return self.heap
|
|
229
|
-
|
|
230
210
|
def __repr__(self):
|
|
231
211
|
ctnt = "LiveDefs"
|
|
232
212
|
if self.tmps:
|
|
@@ -359,6 +339,19 @@ class LiveDefinitions:
|
|
|
359
339
|
return off0 - off1
|
|
360
340
|
return None
|
|
361
341
|
|
|
342
|
+
@staticmethod
|
|
343
|
+
def _simplify_sp_alignment(data: MultiValues) -> MultiValues:
|
|
344
|
+
"""
|
|
345
|
+
Eliminate trivial stack pointer alignment, e.g.: {sp & ~0xf} -> {sp}
|
|
346
|
+
"""
|
|
347
|
+
value = data.one_value()
|
|
348
|
+
if value is not None and "stack_base" in value.variables and value.op == "__and__" and len(value.args) == 2:
|
|
349
|
+
if value.args[1].concrete and is_alignment_mask(value.args[1].concrete_value):
|
|
350
|
+
return MultiValues(value.args[0])
|
|
351
|
+
if value.args[0].concrete and is_alignment_mask(value.args[0].concrete_value):
|
|
352
|
+
return MultiValues(value.args[1])
|
|
353
|
+
return data
|
|
354
|
+
|
|
362
355
|
@staticmethod
|
|
363
356
|
def annotate_with_def(symvar: MVType, definition: Definition) -> MVType:
|
|
364
357
|
"""
|
|
@@ -521,7 +514,8 @@ class LiveDefinitions:
|
|
|
521
514
|
else:
|
|
522
515
|
l.warning("Skip stack storing since the stack offset is None.")
|
|
523
516
|
elif isinstance(atom.addr, HeapAddress):
|
|
524
|
-
|
|
517
|
+
if not isinstance(atom.addr.value, Undefined):
|
|
518
|
+
self.heap.erase(atom.addr.value, size=atom.size)
|
|
525
519
|
elif isinstance(atom.addr, int):
|
|
526
520
|
self.memory.erase(atom.addr, size=atom.size)
|
|
527
521
|
elif isinstance(atom.addr, claripy.ast.Base):
|
|
@@ -571,6 +565,11 @@ class LiveDefinitions:
|
|
|
571
565
|
|
|
572
566
|
# set_object() replaces kill (not implemented) and add (add) in one step
|
|
573
567
|
if isinstance(atom, Register):
|
|
568
|
+
|
|
569
|
+
# Tolerate simple stack pointer alignments
|
|
570
|
+
if atom.reg_offset == self.arch.sp_offset:
|
|
571
|
+
d = self._simplify_sp_alignment(d)
|
|
572
|
+
|
|
574
573
|
try:
|
|
575
574
|
self.registers.store(
|
|
576
575
|
atom.reg_offset,
|
|
@@ -611,7 +610,7 @@ class LiveDefinitions:
|
|
|
611
610
|
return None
|
|
612
611
|
elif isinstance(atom, Tmp):
|
|
613
612
|
if self.track_tmps:
|
|
614
|
-
self.tmps[atom.tmp_idx] = {
|
|
613
|
+
self.tmps[atom.tmp_idx] = {Definition(atom, code_loc, dummy=dummy, tags=tags)}
|
|
615
614
|
else:
|
|
616
615
|
self.tmps[atom.tmp_idx] = self.uses_by_codeloc[code_loc]
|
|
617
616
|
return None
|
|
@@ -686,6 +685,8 @@ class LiveDefinitions:
|
|
|
686
685
|
if isinstance(thing.addr, SpOffset):
|
|
687
686
|
return self.get_stack_definitions(thing.addr.offset, thing.size)
|
|
688
687
|
if isinstance(thing.addr, HeapAddress):
|
|
688
|
+
if isinstance(thing.addr.value, Undefined):
|
|
689
|
+
return set()
|
|
689
690
|
return self.get_heap_definitions(thing.addr.value, size=thing.size)
|
|
690
691
|
if isinstance(thing.addr, int):
|
|
691
692
|
return self.get_memory_definitions(thing.addr, thing.size)
|
|
@@ -747,72 +748,9 @@ class LiveDefinitions:
|
|
|
747
748
|
|
|
748
749
|
return LiveDefinitions.extract_defs_from_annotations(annotations)
|
|
749
750
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
for atom in atoms:
|
|
754
|
-
result |= self.get_definitions(atom)
|
|
755
|
-
return result
|
|
756
|
-
|
|
757
|
-
@deprecated("get_values")
|
|
758
|
-
def get_value_from_definition(self, definition: Definition) -> MultiValues | None:
|
|
759
|
-
return self.get_value_from_atom(definition.atom)
|
|
760
|
-
|
|
761
|
-
@deprecated("get_one_value")
|
|
762
|
-
def get_one_value_from_definition(self, definition: Definition) -> claripy.ast.bv.BV | None:
|
|
763
|
-
return self.get_one_value_from_atom(definition.atom)
|
|
764
|
-
|
|
765
|
-
@deprecated("get_concrete_value")
|
|
766
|
-
def get_concrete_value_from_definition(self, definition: Definition) -> int | None:
|
|
767
|
-
return self.get_concrete_value_from_atom(definition.atom)
|
|
768
|
-
|
|
769
|
-
@deprecated("get_values")
|
|
770
|
-
def get_value_from_atom(self, atom: Atom) -> MultiValues | None:
|
|
771
|
-
if isinstance(atom, Register):
|
|
772
|
-
try:
|
|
773
|
-
return self.registers.load(atom.reg_offset, size=atom.size)
|
|
774
|
-
except SimMemoryMissingError:
|
|
775
|
-
return None
|
|
776
|
-
elif isinstance(atom, MemoryLocation):
|
|
777
|
-
if isinstance(atom.addr, SpOffset):
|
|
778
|
-
stack_addr = self.stack_offset_to_stack_addr(atom.addr.offset)
|
|
779
|
-
try:
|
|
780
|
-
return self.stack.load(stack_addr, size=atom.size, endness=atom.endness)
|
|
781
|
-
except SimMemoryMissingError:
|
|
782
|
-
return None
|
|
783
|
-
elif isinstance(atom.addr, HeapAddress):
|
|
784
|
-
try:
|
|
785
|
-
return self.heap.load(atom.addr.value, size=atom.size, endness=atom.endness)
|
|
786
|
-
except SimMemoryMissingError:
|
|
787
|
-
return None
|
|
788
|
-
elif isinstance(atom.addr, int):
|
|
789
|
-
try:
|
|
790
|
-
return self.memory.load(atom.addr, size=atom.size, endness=atom.endness)
|
|
791
|
-
except SimMemoryMissingError:
|
|
792
|
-
return None
|
|
793
|
-
else:
|
|
794
|
-
# ignore RegisterOffset
|
|
795
|
-
return None
|
|
796
|
-
else:
|
|
797
|
-
return None
|
|
798
|
-
|
|
799
|
-
@deprecated("get_one_value")
|
|
800
|
-
def get_one_value_from_atom(self, atom: Atom) -> claripy.ast.bv.BV | None:
|
|
801
|
-
r = self.get_value_from_atom(atom)
|
|
802
|
-
if r is None:
|
|
803
|
-
return None
|
|
804
|
-
return r.one_value()
|
|
805
|
-
|
|
806
|
-
@deprecated("get_concrete_value")
|
|
807
|
-
def get_concrete_value_from_atom(self, atom: Atom) -> int | None:
|
|
808
|
-
r = self.get_one_value_from_atom(atom)
|
|
809
|
-
if r is None:
|
|
810
|
-
return None
|
|
811
|
-
if r.symbolic:
|
|
812
|
-
return None
|
|
813
|
-
return r.concrete_value
|
|
814
|
-
|
|
815
|
-
def get_values(self, spec: A | Definition[A] | Iterable[A] | Iterable[Definition[A]]) -> MultiValues | None:
|
|
751
|
+
def get_values(
|
|
752
|
+
self, spec: A | Definition[A] | Iterable[A] | Iterable[Definition[A]], endness: archinfo.Endness | None = None
|
|
753
|
+
) -> MultiValues | None:
|
|
816
754
|
if isinstance(spec, Definition):
|
|
817
755
|
atom = spec.atom
|
|
818
756
|
elif isinstance(spec, Atom):
|
|
@@ -820,7 +758,7 @@ class LiveDefinitions:
|
|
|
820
758
|
else:
|
|
821
759
|
result = None
|
|
822
760
|
for atom in spec:
|
|
823
|
-
r = self.get_values(atom)
|
|
761
|
+
r = self.get_values(atom, endness)
|
|
824
762
|
if r is None:
|
|
825
763
|
continue
|
|
826
764
|
result = r if result is None else result.merge(r)
|
|
@@ -831,27 +769,29 @@ class LiveDefinitions:
|
|
|
831
769
|
return self.registers.load(atom.reg_offset, size=atom.size)
|
|
832
770
|
except SimMemoryMissingError:
|
|
833
771
|
return None
|
|
834
|
-
|
|
772
|
+
|
|
773
|
+
if isinstance(atom, MemoryLocation):
|
|
774
|
+
endness = endness or atom.endness
|
|
835
775
|
if isinstance(atom.addr, SpOffset):
|
|
836
776
|
stack_addr = self.stack_offset_to_stack_addr(atom.addr.offset)
|
|
837
777
|
try:
|
|
838
|
-
return self.stack.load(stack_addr, size=atom.size, endness=
|
|
778
|
+
return self.stack.load(stack_addr, size=atom.size, endness=endness)
|
|
839
779
|
except SimMemoryMissingError:
|
|
840
780
|
return None
|
|
841
781
|
elif isinstance(atom.addr, HeapAddress):
|
|
842
782
|
try:
|
|
843
|
-
return self.heap.load(atom.addr.value, size=atom.size, endness=
|
|
783
|
+
return self.heap.load(atom.addr.value, size=atom.size, endness=endness)
|
|
844
784
|
except SimMemoryMissingError:
|
|
845
785
|
return None
|
|
846
786
|
elif isinstance(atom.addr, int):
|
|
847
787
|
try:
|
|
848
|
-
return self.memory.load(atom.addr, size=atom.size, endness=
|
|
788
|
+
return self.memory.load(atom.addr, size=atom.size, endness=endness)
|
|
849
789
|
except SimMemoryMissingError:
|
|
850
790
|
pass
|
|
851
791
|
if self.project is not None:
|
|
852
792
|
try:
|
|
853
793
|
bytestring = self.project.loader.memory.load(atom.addr, atom.size)
|
|
854
|
-
if
|
|
794
|
+
if endness == archinfo.Endness.LE:
|
|
855
795
|
bytestring = bytes(reversed(bytestring))
|
|
856
796
|
return MultiValues(
|
|
857
797
|
self.annotate_with_def(claripy.BVV(bytestring), Definition(atom, ExternalCodeLocation()))
|
|
@@ -877,14 +817,12 @@ class LiveDefinitions:
|
|
|
877
817
|
|
|
878
818
|
@overload
|
|
879
819
|
def get_concrete_value(
|
|
880
|
-
self, spec: A | Definition[A] | Iterable[A] | Iterable[Definition[A]], cast_to: type[int]
|
|
820
|
+
self, spec: A | Definition[A] | Iterable[A] | Iterable[Definition[A]], cast_to: type[int]
|
|
881
821
|
) -> int | None: ...
|
|
882
822
|
|
|
883
823
|
@overload
|
|
884
824
|
def get_concrete_value(
|
|
885
|
-
self,
|
|
886
|
-
spec: A | Definition[A] | Iterable[A] | Iterable[Definition[A]],
|
|
887
|
-
cast_to: type[bytes] = ...,
|
|
825
|
+
self, spec: A | Definition[A] | Iterable[A] | Iterable[Definition[A]], cast_to: type[bytes]
|
|
888
826
|
) -> bytes | None: ...
|
|
889
827
|
|
|
890
828
|
def get_concrete_value(
|
|
@@ -991,7 +929,7 @@ class LiveDefinitions:
|
|
|
991
929
|
|
|
992
930
|
def deref(self, pointer, size, endness=archinfo.Endness.BE):
|
|
993
931
|
if isinstance(pointer, (Atom, Definition)):
|
|
994
|
-
pointer = self.get_values(pointer)
|
|
932
|
+
pointer = self.get_values(pointer, self.arch.memory_endness)
|
|
995
933
|
if pointer is None:
|
|
996
934
|
return set()
|
|
997
935
|
|
|
@@ -12,6 +12,7 @@ from cle.backends.elf.variable import Variable
|
|
|
12
12
|
|
|
13
13
|
from angr.utils.orderedset import OrderedSet
|
|
14
14
|
from angr.utils.ail import is_phi_assignment
|
|
15
|
+
from angr.utils.types import unpack_pointer, replace_pointer_pts_to
|
|
15
16
|
from angr.protos import variables_pb2
|
|
16
17
|
from angr.serializable import Serializable
|
|
17
18
|
from angr.sim_variable import SimVariable, SimStackVariable, SimMemoryVariable, SimRegisterVariable
|
|
@@ -19,7 +20,6 @@ from angr.sim_type import (
|
|
|
19
20
|
TypeRef,
|
|
20
21
|
SimType,
|
|
21
22
|
SimStruct,
|
|
22
|
-
SimTypePointer,
|
|
23
23
|
SimTypeBottom,
|
|
24
24
|
SimTypeChar,
|
|
25
25
|
SimTypeShort,
|
|
@@ -985,10 +985,12 @@ class VariableManagerInternal(Serializable):
|
|
|
985
985
|
if name not in self.types:
|
|
986
986
|
self.types[name] = TypeRef(name, ty).with_arch(self.manager._kb._project.arch)
|
|
987
987
|
ty = self.types[name]
|
|
988
|
-
elif
|
|
989
|
-
typeref = self._register_struct_type(
|
|
990
|
-
|
|
991
|
-
|
|
988
|
+
elif (inner_ty := unpack_pointer(ty, iterative=True)) and isinstance(inner_ty, SimStruct):
|
|
989
|
+
typeref = self._register_struct_type(inner_ty)
|
|
990
|
+
# rebuild the multi-layer pointer type
|
|
991
|
+
replaced_ty = replace_pointer_pts_to(ty, inner_ty, typeref)
|
|
992
|
+
assert replaced_ty is not None
|
|
993
|
+
ty = replaced_ty.with_arch(self.manager._kb._project.arch)
|
|
992
994
|
elif isinstance(ty, SimStruct):
|
|
993
995
|
ty = self._register_struct_type(ty, name=name)
|
|
994
996
|
|
angr/sim_type.py
CHANGED
|
@@ -20,10 +20,8 @@ from .misc.ux import deprecated
|
|
|
20
20
|
|
|
21
21
|
if TYPE_CHECKING:
|
|
22
22
|
from angr.procedures.definitions import SimTypeCollection
|
|
23
|
-
from angr.storage.memory_mixins import _Coerce
|
|
24
|
-
|
|
25
|
-
StoreType = _Coerce
|
|
26
23
|
|
|
24
|
+
StoreType = int | claripy.ast.BV
|
|
27
25
|
|
|
28
26
|
l = logging.getLogger(name=__name__)
|
|
29
27
|
|
|
@@ -318,6 +316,8 @@ class SimTypeReg(SimType):
|
|
|
318
316
|
return f"reg{self.size}_t"
|
|
319
317
|
|
|
320
318
|
def store(self, state, addr, value: StoreType):
|
|
319
|
+
if self.size is None:
|
|
320
|
+
raise TypeError("Need a size to store")
|
|
321
321
|
store_endness = state.arch.memory_endness
|
|
322
322
|
with contextlib.suppress(AttributeError):
|
|
323
323
|
value = value.ast # type: ignore
|
|
@@ -366,7 +366,7 @@ class SimTypeNum(SimType):
|
|
|
366
366
|
def extract(self, state, addr, concrete: Literal[False] = ...) -> claripy.ast.BV: ...
|
|
367
367
|
|
|
368
368
|
@overload
|
|
369
|
-
def extract(self, state, addr, concrete: Literal[True]
|
|
369
|
+
def extract(self, state, addr, concrete: Literal[True]) -> int: ...
|
|
370
370
|
|
|
371
371
|
def extract(self, state, addr, concrete=False):
|
|
372
372
|
out = state.memory.load(addr, self.size // state.arch.byte_width, endness=state.arch.memory_endness)
|
|
@@ -445,7 +445,7 @@ class SimTypeInt(SimTypeReg):
|
|
|
445
445
|
def extract(self, state, addr, concrete: Literal[False] = ...) -> claripy.ast.BV: ...
|
|
446
446
|
|
|
447
447
|
@overload
|
|
448
|
-
def extract(self, state, addr, concrete: Literal[True]
|
|
448
|
+
def extract(self, state, addr, concrete: Literal[True]) -> int: ...
|
|
449
449
|
|
|
450
450
|
def extract(self, state, addr, concrete=False):
|
|
451
451
|
out = state.memory.load(addr, self.size // state.arch.byte_width, endness=state.arch.memory_endness)
|
|
@@ -575,7 +575,7 @@ class SimTypeChar(SimTypeReg):
|
|
|
575
575
|
def extract(self, state, addr, concrete: Literal[False] = ...) -> claripy.ast.BV: ...
|
|
576
576
|
|
|
577
577
|
@overload
|
|
578
|
-
def extract(self, state, addr, concrete: Literal[True]
|
|
578
|
+
def extract(self, state, addr, concrete: Literal[True]) -> bytes: ...
|
|
579
579
|
|
|
580
580
|
def extract(self, state, addr, concrete: bool = False) -> claripy.ast.BV | bytes:
|
|
581
581
|
# FIXME: This is a hack.
|
|
@@ -665,7 +665,7 @@ class SimTypeBool(SimTypeReg):
|
|
|
665
665
|
def extract(self, state, addr, concrete: Literal[False] = ...) -> claripy.ast.Bool: ...
|
|
666
666
|
|
|
667
667
|
@overload
|
|
668
|
-
def extract(self, state, addr, concrete: Literal[True]
|
|
668
|
+
def extract(self, state, addr, concrete: Literal[True]) -> bool: ...
|
|
669
669
|
|
|
670
670
|
def extract(self, state, addr, concrete=False):
|
|
671
671
|
ver = super().extract(state, addr, concrete)
|
|
@@ -715,7 +715,7 @@ class SimTypeFd(SimTypeReg):
|
|
|
715
715
|
def extract(self, state, addr, concrete: Literal[False] = ...) -> claripy.ast.BV: ...
|
|
716
716
|
|
|
717
717
|
@overload
|
|
718
|
-
def extract(self, state, addr, concrete: Literal[True]
|
|
718
|
+
def extract(self, state, addr, concrete: Literal[True]) -> int: ...
|
|
719
719
|
|
|
720
720
|
def extract(self, state, addr, concrete=False):
|
|
721
721
|
# TODO: EDG says this looks dangerously closed-minded. Just in case...
|
|
@@ -788,7 +788,7 @@ class SimTypePointer(SimTypeReg):
|
|
|
788
788
|
def extract(self, state, addr, concrete: Literal[False] = ...) -> claripy.ast.BV: ...
|
|
789
789
|
|
|
790
790
|
@overload
|
|
791
|
-
def extract(self, state, addr, concrete: Literal[True]
|
|
791
|
+
def extract(self, state, addr, concrete: Literal[True]) -> int: ...
|
|
792
792
|
|
|
793
793
|
def extract(self, state, addr, concrete=False):
|
|
794
794
|
# TODO: EDG says this looks dangerously closed-minded. Just in case...
|
|
@@ -848,7 +848,7 @@ class SimTypeReference(SimTypeReg):
|
|
|
848
848
|
def extract(self, state, addr, concrete: Literal[False] = ...) -> claripy.ast.BV: ...
|
|
849
849
|
|
|
850
850
|
@overload
|
|
851
|
-
def extract(self, state, addr, concrete: Literal[True]
|
|
851
|
+
def extract(self, state, addr, concrete: Literal[True]) -> int: ...
|
|
852
852
|
|
|
853
853
|
def extract(self, state, addr, concrete=False):
|
|
854
854
|
# TODO: EDG says this looks dangerously closed-minded. Just in case...
|
|
@@ -984,7 +984,7 @@ class SimTypeString(NamedTypeMixin, SimType):
|
|
|
984
984
|
def extract(self, state, addr, concrete: Literal[False] = ...) -> claripy.ast.BV: ...
|
|
985
985
|
|
|
986
986
|
@overload
|
|
987
|
-
def extract(self, state, addr, concrete: Literal[True]
|
|
987
|
+
def extract(self, state, addr, concrete: Literal[True]) -> bytes: ...
|
|
988
988
|
|
|
989
989
|
def extract(self, state: SimState, addr, concrete=False):
|
|
990
990
|
if self.length is None:
|
|
@@ -1585,7 +1585,7 @@ class SimStructValue:
|
|
|
1585
1585
|
for name in self._struct.fields:
|
|
1586
1586
|
value = self._values[name]
|
|
1587
1587
|
try:
|
|
1588
|
-
f = value.__indented_repr__
|
|
1588
|
+
f = value.__indented_repr__ # type: ignore[reportAttributeAccessIssue]
|
|
1589
1589
|
s = f(indent=indent + 2)
|
|
1590
1590
|
except AttributeError:
|
|
1591
1591
|
s = repr(value)
|
|
@@ -1620,7 +1620,7 @@ class SimStructValue:
|
|
|
1620
1620
|
class SimUnion(NamedTypeMixin, SimType):
|
|
1621
1621
|
fields = ("members", "name")
|
|
1622
1622
|
|
|
1623
|
-
def __init__(self, members, name=None, label=None):
|
|
1623
|
+
def __init__(self, members: dict[str, SimType], name=None, label=None):
|
|
1624
1624
|
"""
|
|
1625
1625
|
:param members: The members of the union, as a mapping name -> type
|
|
1626
1626
|
:param name: The name of the union
|
|
@@ -1630,6 +1630,8 @@ class SimUnion(NamedTypeMixin, SimType):
|
|
|
1630
1630
|
|
|
1631
1631
|
@property
|
|
1632
1632
|
def size(self):
|
|
1633
|
+
if self._arch is None:
|
|
1634
|
+
raise ValueError("Can't tell my size without an arch!")
|
|
1633
1635
|
member_sizes = [ty.size for ty in self.members.values() if not isinstance(ty, SimTypeBottom)]
|
|
1634
1636
|
# fall back to word size in case all members are SimTypeBottom
|
|
1635
1637
|
return max(member_sizes) if member_sizes else self._arch.bytes
|
|
@@ -1722,7 +1724,7 @@ class SimUnionValue:
|
|
|
1722
1724
|
fields = []
|
|
1723
1725
|
for name, value in self._values.items():
|
|
1724
1726
|
try:
|
|
1725
|
-
f = value.__indented_repr__
|
|
1727
|
+
f = value.__indented_repr__ # type: ignore[reportAttributeAccessIssue]
|
|
1726
1728
|
s = f(indent=indent + 2)
|
|
1727
1729
|
except AttributeError:
|
|
1728
1730
|
s = repr(value)
|
|
@@ -1820,7 +1822,7 @@ class SimCppClassValue(SimStructValue):
|
|
|
1820
1822
|
for name in self._class.fields:
|
|
1821
1823
|
value = self._values[name]
|
|
1822
1824
|
try:
|
|
1823
|
-
f = value.__indented_repr__
|
|
1825
|
+
f = value.__indented_repr__ # type: ignore[reportAttributeAccessIssue]
|
|
1824
1826
|
s = f(indent=indent + 2)
|
|
1825
1827
|
except AttributeError:
|
|
1826
1828
|
s = repr(value)
|
|
@@ -1864,10 +1866,10 @@ class SimTypeNumOffset(SimTypeNum):
|
|
|
1864
1866
|
self.offset = offset
|
|
1865
1867
|
|
|
1866
1868
|
@overload
|
|
1867
|
-
def extract(self, state, addr, concrete: Literal[False] = ...) -> claripy.ast.BV: ...
|
|
1869
|
+
def extract(self, state: SimState, addr, concrete: Literal[False] = ...) -> claripy.ast.BV: ...
|
|
1868
1870
|
|
|
1869
1871
|
@overload
|
|
1870
|
-
def extract(self, state, addr, concrete: Literal[True]
|
|
1872
|
+
def extract(self, state: SimState, addr, concrete: Literal[True]) -> int: ...
|
|
1871
1873
|
|
|
1872
1874
|
def extract(self, state: SimState, addr, concrete=False):
|
|
1873
1875
|
if state.arch.memory_endness != Endness.LE:
|
angr/simos/simos.py
CHANGED
|
@@ -23,7 +23,9 @@ class SimOS:
|
|
|
23
23
|
A class describing OS/arch-level configuration.
|
|
24
24
|
"""
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
name: str | None
|
|
27
|
+
|
|
28
|
+
def __init__(self, project: angr.Project, name: str | None = None):
|
|
27
29
|
self.arch = project.arch
|
|
28
30
|
self.project = project
|
|
29
31
|
self.name = name
|