angr 9.2.131__py3-none-manylinux2014_x86_64.whl → 9.2.132__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/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,8 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
from collections import Counter
|
|
4
|
+
from difflib import SequenceMatcher
|
|
4
5
|
|
|
5
|
-
from . import ExplorationTechnique
|
|
6
|
+
from .base import ExplorationTechnique
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
class UniqueSearch(ExplorationTechnique):
|
|
@@ -220,10 +220,10 @@ class Register(Atom):
|
|
|
220
220
|
"arch",
|
|
221
221
|
)
|
|
222
222
|
|
|
223
|
-
def __init__(self, reg_offset: RegisterOffset, size: int, arch: Arch | None = None):
|
|
223
|
+
def __init__(self, reg_offset: RegisterOffset | int, size: int, arch: Arch | None = None):
|
|
224
224
|
super().__init__(size)
|
|
225
225
|
|
|
226
|
-
self.reg_offset = reg_offset
|
|
226
|
+
self.reg_offset = RegisterOffset(reg_offset)
|
|
227
227
|
self.arch = arch
|
|
228
228
|
|
|
229
229
|
def __repr__(self):
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
-
from typing import Any, TYPE_CHECKING, overload
|
|
2
|
+
from typing import Any, TYPE_CHECKING, cast, overload
|
|
3
3
|
from collections.abc import Iterable, Generator
|
|
4
4
|
import weakref
|
|
5
5
|
import logging
|
|
@@ -14,7 +14,7 @@ import archinfo
|
|
|
14
14
|
from angr.misc.ux import deprecated
|
|
15
15
|
from angr.errors import SimMemoryMissingError, SimMemoryError
|
|
16
16
|
from angr.storage.memory_mixins import MultiValuedMemory
|
|
17
|
-
from angr.storage.memory_mixins.paged_memory.pages.multi_values import MultiValues
|
|
17
|
+
from angr.storage.memory_mixins.paged_memory.pages.multi_values import MVType, MultiValues
|
|
18
18
|
from angr.knowledge_plugins.key_definitions.definition import A
|
|
19
19
|
from angr.engines.light import SpOffset
|
|
20
20
|
from angr.code_location import CodeLocation, ExternalCodeLocation
|
|
@@ -324,7 +324,7 @@ class LiveDefinitions:
|
|
|
324
324
|
return True
|
|
325
325
|
return False
|
|
326
326
|
|
|
327
|
-
def stack_address(self, offset: int) -> claripy.ast.bv.BV
|
|
327
|
+
def stack_address(self, offset: int) -> claripy.ast.bv.BV:
|
|
328
328
|
base = claripy.BVS("stack_base", self.arch.bits, explicit_name=True)
|
|
329
329
|
if offset:
|
|
330
330
|
return base + offset
|
|
@@ -346,21 +346,21 @@ class LiveDefinitions:
|
|
|
346
346
|
return 0
|
|
347
347
|
if addr.op == "__add__":
|
|
348
348
|
if len(addr.args) == 2:
|
|
349
|
-
off0 = LiveDefinitions.get_stack_offset(addr.args[0], had_stack_base=True)
|
|
350
|
-
off1 = LiveDefinitions.get_stack_offset(addr.args[1], had_stack_base=True)
|
|
349
|
+
off0 = LiveDefinitions.get_stack_offset(cast(claripy.ast.BV, addr.args[0]), had_stack_base=True)
|
|
350
|
+
off1 = LiveDefinitions.get_stack_offset(cast(claripy.ast.BV, addr.args[1]), had_stack_base=True)
|
|
351
351
|
if off0 is not None and off1 is not None:
|
|
352
352
|
return off0 + off1
|
|
353
353
|
elif len(addr.args) == 1:
|
|
354
354
|
return 0
|
|
355
355
|
elif addr.op == "__sub__" and len(addr.args) == 2:
|
|
356
|
-
off0 = LiveDefinitions.get_stack_offset(addr.args[0], had_stack_base=True)
|
|
357
|
-
off1 = LiveDefinitions.get_stack_offset(addr.args[1], had_stack_base=True)
|
|
356
|
+
off0 = LiveDefinitions.get_stack_offset(cast(claripy.ast.BV, addr.args[0]), had_stack_base=True)
|
|
357
|
+
off1 = LiveDefinitions.get_stack_offset(cast(claripy.ast.BV, addr.args[1]), had_stack_base=True)
|
|
358
358
|
if off0 is not None and off1 is not None:
|
|
359
359
|
return off0 - off1
|
|
360
360
|
return None
|
|
361
361
|
|
|
362
362
|
@staticmethod
|
|
363
|
-
def annotate_with_def(symvar:
|
|
363
|
+
def annotate_with_def(symvar: MVType, definition: Definition) -> MVType:
|
|
364
364
|
"""
|
|
365
365
|
|
|
366
366
|
:param symvar:
|
|
@@ -562,9 +562,12 @@ class LiveDefinitions:
|
|
|
562
562
|
else:
|
|
563
563
|
definition: Definition = Definition(atom, code_loc, dummy=dummy, tags=tags)
|
|
564
564
|
d = MultiValues()
|
|
565
|
+
count = 0
|
|
565
566
|
for offset, vs in data.items():
|
|
566
567
|
for v in vs:
|
|
568
|
+
count += 1
|
|
567
569
|
d.add_value(offset, self.annotate_with_def(v, definition))
|
|
570
|
+
assert count != 0, "MV may not be empty, use TOP instead"
|
|
568
571
|
|
|
569
572
|
# set_object() replaces kill (not implemented) and add (add) in one step
|
|
570
573
|
if isinstance(atom, Register):
|
|
@@ -659,7 +662,7 @@ class LiveDefinitions:
|
|
|
659
662
|
self.other_uses.add_use(definition, code_loc, expr)
|
|
660
663
|
|
|
661
664
|
def get_definitions(
|
|
662
|
-
self, thing:
|
|
665
|
+
self, thing: Atom | Definition[Atom] | Iterable[Atom] | Iterable[Definition[Atom]] | MultiValues
|
|
663
666
|
) -> set[Definition[Atom]]:
|
|
664
667
|
if isinstance(thing, MultiValues):
|
|
665
668
|
defs = set()
|
|
@@ -973,7 +976,7 @@ class LiveDefinitions:
|
|
|
973
976
|
@overload
|
|
974
977
|
def deref(
|
|
975
978
|
self,
|
|
976
|
-
pointer: MultiValues |
|
|
979
|
+
pointer: MultiValues[claripy.ast.BV] | Atom | Definition[Atom] | Iterable[Atom] | Iterable[Definition[Atom]],
|
|
977
980
|
size: int | DerefSize,
|
|
978
981
|
endness: archinfo.Endness = ...,
|
|
979
982
|
) -> set[MemoryLocation]: ...
|
|
@@ -1023,7 +1026,7 @@ class LiveDefinitions:
|
|
|
1023
1026
|
if heap_offset is not None:
|
|
1024
1027
|
addr = HeapAddress(heap_offset)
|
|
1025
1028
|
elif pointer.op == "BVV":
|
|
1026
|
-
addr = pointer.args[0]
|
|
1029
|
+
addr = cast(int, pointer.args[0])
|
|
1027
1030
|
else:
|
|
1028
1031
|
# cannot resolve
|
|
1029
1032
|
return None
|
|
@@ -1054,8 +1057,8 @@ class LiveDefinitions:
|
|
|
1054
1057
|
if "heap_base" in addr.variables:
|
|
1055
1058
|
if addr.op == "BVS":
|
|
1056
1059
|
return 0
|
|
1057
|
-
if addr.op == "__add__" and len(addr.args) == 2 and addr.args[1].op == "BVV":
|
|
1058
|
-
return addr.args[1].concrete_value
|
|
1060
|
+
if addr.op == "__add__" and len(addr.args) == 2 and cast(claripy.ast.BV, addr.args[1]).op == "BVV":
|
|
1061
|
+
return cast(claripy.ast.BV, addr.args[1]).concrete_value
|
|
1059
1062
|
return None
|
|
1060
1063
|
|
|
1061
1064
|
def heap_address(self, offset: int | HeapAddress) -> claripy.ast.BV:
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
# pylint:disable=too-many-boolean-expressions
|
|
2
2
|
from __future__ import annotations
|
|
3
|
+
from abc import abstractmethod
|
|
3
4
|
from typing import Any, TYPE_CHECKING
|
|
4
5
|
from collections import defaultdict
|
|
5
6
|
import weakref
|
|
6
7
|
|
|
8
|
+
from typing_extensions import Self
|
|
9
|
+
|
|
7
10
|
import ailment
|
|
8
11
|
import claripy
|
|
9
12
|
import archinfo
|
|
@@ -114,7 +117,7 @@ class PropagatorState:
|
|
|
114
117
|
self.model = model
|
|
115
118
|
self.rda = rda
|
|
116
119
|
|
|
117
|
-
def __repr__(self):
|
|
120
|
+
def __repr__(self) -> str:
|
|
118
121
|
return "<PropagatorState>"
|
|
119
122
|
|
|
120
123
|
@classmethod
|
|
@@ -155,6 +158,7 @@ class PropagatorState:
|
|
|
155
158
|
# comparing bytes from two sets of memory objects
|
|
156
159
|
# we don't need to resort to byte-level comparison. object-level is good enough.
|
|
157
160
|
|
|
161
|
+
# TODO what if object is bytes?
|
|
158
162
|
if mo_self.object.symbolic or mo_other.object.symbolic:
|
|
159
163
|
if type(mo_self) is SimLabeledMemoryObject and type(mo_other) is SimLabeledMemoryObject:
|
|
160
164
|
return mo_self.label == mo_other.label and mo_self.object is mo_other.object
|
|
@@ -165,7 +169,7 @@ class PropagatorState:
|
|
|
165
169
|
return None
|
|
166
170
|
|
|
167
171
|
@staticmethod
|
|
168
|
-
def top(bits: int) -> claripy.ast.
|
|
172
|
+
def top(bits: int) -> claripy.ast.BV:
|
|
169
173
|
"""
|
|
170
174
|
Get a TOP value.
|
|
171
175
|
|
|
@@ -243,10 +247,11 @@ class PropagatorState:
|
|
|
243
247
|
merge_occurred = True
|
|
244
248
|
return merge_occurred
|
|
245
249
|
|
|
246
|
-
|
|
250
|
+
@abstractmethod
|
|
251
|
+
def copy(self) -> Self:
|
|
247
252
|
raise NotImplementedError
|
|
248
253
|
|
|
249
|
-
def merge(self, *others):
|
|
254
|
+
def merge(self, *others: Self) -> tuple[Self, bool]:
|
|
250
255
|
state = self.copy()
|
|
251
256
|
merge_occurred = False
|
|
252
257
|
|
|
@@ -263,8 +268,8 @@ class PropagatorState:
|
|
|
263
268
|
self._replacements = defaultdict(dict)
|
|
264
269
|
|
|
265
270
|
def add_replacement(
|
|
266
|
-
self, codeloc: CodeLocation, old, new, force_replace: bool = False
|
|
267
|
-
) -> bool:
|
|
271
|
+
self, codeloc: CodeLocation, old, new, force_replace: bool = False # pylint:disable=unused-argument
|
|
272
|
+
) -> bool:
|
|
268
273
|
"""
|
|
269
274
|
Add a replacement record: Replacing expression `old` with `new` at program location `codeloc`.
|
|
270
275
|
If the self._only_consts flag is set to true, only constant values will be set.
|
|
@@ -331,7 +336,7 @@ class RegisterComparisonAnnotation(claripy.Annotation):
|
|
|
331
336
|
Annotate TOP values that are the result of register values comparing against constant values.
|
|
332
337
|
"""
|
|
333
338
|
|
|
334
|
-
def __init__(self, offset, size, cmp_op, value):
|
|
339
|
+
def __init__(self, offset: int, size: int, cmp_op: str, value: int):
|
|
335
340
|
self.offset = offset
|
|
336
341
|
self.size = size
|
|
337
342
|
self.cmp_op = cmp_op
|
|
@@ -504,7 +509,7 @@ class PropagatorVEXState(PropagatorState):
|
|
|
504
509
|
# TODO: Handle size
|
|
505
510
|
self._stack_variables.store(offset, value, size=size, endness=endness)
|
|
506
511
|
|
|
507
|
-
def load_local_variable(self, offset, size, endness): # pylint:disable=unused-argument
|
|
512
|
+
def load_local_variable(self, offset, size, endness) -> claripy.ast.BV: # pylint:disable=unused-argument
|
|
508
513
|
# TODO: Handle size
|
|
509
514
|
try:
|
|
510
515
|
return self._stack_variables.load(offset, size=size, endness=endness)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
-
from typing import Literal, TYPE_CHECKING
|
|
2
|
+
from typing import Literal, TYPE_CHECKING, overload
|
|
3
3
|
import logging
|
|
4
4
|
from collections import defaultdict
|
|
5
5
|
from itertools import count, chain
|
|
@@ -77,14 +77,14 @@ class VariableManagerInternal(Serializable):
|
|
|
77
77
|
|
|
78
78
|
self.func_addr = func_addr
|
|
79
79
|
|
|
80
|
-
self._variables:
|
|
80
|
+
self._variables: OrderedSet[SimVariable] = OrderedSet() # all variables that are added to any region
|
|
81
81
|
self._global_region = KeyedRegion()
|
|
82
82
|
self._stack_region = KeyedRegion()
|
|
83
83
|
self._register_region = KeyedRegion()
|
|
84
84
|
self._live_variables = {} # a mapping between addresses of program points and live variable collections
|
|
85
85
|
|
|
86
86
|
self._variable_accesses: dict[SimVariable, set[VariableAccess]] = defaultdict(set)
|
|
87
|
-
self._insn_to_variable: dict[int, set[tuple[SimVariable, int]]] = defaultdict(set)
|
|
87
|
+
self._insn_to_variable: dict[int, set[tuple[SimVariable, int | None]]] = defaultdict(set)
|
|
88
88
|
self._stmt_to_variable: dict[tuple[int, int] | tuple[int, int, int], set[tuple[SimVariable, int]]] = (
|
|
89
89
|
defaultdict(set)
|
|
90
90
|
)
|
|
@@ -115,7 +115,7 @@ class VariableManagerInternal(Serializable):
|
|
|
115
115
|
# optimization
|
|
116
116
|
self._variables_without_writes = set()
|
|
117
117
|
|
|
118
|
-
self.stack_offset_to_struct_member_info: dict[SimStackVariable,
|
|
118
|
+
self.stack_offset_to_struct_member_info: dict[SimStackVariable, tuple[int, SimStackVariable, SimStruct]] = {}
|
|
119
119
|
|
|
120
120
|
self.ret_val_size = None
|
|
121
121
|
|
|
@@ -291,9 +291,11 @@ class VariableManagerInternal(Serializable):
|
|
|
291
291
|
variable_access = VariableAccess.parse_from_cmessage(varaccess_pb2, variable_by_ident=variable_by_ident)
|
|
292
292
|
variable = variable_access.variable
|
|
293
293
|
offset = variable_access.offset
|
|
294
|
+
assert variable is not None
|
|
294
295
|
tpl = (variable, offset)
|
|
295
296
|
|
|
296
297
|
model._variable_accesses[variable_access.variable].add(variable_access)
|
|
298
|
+
assert variable_access.location.ins_addr is not None
|
|
297
299
|
model._insn_to_variable[variable_access.location.ins_addr].add(tpl)
|
|
298
300
|
loc = (
|
|
299
301
|
(variable_access.location.block_addr, variable_access.location.stmt_idx)
|
|
@@ -670,9 +672,16 @@ class VariableManagerInternal(Serializable):
|
|
|
670
672
|
|
|
671
673
|
return accesses
|
|
672
674
|
|
|
675
|
+
@overload
|
|
676
|
+
def get_variables(self, sort: Literal["stack"], collapse_same_ident: bool = False) -> list[SimStackVariable]: ...
|
|
677
|
+
@overload
|
|
678
|
+
def get_variables(self, sort: Literal["reg"], collapse_same_ident: bool = False) -> list[SimRegisterVariable]: ...
|
|
679
|
+
@overload
|
|
673
680
|
def get_variables(
|
|
674
|
-
self, sort:
|
|
675
|
-
) -> list[
|
|
681
|
+
self, sort: None, collapse_same_ident: bool = False
|
|
682
|
+
) -> list[SimRegisterVariable | SimRegisterVariable]: ...
|
|
683
|
+
|
|
684
|
+
def get_variables(self, sort=None, collapse_same_ident=False):
|
|
676
685
|
"""
|
|
677
686
|
Get a list of variables.
|
|
678
687
|
|
|
@@ -695,9 +704,14 @@ class VariableManagerInternal(Serializable):
|
|
|
695
704
|
|
|
696
705
|
return variables
|
|
697
706
|
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
707
|
+
@overload
|
|
708
|
+
def get_unified_variables(self, sort: Literal["stack"]) -> list[SimStackVariable]: ...
|
|
709
|
+
@overload
|
|
710
|
+
def get_unified_variables(self, sort: Literal["reg"]) -> list[SimRegisterVariable]: ...
|
|
711
|
+
@overload
|
|
712
|
+
def get_unified_variables(self, sort: None) -> list[SimRegisterVariable | SimRegisterVariable]: ...
|
|
713
|
+
|
|
714
|
+
def get_unified_variables(self, sort=None):
|
|
701
715
|
"""
|
|
702
716
|
Get a list of unified variables.
|
|
703
717
|
|
angr/sim_manager.py
CHANGED
|
@@ -10,6 +10,7 @@ from types import TracebackType
|
|
|
10
10
|
import claripy
|
|
11
11
|
import mulpyplexer
|
|
12
12
|
|
|
13
|
+
from .exploration_techniques import ExplorationTechnique, Veritesting, Threading, Explorer, Suggestions
|
|
13
14
|
from .misc.hookset import HookSet
|
|
14
15
|
from .misc.ux import once
|
|
15
16
|
from .misc.picklable_lock import PicklableLock
|
|
@@ -968,6 +969,3 @@ class ErrorRecord:
|
|
|
968
969
|
|
|
969
970
|
def __eq__(self, other):
|
|
970
971
|
return self is other or self.state is other
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
from .exploration_techniques import ExplorationTechnique, Veritesting, Threading, Explorer, Suggestions
|
angr/sim_state.py
CHANGED
|
@@ -5,12 +5,14 @@ import functools
|
|
|
5
5
|
import itertools
|
|
6
6
|
import logging
|
|
7
7
|
import weakref
|
|
8
|
-
from typing import TypeVar, TYPE_CHECKING
|
|
8
|
+
from typing import Any, TypeVar, TYPE_CHECKING, Generic
|
|
9
|
+
from collections.abc import Callable
|
|
9
10
|
|
|
10
11
|
import archinfo
|
|
11
|
-
import claripy
|
|
12
12
|
from archinfo import Arch
|
|
13
13
|
from archinfo.arch_soot import SootAddressDescriptor
|
|
14
|
+
import claripy
|
|
15
|
+
from cle import Clemory
|
|
14
16
|
|
|
15
17
|
from . import sim_options as o
|
|
16
18
|
from .errors import SimMergeError, SimValueError, SimStateError, SimSolverModeError
|
|
@@ -27,6 +29,8 @@ if TYPE_CHECKING:
|
|
|
27
29
|
from .state_plugins.inspect import SimInspector
|
|
28
30
|
from .state_plugins.jni_references import SimStateJNIReferences
|
|
29
31
|
from .state_plugins.scratch import SimStateScratch
|
|
32
|
+
from angr.project import Project
|
|
33
|
+
from angr.simos.javavm import SimJavaVM
|
|
30
34
|
|
|
31
35
|
|
|
32
36
|
l = logging.getLogger(name=__name__)
|
|
@@ -48,9 +52,12 @@ merge_counter = itertools.count()
|
|
|
48
52
|
|
|
49
53
|
_complained_se = False
|
|
50
54
|
|
|
55
|
+
IPTypeConc = TypeVar("IPTypeConc")
|
|
56
|
+
IPTypeSym = TypeVar("IPTypeSym")
|
|
57
|
+
|
|
51
58
|
|
|
52
59
|
# pylint: disable=not-callable
|
|
53
|
-
class SimState(PluginHub):
|
|
60
|
+
class SimState(Generic[IPTypeConc, IPTypeSym], PluginHub[SimStatePlugin]):
|
|
54
61
|
"""
|
|
55
62
|
The SimState represents the state of a program, including its memory, registers, and so forth.
|
|
56
63
|
|
|
@@ -88,23 +95,23 @@ class SimState(PluginHub):
|
|
|
88
95
|
|
|
89
96
|
def __init__(
|
|
90
97
|
self,
|
|
91
|
-
project=None,
|
|
92
|
-
arch=None,
|
|
93
|
-
plugins=None,
|
|
94
|
-
mode=None,
|
|
95
|
-
options=None,
|
|
96
|
-
add_options=None,
|
|
97
|
-
remove_options=None,
|
|
98
|
-
special_memory_filler=None,
|
|
99
|
-
os_name=None,
|
|
100
|
-
plugin_preset="default",
|
|
101
|
-
cle_memory_backer=None,
|
|
102
|
-
dict_memory_backer=None,
|
|
103
|
-
permissions_map=None,
|
|
104
|
-
default_permissions=3,
|
|
105
|
-
stack_perms=None,
|
|
106
|
-
stack_end=None,
|
|
107
|
-
stack_size=None,
|
|
98
|
+
project: Project | None = None,
|
|
99
|
+
arch: Arch | None = None,
|
|
100
|
+
plugins: dict[str, SimStatePlugin] | None = None,
|
|
101
|
+
mode: str | None = None,
|
|
102
|
+
options: set[str] | list[str] | SimStateOptions | None = None,
|
|
103
|
+
add_options: set[str] | None = None,
|
|
104
|
+
remove_options: set[str] | None = None,
|
|
105
|
+
special_memory_filler: Callable[[str, int, int, SimState], Any] | None = None,
|
|
106
|
+
os_name: str | None = None,
|
|
107
|
+
plugin_preset: str = "default",
|
|
108
|
+
cle_memory_backer: Clemory | None = None,
|
|
109
|
+
dict_memory_backer: dict[int, bytes] | None = None,
|
|
110
|
+
permissions_map: dict[tuple[int, int], int] | None = None,
|
|
111
|
+
default_permissions: int = 3,
|
|
112
|
+
stack_perms: int | None = None,
|
|
113
|
+
stack_end: int | None = None,
|
|
114
|
+
stack_size: int | None = None,
|
|
108
115
|
regioned_memory_cls=None,
|
|
109
116
|
**kwargs,
|
|
110
117
|
):
|
|
@@ -118,7 +125,9 @@ class SimState(PluginHub):
|
|
|
118
125
|
self._is_java_jni_project = self.project and self.project.is_java_jni_project
|
|
119
126
|
|
|
120
127
|
# Arch
|
|
121
|
-
if self._is_java_jni_project:
|
|
128
|
+
if self._is_java_jni_project and project is not None:
|
|
129
|
+
if TYPE_CHECKING:
|
|
130
|
+
assert isinstance(project.simos, SimJavaVM)
|
|
122
131
|
self._arch = {"soot": project.arch, "vex": project.simos.native_simos.arch}
|
|
123
132
|
# This flag indicates whether the current ip is a native address or
|
|
124
133
|
# a soot address descriptor.
|
|
@@ -177,6 +186,7 @@ class SimState(PluginHub):
|
|
|
177
186
|
# we have no choice but to use the 'default' plugin preset.
|
|
178
187
|
if self.plugin_preset is None:
|
|
179
188
|
self.use_plugin_preset("default")
|
|
189
|
+
assert self.plugin_preset is not None
|
|
180
190
|
|
|
181
191
|
# Determine memory backend
|
|
182
192
|
if self._is_java_project and not self._is_java_jni_project:
|
|
@@ -186,16 +196,14 @@ class SimState(PluginHub):
|
|
|
186
196
|
elif o.ABSTRACT_MEMORY in self.options:
|
|
187
197
|
# We use SimAbstractMemory in static mode.
|
|
188
198
|
# Convert memory_backer into 'global' region.
|
|
189
|
-
if cle_memory_backer is not None
|
|
190
|
-
|
|
191
|
-
if dict_memory_backer is not None:
|
|
192
|
-
dict_memory_backer = {"global": dict_memory_backer}
|
|
199
|
+
cle_memory_backer_map = {"global": cle_memory_backer} if cle_memory_backer is not None else None
|
|
200
|
+
dict_memory_backer_map = {"global": dict_memory_backer} if dict_memory_backer is not None else None
|
|
193
201
|
|
|
194
202
|
# TODO: support permissions backer in SimAbstractMemory
|
|
195
203
|
sim_memory_cls = self.plugin_preset.request_plugin("abs_memory")
|
|
196
204
|
sim_memory = sim_memory_cls(
|
|
197
|
-
cle_memory_backer=
|
|
198
|
-
dict_memory_backer=
|
|
205
|
+
cle_memory_backer=cle_memory_backer_map,
|
|
206
|
+
dict_memory_backer=dict_memory_backer_map,
|
|
199
207
|
memory_id="mem",
|
|
200
208
|
regioned_memory_cls=regioned_memory_cls,
|
|
201
209
|
)
|
|
@@ -234,6 +242,7 @@ class SimState(PluginHub):
|
|
|
234
242
|
# Same as for 'memory' plugin.
|
|
235
243
|
if self.plugin_preset is None:
|
|
236
244
|
self.use_plugin_preset("default")
|
|
245
|
+
assert self.plugin_preset is not None
|
|
237
246
|
|
|
238
247
|
# Get register endness
|
|
239
248
|
if self._is_java_jni_project:
|
|
@@ -322,17 +331,6 @@ class SimState(PluginHub):
|
|
|
322
331
|
# TODO: This shouldn't be access directly.
|
|
323
332
|
return self._active_plugins
|
|
324
333
|
|
|
325
|
-
@property
|
|
326
|
-
def se(self):
|
|
327
|
-
"""
|
|
328
|
-
Deprecated alias for `solver`
|
|
329
|
-
"""
|
|
330
|
-
global _complained_se
|
|
331
|
-
if not _complained_se:
|
|
332
|
-
_complained_se = True
|
|
333
|
-
l.critical("The name state.se is deprecated; please use state.solver.")
|
|
334
|
-
return self.get_plugin("solver")
|
|
335
|
-
|
|
336
334
|
@property
|
|
337
335
|
def ip(self):
|
|
338
336
|
"""
|
|
@@ -348,7 +346,7 @@ class SimState(PluginHub):
|
|
|
348
346
|
self.regs.ip = val
|
|
349
347
|
|
|
350
348
|
@property
|
|
351
|
-
def _ip(self):
|
|
349
|
+
def _ip(self) -> IPTypeSym:
|
|
352
350
|
"""
|
|
353
351
|
Get the instruction pointer expression without triggering SimInspect breakpoints or generating SimActions.
|
|
354
352
|
|
|
@@ -360,7 +358,7 @@ class SimState(PluginHub):
|
|
|
360
358
|
raise TypeError(str(e)) from e
|
|
361
359
|
|
|
362
360
|
@_ip.setter
|
|
363
|
-
def _ip(self, val):
|
|
361
|
+
def _ip(self, val: IPTypeSym | IPTypeConc):
|
|
364
362
|
"""
|
|
365
363
|
Set the instruction pointer without triggering SimInspect breakpoints or generating SimActions.
|
|
366
364
|
|
|
@@ -373,7 +371,7 @@ class SimState(PluginHub):
|
|
|
373
371
|
raise TypeError(str(e)) from e
|
|
374
372
|
|
|
375
373
|
@property
|
|
376
|
-
def addr(self):
|
|
374
|
+
def addr(self) -> IPTypeConc:
|
|
377
375
|
"""
|
|
378
376
|
Get the concrete address of the instruction pointer, without triggering SimInspect breakpoints or generating
|
|
379
377
|
SimActions. An integer is returned, or an exception is raised if the instruction pointer is symbolic.
|
angr/sim_type.py
CHANGED
|
@@ -535,6 +535,11 @@ class SimTypeInt256(SimTypeFixedSizeInt):
|
|
|
535
535
|
_fixed_size = 256
|
|
536
536
|
|
|
537
537
|
|
|
538
|
+
class SimTypeInt512(SimTypeFixedSizeInt):
|
|
539
|
+
_base_name = "int512_t"
|
|
540
|
+
_fixed_size = 512
|
|
541
|
+
|
|
542
|
+
|
|
538
543
|
class SimTypeChar(SimTypeReg):
|
|
539
544
|
"""
|
|
540
545
|
SimTypeChar is a type that specifies a character;
|
angr/sim_variable.py
CHANGED
|
@@ -22,7 +22,9 @@ class SimVariable(Serializable):
|
|
|
22
22
|
"size",
|
|
23
23
|
]
|
|
24
24
|
|
|
25
|
-
def __init__(
|
|
25
|
+
def __init__(
|
|
26
|
+
self, size: int, ident: str | None = None, name: str | None = None, region: int | None = None, category=None
|
|
27
|
+
):
|
|
26
28
|
"""
|
|
27
29
|
:param ident: A unique identifier provided by user or the program. Usually a string.
|
|
28
30
|
:param str name: Name of this variable.
|
|
@@ -87,7 +89,7 @@ class SimVariable(Serializable):
|
|
|
87
89
|
class SimConstantVariable(SimVariable):
|
|
88
90
|
__slots__ = ["value", "_hash"]
|
|
89
91
|
|
|
90
|
-
def __init__(self, ident=None, value=None, region=None
|
|
92
|
+
def __init__(self, size: int, ident=None, value=None, region=None):
|
|
91
93
|
super().__init__(ident=ident, region=region, size=size)
|
|
92
94
|
self.value = value
|
|
93
95
|
self._hash = None
|
|
@@ -122,7 +124,7 @@ class SimConstantVariable(SimVariable):
|
|
|
122
124
|
class SimTemporaryVariable(SimVariable):
|
|
123
125
|
__slots__ = ["tmp_id", "_hash"]
|
|
124
126
|
|
|
125
|
-
def __init__(self, tmp_id, size
|
|
127
|
+
def __init__(self, tmp_id: int, size: int):
|
|
126
128
|
SimVariable.__init__(self, size=size)
|
|
127
129
|
|
|
128
130
|
self.tmp_id = tmp_id
|
|
@@ -162,7 +164,7 @@ class SimTemporaryVariable(SimVariable):
|
|
|
162
164
|
|
|
163
165
|
@classmethod
|
|
164
166
|
def parse_from_cmessage(cls, cmsg, **kwargs):
|
|
165
|
-
obj = cls(cmsg.tmp_id)
|
|
167
|
+
obj = cls(cmsg.tmp_id, cmsg.base.size)
|
|
166
168
|
obj._from_base(cmsg)
|
|
167
169
|
return obj
|
|
168
170
|
|
|
@@ -170,10 +172,10 @@ class SimTemporaryVariable(SimVariable):
|
|
|
170
172
|
class SimRegisterVariable(SimVariable):
|
|
171
173
|
__slots__ = ["reg", "_hash"]
|
|
172
174
|
|
|
173
|
-
def __init__(self, reg_offset, size, ident=None, name=None, region=None, category=None):
|
|
175
|
+
def __init__(self, reg_offset: int, size: int, ident=None, name=None, region=None, category=None):
|
|
174
176
|
SimVariable.__init__(self, ident=ident, name=name, region=region, category=category, size=size)
|
|
175
177
|
|
|
176
|
-
self.reg
|
|
178
|
+
self.reg = reg_offset
|
|
177
179
|
self._hash: int | None = None
|
|
178
180
|
|
|
179
181
|
@property
|
|
@@ -236,7 +238,7 @@ class SimRegisterVariable(SimVariable):
|
|
|
236
238
|
class SimMemoryVariable(SimVariable):
|
|
237
239
|
__slots__ = ["addr", "_hash"]
|
|
238
240
|
|
|
239
|
-
def __init__(self, addr, size, ident=None, name=None, region=None, category=None):
|
|
241
|
+
def __init__(self, addr, size: int, ident=None, name=None, region=None, category=None):
|
|
240
242
|
SimVariable.__init__(self, ident=ident, name=name, region=region, category=category, size=size)
|
|
241
243
|
|
|
242
244
|
self.addr = addr
|
|
@@ -313,7 +315,9 @@ class SimStackVariable(SimMemoryVariable):
|
|
|
313
315
|
"base_addr",
|
|
314
316
|
)
|
|
315
317
|
|
|
316
|
-
def __init__(
|
|
318
|
+
def __init__(
|
|
319
|
+
self, offset: int, size: int, base="sp", base_addr=None, ident=None, name=None, region=None, category=None
|
|
320
|
+
):
|
|
317
321
|
if isinstance(offset, int) and offset > 0x1000000:
|
|
318
322
|
# I don't think any positive stack offset will be greater than that...
|
|
319
323
|
# convert it to a negative number
|
|
@@ -422,16 +426,15 @@ class SimVariableSet(collections.abc.MutableSet):
|
|
|
422
426
|
# For the sake of performance, we have another set that stores memory addresses of memory_variables
|
|
423
427
|
self.memory_variable_addresses = set()
|
|
424
428
|
|
|
425
|
-
def add(self,
|
|
426
|
-
if type(
|
|
427
|
-
if not self.contains_register_variable(
|
|
428
|
-
self.add_register_variable(
|
|
429
|
-
elif type(
|
|
430
|
-
if not self.contains_memory_variable(
|
|
431
|
-
self.add_memory_variable(
|
|
429
|
+
def add(self, value):
|
|
430
|
+
if type(value) is SimRegisterVariable:
|
|
431
|
+
if not self.contains_register_variable(value):
|
|
432
|
+
self.add_register_variable(value)
|
|
433
|
+
elif type(value) is SimMemoryVariable:
|
|
434
|
+
if not self.contains_memory_variable(value):
|
|
435
|
+
self.add_memory_variable(value)
|
|
432
436
|
else:
|
|
433
|
-
|
|
434
|
-
raise Exception("WTF")
|
|
437
|
+
assert False, "Unknown type"
|
|
435
438
|
|
|
436
439
|
def add_register_variable(self, reg_var):
|
|
437
440
|
self.register_variables.add(reg_var)
|
|
@@ -443,16 +446,15 @@ class SimVariableSet(collections.abc.MutableSet):
|
|
|
443
446
|
for i in range(mem_var.size):
|
|
444
447
|
self.memory_variable_addresses.add(base_address + i)
|
|
445
448
|
|
|
446
|
-
def discard(self,
|
|
447
|
-
if type(
|
|
448
|
-
if self.contains_register_variable(
|
|
449
|
-
self.discard_register_variable(
|
|
450
|
-
elif isinstance(
|
|
451
|
-
if self.contains_memory_variable(
|
|
452
|
-
self.discard_memory_variable(
|
|
449
|
+
def discard(self, value):
|
|
450
|
+
if type(value) is SimRegisterVariable:
|
|
451
|
+
if self.contains_register_variable(value):
|
|
452
|
+
self.discard_register_variable(value)
|
|
453
|
+
elif isinstance(value, SimMemoryVariable):
|
|
454
|
+
if self.contains_memory_variable(value):
|
|
455
|
+
self.discard_memory_variable(value)
|
|
453
456
|
else:
|
|
454
|
-
|
|
455
|
-
raise Exception("")
|
|
457
|
+
assert False, "Unknown type"
|
|
456
458
|
|
|
457
459
|
def discard_register_variable(self, reg_var):
|
|
458
460
|
self.register_variables.remove(reg_var)
|
|
@@ -528,5 +530,4 @@ class SimVariableSet(collections.abc.MutableSet):
|
|
|
528
530
|
# TODO: Make it better!
|
|
529
531
|
return self.contains_memory_variable(item)
|
|
530
532
|
|
|
531
|
-
|
|
532
|
-
raise Exception("WTF is this variable?")
|
|
533
|
+
assert False, "WTF is this variable?"
|
angr/utils/bits.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import claripy
|
|
4
|
+
|
|
3
5
|
|
|
4
6
|
def truncate_bits(value: int, nbits: int) -> int:
|
|
5
7
|
"""
|
|
@@ -19,3 +21,13 @@ def ffs(x: int) -> int:
|
|
|
19
21
|
def sign_extend(value: int, bits: int) -> int:
|
|
20
22
|
sign_bit = 1 << (bits - 1)
|
|
21
23
|
return (value & (sign_bit - 1)) - (value & sign_bit)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def zeroextend_on_demand(op0: claripy.ast.BV, op1: claripy.ast.BV) -> claripy.ast.BV:
|
|
27
|
+
"""
|
|
28
|
+
ZeroExtend op1 if the size of op1 is smaller than the size of op0. Otherwise, return op1.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
if op0.size() > op1.size():
|
|
32
|
+
return claripy.ZeroExt(op0.size() - op1.size(), op1)
|
|
33
|
+
return op1
|
angr/utils/orderedset.py
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
+
from typing import Generic, TypeVar
|
|
2
3
|
import collections.abc
|
|
3
4
|
|
|
5
|
+
T = TypeVar("T")
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
|
|
8
|
+
class OrderedSet(Generic[T], collections.abc.MutableSet[T]):
|
|
6
9
|
"""
|
|
7
10
|
Adapted from http://code.activestate.com/recipes/576694/
|
|
8
11
|
Originally created by Raymond Hettinger and licensed under MIT.
|