angr 9.2.131__py3-none-manylinux2014_aarch64.whl → 9.2.133__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 +128 -128
- angr/analyses/__init__.py +38 -38
- angr/analyses/analysis.py +6 -2
- angr/analyses/backward_slice.py +3 -4
- angr/analyses/binary_optimizer.py +5 -12
- angr/analyses/bindiff.py +3 -6
- angr/analyses/calling_convention.py +3 -4
- angr/analyses/cfg/__init__.py +3 -3
- angr/analyses/cfg/cfg_base.py +1 -1
- angr/analyses/cfg/cfg_emulated.py +5 -5
- angr/analyses/cfg/cfg_fast.py +19 -17
- angr/analyses/cfg/indirect_jump_resolvers/__init__.py +5 -5
- angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +1 -1
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +148 -101
- angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +1 -1
- angr/analyses/data_dep/__init__.py +4 -4
- angr/analyses/datagraph_meta.py +1 -1
- angr/analyses/ddg.py +16 -17
- angr/analyses/decompiler/__init__.py +12 -12
- angr/analyses/decompiler/ail_simplifier.py +24 -12
- angr/analyses/decompiler/block_similarity.py +2 -4
- angr/analyses/decompiler/block_simplifier.py +10 -21
- angr/analyses/decompiler/callsite_maker.py +1 -1
- angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +1 -1
- angr/analyses/decompiler/clinic.py +122 -41
- angr/analyses/decompiler/condition_processor.py +57 -39
- angr/analyses/decompiler/counters/__init__.py +3 -3
- angr/analyses/decompiler/decompilation_cache.py +7 -7
- angr/analyses/decompiler/dephication/__init__.py +1 -1
- angr/analyses/decompiler/dephication/graph_rewriting.py +1 -1
- angr/analyses/decompiler/dephication/graph_vvar_mapping.py +11 -3
- angr/analyses/decompiler/dephication/rewriting_engine.py +169 -45
- angr/analyses/decompiler/dephication/seqnode_dephication.py +5 -4
- angr/analyses/decompiler/expression_narrower.py +1 -1
- angr/analyses/decompiler/graph_region.py +8 -8
- angr/analyses/decompiler/optimization_passes/__init__.py +20 -20
- angr/analyses/decompiler/optimization_passes/const_derefs.py +1 -0
- angr/analyses/decompiler/optimization_passes/deadblock_remover.py +1 -2
- angr/analyses/decompiler/optimization_passes/div_simplifier.py +41 -16
- angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +8 -7
- angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py +1 -3
- angr/analyses/decompiler/optimization_passes/engine_base.py +262 -84
- angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +175 -39
- angr/analyses/decompiler/optimization_passes/ite_region_converter.py +2 -5
- angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +5 -5
- angr/analyses/decompiler/optimization_passes/mod_simplifier.py +12 -3
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +42 -19
- angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +9 -5
- angr/analyses/decompiler/peephole_optimizations/__init__.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/base.py +6 -6
- angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +2 -0
- angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +1 -1
- angr/analyses/decompiler/presets/__init__.py +1 -1
- angr/analyses/decompiler/region_simplifiers/expr_folding.py +3 -3
- angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +8 -12
- angr/analyses/decompiler/ssailification/rewriting.py +1 -2
- angr/analyses/decompiler/ssailification/rewriting_engine.py +139 -56
- 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/__init__.py +5 -5
- angr/analyses/decompiler/structured_codegen/base.py +3 -3
- angr/analyses/decompiler/structured_codegen/c.py +39 -40
- angr/analyses/decompiler/structuring/__init__.py +3 -3
- angr/analyses/decompiler/structuring/phoenix.py +45 -29
- angr/analyses/decompiler/structuring/structurer_base.py +2 -2
- angr/analyses/decompiler/structuring/structurer_nodes.py +23 -14
- angr/analyses/deobfuscator/__init__.py +3 -3
- angr/analyses/deobfuscator/irsb_reg_collector.py +29 -60
- angr/analyses/deobfuscator/string_obf_finder.py +2 -2
- angr/analyses/deobfuscator/string_obf_opt_passes.py +1 -1
- angr/analyses/disassembly.py +4 -4
- angr/analyses/forward_analysis/__init__.py +1 -1
- angr/analyses/forward_analysis/visitors/graph.py +6 -6
- angr/analyses/init_finder.py +47 -22
- angr/analyses/loop_analysis.py +1 -1
- angr/analyses/loopfinder.py +1 -1
- angr/analyses/propagator/engine_base.py +21 -14
- angr/analyses/propagator/engine_vex.py +149 -179
- angr/analyses/propagator/outdated_definition_walker.py +12 -6
- angr/analyses/propagator/propagator.py +10 -28
- angr/analyses/propagator/top_checker_mixin.py +211 -5
- angr/analyses/propagator/vex_vars.py +4 -4
- angr/analyses/reaching_definitions/__init__.py +9 -9
- angr/analyses/reaching_definitions/call_trace.py +2 -2
- 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/function_handler_library/__init__.py +1 -1
- angr/analyses/reaching_definitions/rd_state.py +47 -42
- angr/analyses/reassembler.py +26 -31
- angr/analyses/s_liveness.py +8 -0
- angr/analyses/s_propagator.py +18 -3
- angr/analyses/s_reaching_definitions/s_rda_view.py +2 -5
- angr/analyses/s_reaching_definitions/s_reaching_definitions.py +9 -5
- angr/analyses/stack_pointer_tracker.py +4 -4
- angr/analyses/typehoon/simple_solver.py +14 -14
- angr/analyses/typehoon/translator.py +10 -2
- angr/analyses/typehoon/typeconsts.py +11 -3
- angr/analyses/typehoon/typevars.py +26 -26
- angr/analyses/unpacker/__init__.py +1 -1
- angr/analyses/variable_recovery/engine_ail.py +299 -259
- angr/analyses/variable_recovery/engine_base.py +138 -121
- 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 +33 -34
- angr/analyses/variable_recovery/variable_recovery_fast.py +4 -8
- angr/analyses/veritesting.py +2 -2
- angr/analyses/vfg.py +5 -5
- angr/analyses/xrefs.py +46 -19
- angr/angrdb/serializers/__init__.py +1 -1
- angr/annocfg.py +20 -15
- angr/blade.py +2 -2
- angr/block.py +20 -25
- angr/calling_conventions.py +12 -14
- angr/code_location.py +6 -10
- angr/codenode.py +3 -3
- angr/engines/__init__.py +12 -14
- angr/engines/engine.py +24 -61
- angr/engines/light/__init__.py +13 -5
- angr/engines/light/data.py +1 -1
- angr/engines/light/engine.py +1003 -1185
- angr/engines/pcode/__init__.py +1 -1
- angr/engines/pcode/behavior.py +1 -1
- angr/engines/pcode/cc.py +2 -0
- angr/engines/pcode/lifter.py +13 -15
- angr/engines/soot/expressions/__init__.py +12 -12
- angr/engines/soot/statements/__init__.py +6 -6
- angr/engines/soot/values/__init__.py +6 -6
- angr/engines/soot/values/arrayref.py +2 -2
- angr/engines/soot/values/constants.py +1 -1
- angr/engines/soot/values/instancefieldref.py +1 -1
- angr/engines/soot/values/paramref.py +1 -1
- angr/engines/soot/values/staticfieldref.py +1 -1
- angr/engines/successors.py +15 -14
- angr/engines/vex/__init__.py +5 -5
- angr/engines/vex/claripy/ccall.py +2 -2
- angr/engines/vex/claripy/datalayer.py +1 -1
- angr/engines/vex/claripy/irop.py +19 -19
- angr/engines/vex/heavy/__init__.py +2 -2
- angr/engines/vex/heavy/actions.py +1 -3
- angr/engines/vex/heavy/heavy.py +4 -6
- angr/engines/vex/lifter.py +2 -4
- angr/engines/vex/light/light.py +0 -2
- angr/engines/vex/light/slicing.py +5 -5
- angr/exploration_techniques/__init__.py +19 -142
- 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 +2 -11
- 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/factory.py +36 -6
- angr/keyed_region.py +4 -4
- angr/knowledge_base.py +1 -1
- angr/knowledge_plugins/__init__.py +11 -11
- angr/knowledge_plugins/cfg/__init__.py +5 -5
- angr/knowledge_plugins/cfg/cfg_manager.py +2 -2
- angr/knowledge_plugins/cfg/cfg_model.py +8 -8
- angr/knowledge_plugins/cfg/cfg_node.py +19 -19
- angr/knowledge_plugins/cfg/indirect_jump.py +6 -6
- angr/knowledge_plugins/cfg/memory_data.py +5 -7
- angr/knowledge_plugins/functions/function.py +48 -52
- angr/knowledge_plugins/functions/function_parser.py +4 -4
- angr/knowledge_plugins/key_definitions/__init__.py +3 -3
- angr/knowledge_plugins/key_definitions/atoms.py +8 -8
- angr/knowledge_plugins/key_definitions/definition.py +1 -1
- angr/knowledge_plugins/key_definitions/live_definitions.py +30 -27
- angr/knowledge_plugins/labels.py +1 -1
- angr/knowledge_plugins/propagations/__init__.py +1 -1
- angr/knowledge_plugins/propagations/prop_value.py +2 -2
- angr/knowledge_plugins/propagations/propagation_model.py +7 -8
- angr/knowledge_plugins/propagations/states.py +44 -39
- angr/knowledge_plugins/variables/variable_access.py +2 -2
- angr/knowledge_plugins/variables/variable_manager.py +24 -10
- angr/knowledge_plugins/xrefs/xref.py +5 -8
- angr/misc/__init__.py +4 -4
- angr/misc/hookset.py +4 -5
- angr/misc/loggers.py +2 -2
- angr/misc/telemetry.py +1 -1
- angr/procedures/__init__.py +1 -1
- angr/procedures/cgc/fdwait.py +2 -2
- angr/procedures/definitions/__init__.py +2 -2
- angr/procedures/definitions/linux_kernel.py +0 -1
- angr/procedures/definitions/parse_syscalls_from_local_system.py +1 -1
- angr/procedures/definitions/parse_win32json.py +0 -1
- angr/procedures/ntdll/exceptions.py +1 -1
- angr/procedures/stubs/format_parser.py +3 -3
- angr/procedures/win32/dynamic_loading.py +1 -1
- angr/protos/__init__.py +3 -3
- angr/sim_manager.py +3 -5
- angr/sim_state.py +40 -42
- angr/sim_state_options.py +3 -3
- angr/sim_type.py +15 -14
- angr/sim_variable.py +42 -45
- angr/simos/__init__.py +4 -4
- angr/simos/cgc.py +1 -1
- angr/simos/simos.py +1 -1
- angr/simos/userland.py +1 -1
- angr/slicer.py +4 -7
- angr/state_plugins/__init__.py +34 -34
- angr/state_plugins/callstack.py +5 -12
- angr/state_plugins/heap/__init__.py +2 -2
- angr/state_plugins/heap/heap_brk.py +2 -4
- angr/state_plugins/heap/heap_ptmalloc.py +1 -1
- angr/state_plugins/jni_references.py +3 -2
- angr/state_plugins/scratch.py +1 -1
- angr/state_plugins/sim_action.py +1 -4
- angr/state_plugins/sim_event.py +1 -1
- angr/state_plugins/solver.py +7 -9
- angr/state_plugins/uc_manager.py +1 -1
- angr/state_plugins/view.py +2 -2
- angr/storage/__init__.py +1 -1
- angr/storage/file.py +10 -10
- angr/storage/memory_mixins/__init__.py +46 -46
- angr/storage/memory_mixins/default_filler_mixin.py +1 -3
- angr/storage/memory_mixins/javavm_memory_mixin.py +2 -2
- angr/storage/memory_mixins/name_resolution_mixin.py +2 -2
- angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +1 -3
- angr/storage/memory_mixins/paged_memory/pages/__init__.py +6 -6
- angr/storage/memory_mixins/paged_memory/pages/list_page.py +1 -1
- angr/storage/memory_mixins/paged_memory/pages/multi_values.py +1 -1
- angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +1 -1
- angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +2 -4
- angr/storage/memory_mixins/regioned_memory/__init__.py +3 -3
- angr/storage/memory_mixins/regioned_memory/region_data.py +5 -5
- angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +7 -9
- angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +4 -4
- angr/storage/memory_object.py +4 -4
- angr/utils/__init__.py +3 -3
- angr/utils/bits.py +12 -0
- angr/utils/dynamic_dictlist.py +1 -1
- angr/utils/graph.py +1 -1
- angr/utils/orderedset.py +4 -1
- angr/utils/segment_list.py +2 -2
- angr/utils/ssa/__init__.py +33 -8
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/METADATA +6 -6
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/RECORD +262 -263
- 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.133.dist-info}/LICENSE +0 -0
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/WHEEL +0 -0
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/entry_points.txt +0 -0
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/top_level.txt +0 -0
|
@@ -86,7 +86,7 @@ class FunctionCallData:
|
|
|
86
86
|
|
|
87
87
|
callsite_codeloc: CodeLocation
|
|
88
88
|
function_codeloc: CodeLocation
|
|
89
|
-
address_multi: MultiValues | None
|
|
89
|
+
address_multi: MultiValues[claripy.ast.BV | claripy.ast.FP] | None
|
|
90
90
|
address: int | None = None
|
|
91
91
|
symbol: Symbol | None = None
|
|
92
92
|
function: Function | None = None
|
|
@@ -94,12 +94,12 @@ class FunctionCallData:
|
|
|
94
94
|
cc: SimCC | None = None
|
|
95
95
|
prototype: SimTypeFunction | None = None
|
|
96
96
|
args_atoms: list[set[Atom]] | None = None
|
|
97
|
-
args_values: list[MultiValues] | None = None
|
|
97
|
+
args_values: list[MultiValues[claripy.ast.BV | claripy.ast.FP]] | None = None
|
|
98
98
|
ret_atoms: set[Atom] | None = None
|
|
99
99
|
redefine_locals: bool = True
|
|
100
100
|
visited_blocks: set[int] | None = None
|
|
101
101
|
effects: list[FunctionEffect] = field(default_factory=list)
|
|
102
|
-
ret_values: MultiValues | None = None
|
|
102
|
+
ret_values: MultiValues[claripy.ast.BV | claripy.ast.FP] | None = None
|
|
103
103
|
ret_values_deps: set[Definition] | None = None
|
|
104
104
|
caller_will_handle_single_ret: bool = False
|
|
105
105
|
guessed_cc: bool = False
|
|
@@ -9,4 +9,4 @@ class LibcHandlers(LibcStdlibHandlers, LibcStdioHandlers, LibcUnistdHandlers, Li
|
|
|
9
9
|
pass
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
__all__ = ["EnvironAtom", "
|
|
12
|
+
__all__ = ["EnvironAtom", "ExecveAtom", "LibcHandlers", "StdinAtom", "StdoutAtom", "SystemAtom"]
|
|
@@ -1,7 +1,8 @@
|
|
|
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, Iterator
|
|
4
4
|
import logging
|
|
5
|
+
from typing_extensions import Self
|
|
5
6
|
|
|
6
7
|
import archinfo
|
|
7
8
|
import claripy
|
|
@@ -13,7 +14,7 @@ from angr.knowledge_plugins.key_definitions.heap_address import HeapAddress
|
|
|
13
14
|
from angr.knowledge_plugins.key_definitions.definition import A
|
|
14
15
|
from angr.engines.light import SpOffset
|
|
15
16
|
from angr.code_location import CodeLocation
|
|
16
|
-
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
|
|
17
18
|
from angr.storage.memory_mixins import MultiValuedMemory
|
|
18
19
|
from angr.knowledge_plugins.key_definitions import LiveDefinitions, DerefSize, Definition
|
|
19
20
|
from angr.knowledge_plugins.key_definitions.atoms import Atom, GuardUse, Register, MemoryLocation, ConstantSrc
|
|
@@ -55,21 +56,21 @@ class ReachingDefinitionsState:
|
|
|
55
56
|
"""
|
|
56
57
|
|
|
57
58
|
__slots__ = (
|
|
58
|
-
"
|
|
59
|
+
"_canonical_size",
|
|
60
|
+
"_element_limit",
|
|
61
|
+
"_environment",
|
|
62
|
+
"_sp_adjusted",
|
|
59
63
|
"_subject",
|
|
64
|
+
"_track_consts",
|
|
60
65
|
"_track_tmps",
|
|
66
|
+
"all_definitions",
|
|
61
67
|
"analysis",
|
|
68
|
+
"arch",
|
|
62
69
|
"codeloc",
|
|
63
70
|
"codeloc_uses",
|
|
64
|
-
"live_definitions",
|
|
65
|
-
"all_definitions",
|
|
66
|
-
"_canonical_size",
|
|
67
|
-
"heap_allocator",
|
|
68
|
-
"_environment",
|
|
69
|
-
"_track_consts",
|
|
70
|
-
"_sp_adjusted",
|
|
71
71
|
"exit_observed",
|
|
72
|
-
"
|
|
72
|
+
"heap_allocator",
|
|
73
|
+
"live_definitions",
|
|
73
74
|
)
|
|
74
75
|
|
|
75
76
|
def __init__(
|
|
@@ -77,14 +78,14 @@ class ReachingDefinitionsState:
|
|
|
77
78
|
codeloc: CodeLocation,
|
|
78
79
|
arch: archinfo.Arch,
|
|
79
80
|
subject: Subject,
|
|
81
|
+
analysis: ReachingDefinitionsAnalysis,
|
|
80
82
|
track_tmps: bool = False,
|
|
81
83
|
track_consts: bool = False,
|
|
82
|
-
analysis: ReachingDefinitionsAnalysis | None = None,
|
|
83
84
|
rtoc_value=None,
|
|
84
85
|
live_definitions: LiveDefinitions | None = None,
|
|
85
86
|
canonical_size: int = 8,
|
|
86
|
-
heap_allocator: HeapAllocator = None,
|
|
87
|
-
environment: Environment = None,
|
|
87
|
+
heap_allocator: HeapAllocator | None = None,
|
|
88
|
+
environment: Environment | None = None,
|
|
88
89
|
sp_adjusted: bool = False,
|
|
89
90
|
all_definitions: set[Definition[A]] | None = None,
|
|
90
91
|
initializer: RDAStateInitializer | None = None,
|
|
@@ -102,12 +103,12 @@ class ReachingDefinitionsState:
|
|
|
102
103
|
self._sp_adjusted: bool = sp_adjusted
|
|
103
104
|
self._element_limit: int = element_limit
|
|
104
105
|
|
|
105
|
-
self.all_definitions: set[Definition[
|
|
106
|
+
self.all_definitions: set[Definition[Any]] = set() if all_definitions is None else all_definitions
|
|
106
107
|
|
|
107
108
|
self.heap_allocator = heap_allocator or HeapAllocator(canonical_size)
|
|
108
109
|
self._environment: Environment = environment or Environment()
|
|
109
110
|
|
|
110
|
-
self.codeloc_uses: set[Definition[
|
|
111
|
+
self.codeloc_uses: set[Definition[Any]] = set()
|
|
111
112
|
|
|
112
113
|
# have we observed an exit statement or not during the analysis of the *last instruction* of a block? we should
|
|
113
114
|
# not perform any sp updates if it is the case. this is for handling conditional returns in ARM binaries.
|
|
@@ -176,7 +177,7 @@ class ReachingDefinitionsState:
|
|
|
176
177
|
return claripy.BVS("stack_base", 32, explicit_name=True)
|
|
177
178
|
if self.arch.bits == 64:
|
|
178
179
|
return claripy.BVS("stack_base", 64, explicit_name=True)
|
|
179
|
-
raise ValueError("Unsupported architecture word size
|
|
180
|
+
raise ValueError(f"Unsupported architecture word size {self.arch.bits}")
|
|
180
181
|
|
|
181
182
|
def _to_signed(self, n):
|
|
182
183
|
if n >= 2 ** (self.arch.bits - 1):
|
|
@@ -184,7 +185,7 @@ class ReachingDefinitionsState:
|
|
|
184
185
|
return n - 2**self.arch.bits
|
|
185
186
|
return n
|
|
186
187
|
|
|
187
|
-
def annotate_with_def(self, symvar:
|
|
188
|
+
def annotate_with_def(self, symvar: MVType, definition: Definition[Any]) -> MVType:
|
|
188
189
|
"""
|
|
189
190
|
|
|
190
191
|
:param symvar:
|
|
@@ -193,14 +194,14 @@ class ReachingDefinitionsState:
|
|
|
193
194
|
"""
|
|
194
195
|
return self.live_definitions.annotate_with_def(symvar, definition)
|
|
195
196
|
|
|
196
|
-
def annotate_mv_with_def(self, mv: MultiValues, definition: Definition[A]) -> MultiValues:
|
|
197
|
+
def annotate_mv_with_def(self, mv: MultiValues[MVType], definition: Definition[A]) -> MultiValues[MVType]:
|
|
197
198
|
return MultiValues(
|
|
198
199
|
offset_to_values={
|
|
199
200
|
offset: {self.annotate_with_def(value, definition) for value in values} for offset, values in mv.items()
|
|
200
201
|
}
|
|
201
202
|
)
|
|
202
203
|
|
|
203
|
-
def extract_defs(self, symvar: claripy.ast.Base) -> Iterator[Definition[
|
|
204
|
+
def extract_defs(self, symvar: claripy.ast.Base) -> Iterator[Definition[Any]]:
|
|
204
205
|
yield from self.live_definitions.extract_defs(symvar)
|
|
205
206
|
|
|
206
207
|
#
|
|
@@ -254,7 +255,7 @@ class ReachingDefinitionsState:
|
|
|
254
255
|
def get_sp(self) -> int:
|
|
255
256
|
return self.live_definitions.get_sp()
|
|
256
257
|
|
|
257
|
-
def get_stack_address(self, offset: claripy.ast.Base) -> int:
|
|
258
|
+
def get_stack_address(self, offset: claripy.ast.Base) -> int | None:
|
|
258
259
|
return self.live_definitions.get_stack_address(offset)
|
|
259
260
|
|
|
260
261
|
@property
|
|
@@ -300,8 +301,8 @@ class ReachingDefinitionsState:
|
|
|
300
301
|
|
|
301
302
|
return self
|
|
302
303
|
|
|
303
|
-
def copy(self, discard_tmpdefs=False) ->
|
|
304
|
-
return
|
|
304
|
+
def copy(self, discard_tmpdefs=False) -> Self:
|
|
305
|
+
return type(self)(
|
|
305
306
|
self.codeloc,
|
|
306
307
|
self.arch,
|
|
307
308
|
self._subject,
|
|
@@ -317,9 +318,8 @@ class ReachingDefinitionsState:
|
|
|
317
318
|
element_limit=self._element_limit,
|
|
318
319
|
)
|
|
319
320
|
|
|
320
|
-
def merge(self, *others) -> tuple[
|
|
321
|
+
def merge(self, *others: Self) -> tuple[Self, bool]:
|
|
321
322
|
state = self.copy()
|
|
322
|
-
others: Iterable[ReachingDefinitionsState]
|
|
323
323
|
|
|
324
324
|
state.live_definitions, merged_0 = state.live_definitions.merge(*[other.live_definitions for other in others])
|
|
325
325
|
state._environment, merged_1 = state.environment.merge(*[other.environment for other in others])
|
|
@@ -419,10 +419,12 @@ class ReachingDefinitionsState:
|
|
|
419
419
|
for def_ in defs:
|
|
420
420
|
if not def_.dummy:
|
|
421
421
|
self._dep_graph.add_edge(used, def_)
|
|
422
|
+
|
|
423
|
+
cfg = self.analysis.project.kb.cfgs.get_most_accurate()
|
|
422
424
|
self._dep_graph.add_dependencies_for_concrete_pointers_of(
|
|
423
425
|
values,
|
|
424
426
|
used,
|
|
425
|
-
|
|
427
|
+
cfg,
|
|
426
428
|
self.analysis.project.loader,
|
|
427
429
|
)
|
|
428
430
|
else:
|
|
@@ -491,7 +493,9 @@ class ReachingDefinitionsState:
|
|
|
491
493
|
self.codeloc_uses.add(definition)
|
|
492
494
|
self.live_definitions.add_memory_use_by_def(definition, self.codeloc, expr=expr)
|
|
493
495
|
|
|
494
|
-
def get_definitions(
|
|
496
|
+
def get_definitions(
|
|
497
|
+
self, atom: Atom | Definition[Atom] | Iterable[Atom] | Iterable[Definition[Atom]]
|
|
498
|
+
) -> set[Definition[Atom]]:
|
|
495
499
|
return self.live_definitions.get_definitions(atom)
|
|
496
500
|
|
|
497
501
|
def get_values(self, spec: A | Definition[A] | Iterable[A]) -> MultiValues | None:
|
|
@@ -503,13 +507,15 @@ class ReachingDefinitionsState:
|
|
|
503
507
|
return self.live_definitions.get_one_value(spec, strip_annotations=strip_annotations)
|
|
504
508
|
|
|
505
509
|
@overload
|
|
506
|
-
def get_concrete_value(self, spec:
|
|
510
|
+
def get_concrete_value(self, spec: Atom | Definition[Atom] | Iterable[Atom], cast_to: type[int]) -> int | None: ...
|
|
507
511
|
|
|
508
512
|
@overload
|
|
509
|
-
def get_concrete_value(
|
|
513
|
+
def get_concrete_value(
|
|
514
|
+
self, spec: Atom | Definition[Atom] | Iterable[Atom], cast_to: type[bytes]
|
|
515
|
+
) -> bytes | None: ...
|
|
510
516
|
|
|
511
517
|
def get_concrete_value(
|
|
512
|
-
self, spec:
|
|
518
|
+
self, spec: Atom | Definition[Atom] | Iterable[Atom], cast_to: type[int] | type[bytes] = int
|
|
513
519
|
) -> int | bytes | None:
|
|
514
520
|
return self.live_definitions.get_concrete_value(spec, cast_to)
|
|
515
521
|
|
|
@@ -551,11 +557,10 @@ class ReachingDefinitionsState:
|
|
|
551
557
|
return result
|
|
552
558
|
|
|
553
559
|
@deprecated("deref")
|
|
554
|
-
def pointer_to_atom(self, value: claripy.ast.
|
|
560
|
+
def pointer_to_atom(self, value: claripy.ast.BV, size: int, endness: str) -> MemoryLocation | None:
|
|
555
561
|
if self.is_top(value):
|
|
556
562
|
return None
|
|
557
563
|
|
|
558
|
-
# TODO this can be simplified with the walrus operator
|
|
559
564
|
stack_offset = self.get_stack_offset(value)
|
|
560
565
|
if stack_offset is not None:
|
|
561
566
|
addr = SpOffset(len(value), stack_offset)
|
|
@@ -564,7 +569,7 @@ class ReachingDefinitionsState:
|
|
|
564
569
|
if heap_offset is not None:
|
|
565
570
|
addr = HeapAddress(heap_offset)
|
|
566
571
|
elif value.op == "BVV":
|
|
567
|
-
addr = value.args[0]
|
|
572
|
+
addr = cast(int, value.args[0])
|
|
568
573
|
else:
|
|
569
574
|
# cannot resolve
|
|
570
575
|
return None
|
|
@@ -574,9 +579,9 @@ class ReachingDefinitionsState:
|
|
|
574
579
|
@overload
|
|
575
580
|
def deref(
|
|
576
581
|
self,
|
|
577
|
-
pointer: int | claripy.ast.
|
|
582
|
+
pointer: int | claripy.ast.BV | HeapAddress | SpOffset,
|
|
578
583
|
size: int | DerefSize,
|
|
579
|
-
endness:
|
|
584
|
+
endness: archinfo.Endness = ...,
|
|
580
585
|
) -> MemoryLocation | None: ...
|
|
581
586
|
|
|
582
587
|
@overload
|
|
@@ -584,23 +589,23 @@ class ReachingDefinitionsState:
|
|
|
584
589
|
self,
|
|
585
590
|
pointer: MultiValues | A | Definition | Iterable[A] | Iterable[Definition[A]],
|
|
586
591
|
size: int | DerefSize,
|
|
587
|
-
endness:
|
|
592
|
+
endness: archinfo.Endness = ...,
|
|
588
593
|
) -> set[MemoryLocation]: ...
|
|
589
594
|
|
|
590
595
|
def deref(
|
|
591
596
|
self,
|
|
592
597
|
pointer: (
|
|
593
|
-
MultiValues
|
|
594
|
-
|
|
|
595
|
-
| Definition
|
|
596
|
-
| Iterable[
|
|
597
|
-
| Iterable[Definition[
|
|
598
|
+
MultiValues[claripy.ast.BV]
|
|
599
|
+
| Atom
|
|
600
|
+
| Definition[Atom]
|
|
601
|
+
| Iterable[Atom]
|
|
602
|
+
| Iterable[Definition[Atom]]
|
|
598
603
|
| int
|
|
599
604
|
| claripy.ast.BV
|
|
600
605
|
| HeapAddress
|
|
601
606
|
| SpOffset
|
|
602
607
|
),
|
|
603
608
|
size: int | DerefSize,
|
|
604
|
-
endness:
|
|
609
|
+
endness: archinfo.Endness = archinfo.Endness.BE,
|
|
605
610
|
):
|
|
606
611
|
return self.live_definitions.deref(pointer, size, endness)
|
angr/analyses/reassembler.py
CHANGED
|
@@ -152,7 +152,7 @@ class Label:
|
|
|
152
152
|
self.var_size = None
|
|
153
153
|
|
|
154
154
|
if self.name is None:
|
|
155
|
-
self.name = "label_
|
|
155
|
+
self.name = f"label_{next(Label.g_label_ctr)}"
|
|
156
156
|
|
|
157
157
|
self.original_addr = original_addr
|
|
158
158
|
self.base_addr = None
|
|
@@ -189,7 +189,7 @@ class Label:
|
|
|
189
189
|
offset = self.offset
|
|
190
190
|
sign = "+" if offset >= 0 else "-"
|
|
191
191
|
offset = abs(offset)
|
|
192
|
-
return "
|
|
192
|
+
return f".{self.name}{sign}{offset}"
|
|
193
193
|
|
|
194
194
|
@property
|
|
195
195
|
def offset(self):
|
|
@@ -318,7 +318,7 @@ class SymbolManager:
|
|
|
318
318
|
|
|
319
319
|
i = 0
|
|
320
320
|
while True:
|
|
321
|
-
name = "
|
|
321
|
+
name = f"{symbol_name}_{i}"
|
|
322
322
|
if name not in self.symbol_names:
|
|
323
323
|
self.symbol_names.add(name)
|
|
324
324
|
return name
|
|
@@ -473,9 +473,9 @@ class Operand:
|
|
|
473
473
|
def assembly(self):
|
|
474
474
|
if self.type == OP_TYPE_IMM and self.label:
|
|
475
475
|
if self.label_offset > 0:
|
|
476
|
-
return "
|
|
476
|
+
return f"{self.label.operand_str} + {self.label_offset}"
|
|
477
477
|
if self.label_offset < 0:
|
|
478
|
-
return "
|
|
478
|
+
return f"{self.label.operand_str} - {abs(self.label_offset)}"
|
|
479
479
|
return self.label.operand_str
|
|
480
480
|
|
|
481
481
|
if self.type == OP_TYPE_MEM:
|
|
@@ -483,13 +483,13 @@ class Operand:
|
|
|
483
483
|
if self.disp:
|
|
484
484
|
if self.disp_label:
|
|
485
485
|
if self.disp_label_offset > 0:
|
|
486
|
-
disp = "
|
|
486
|
+
disp = f"{self.disp_label.operand_str} + {self.disp_label_offset}"
|
|
487
487
|
elif self.disp_label_offset < 0:
|
|
488
|
-
disp = "
|
|
488
|
+
disp = f"{self.disp_label.operand_str} - {abs(self.disp_label_offset)}"
|
|
489
489
|
else:
|
|
490
490
|
disp = self.disp_label.operand_str
|
|
491
491
|
else:
|
|
492
|
-
disp = "
|
|
492
|
+
disp = f"{self.disp}"
|
|
493
493
|
|
|
494
494
|
base = ""
|
|
495
495
|
if self.base:
|
|
@@ -504,12 +504,7 @@ class Operand:
|
|
|
504
504
|
disp = "*" + disp
|
|
505
505
|
|
|
506
506
|
if self.index:
|
|
507
|
-
s = "
|
|
508
|
-
disp,
|
|
509
|
-
base,
|
|
510
|
-
CAPSTONE_REG_MAP[self.project.arch.name][self.index],
|
|
511
|
-
self.scale,
|
|
512
|
-
)
|
|
507
|
+
s = f"{disp}({base}, %{CAPSTONE_REG_MAP[self.project.arch.name][self.index]}, {self.scale})"
|
|
513
508
|
elif self.base: # not self.index
|
|
514
509
|
s = f"{disp}({base})"
|
|
515
510
|
else:
|
|
@@ -524,7 +519,7 @@ class Operand:
|
|
|
524
519
|
if self.index and self.scale:
|
|
525
520
|
if s:
|
|
526
521
|
s.append("+")
|
|
527
|
-
s.append("(
|
|
522
|
+
s.append(f"({CAPSTONE_REG_MAP[self.project.arch.name][self.index]} * {self.scale})")
|
|
528
523
|
|
|
529
524
|
if disp:
|
|
530
525
|
if disp.startswith("-"):
|
|
@@ -807,7 +802,7 @@ class Instruction:
|
|
|
807
802
|
if op.type in (OP_TYPE_IMM, OP_TYPE_MEM, OP_TYPE_RAW):
|
|
808
803
|
all_operands[i] = op_asm
|
|
809
804
|
else:
|
|
810
|
-
raise BinaryError("Unsupported operand type
|
|
805
|
+
raise BinaryError(f"Unsupported operand type {op.type}.")
|
|
811
806
|
|
|
812
807
|
if op.type != OP_TYPE_RAW and self.capstone_operand_types[i] == capstone.CS_OP_IMM:
|
|
813
808
|
if mnemonic.startswith(("j", "call", "loop")):
|
|
@@ -1247,7 +1242,7 @@ class Data:
|
|
|
1247
1242
|
self._initialize()
|
|
1248
1243
|
|
|
1249
1244
|
def __repr__(self):
|
|
1250
|
-
return "<DataItem
|
|
1245
|
+
return f"<DataItem {self.sort}@{self.addr:#08x}, {self.size} bytes>"
|
|
1251
1246
|
|
|
1252
1247
|
@property
|
|
1253
1248
|
def content(self):
|
|
@@ -1399,7 +1394,7 @@ class Data:
|
|
|
1399
1394
|
i += self.project.arch.bytes
|
|
1400
1395
|
|
|
1401
1396
|
if isinstance(symbolized_label, int):
|
|
1402
|
-
s += "\t
|
|
1397
|
+
s += f"\t{directive} {symbolized_label}\n"
|
|
1403
1398
|
else:
|
|
1404
1399
|
s += f"\t{directive} {symbolized_label.operand_str}\n"
|
|
1405
1400
|
|
|
@@ -1442,11 +1437,12 @@ class Data:
|
|
|
1442
1437
|
|
|
1443
1438
|
show_integer = False
|
|
1444
1439
|
if len(addr_to_labels) == 0 or (
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1440
|
+
(
|
|
1441
|
+
len(addr_to_labels) == 1
|
|
1442
|
+
and self.addr is not None
|
|
1443
|
+
and next(iter(addr_to_labels.keys())) == self.addr
|
|
1444
|
+
)
|
|
1445
|
+
or (self.addr is None and next(iter(addr_to_labels.keys())) == 0)
|
|
1450
1446
|
):
|
|
1451
1447
|
show_integer = True
|
|
1452
1448
|
|
|
@@ -1474,7 +1470,7 @@ class Data:
|
|
|
1474
1470
|
content += [f"{label!s}"]
|
|
1475
1471
|
addr += 1
|
|
1476
1472
|
|
|
1477
|
-
content += ["\t.byte
|
|
1473
|
+
content += [f"\t.byte {c}"]
|
|
1478
1474
|
|
|
1479
1475
|
else:
|
|
1480
1476
|
integer = struct.unpack(fmt_str, self.content[0])[0]
|
|
@@ -1508,10 +1504,10 @@ class Data:
|
|
|
1508
1504
|
content += [f"{label!s}"]
|
|
1509
1505
|
addr += 1
|
|
1510
1506
|
|
|
1511
|
-
content += ["\t.byte
|
|
1507
|
+
content += [f"\t.byte {c}"]
|
|
1512
1508
|
else:
|
|
1513
1509
|
for piece in self.content:
|
|
1514
|
-
content += ["\t.byte
|
|
1510
|
+
content += [f"\t.byte {c}" for c in piece]
|
|
1515
1511
|
|
|
1516
1512
|
s += "\n".join(content)
|
|
1517
1513
|
s += "\n"
|
|
@@ -1534,10 +1530,10 @@ class Data:
|
|
|
1534
1530
|
content += [f"{label!s}"]
|
|
1535
1531
|
addr += 1
|
|
1536
1532
|
|
|
1537
|
-
content += ["\t.byte
|
|
1533
|
+
content += [f"\t.byte {c}"]
|
|
1538
1534
|
else:
|
|
1539
1535
|
for piece in self.content:
|
|
1540
|
-
content += ["\t.byte
|
|
1536
|
+
content += [f"\t.byte {c}" for c in piece]
|
|
1541
1537
|
|
|
1542
1538
|
s += "\n".join(content)
|
|
1543
1539
|
s += "\n"
|
|
@@ -1554,7 +1550,7 @@ class Data:
|
|
|
1554
1550
|
|
|
1555
1551
|
def _initialize(self):
|
|
1556
1552
|
if self.memory_data is None:
|
|
1557
|
-
if self.size is None or self._initial_content is None and self.sort is None:
|
|
1553
|
+
if self.size is None or (self._initial_content is None and self.sort is None):
|
|
1558
1554
|
raise BinaryError("You must at least specify size, initial_content, and sort.")
|
|
1559
1555
|
|
|
1560
1556
|
if self.sort == MemoryDataSort.PointerArray:
|
|
@@ -2647,8 +2643,7 @@ class Reassembler(Analysis):
|
|
|
2647
2643
|
return bool(
|
|
2648
2644
|
cfg.project.loader.find_section_containing(ptr) is not None
|
|
2649
2645
|
or cfg.project.loader.find_segment_containing(ptr) is not None
|
|
2650
|
-
or self._extra_memory_regions
|
|
2651
|
-
and next((a < ptr < b for a, b in self._extra_memory_regions), None)
|
|
2646
|
+
or (self._extra_memory_regions and next((a < ptr < b for a, b in self._extra_memory_regions), None))
|
|
2652
2647
|
)
|
|
2653
2648
|
|
|
2654
2649
|
def _sequence_handler(self, cfg, irsb, irsb_addr, stmt_idx, data_addr, max_size): # pylint:disable=unused-argument
|
angr/analyses/s_liveness.py
CHANGED
|
@@ -29,6 +29,7 @@ class SLivenessAnalysis(Analysis):
|
|
|
29
29
|
func_graph=None,
|
|
30
30
|
entry=None,
|
|
31
31
|
func_addr: int | None = None,
|
|
32
|
+
arg_vvars: list[VirtualVariable] | None = None,
|
|
32
33
|
):
|
|
33
34
|
self.func = func
|
|
34
35
|
self.func_addr = func_addr if func_addr is not None else func.addr
|
|
@@ -38,6 +39,7 @@ class SLivenessAnalysis(Analysis):
|
|
|
38
39
|
if entry is not None
|
|
39
40
|
else next(iter(bb for bb in self.func_graph if bb.addr == self.func_addr and bb.idx is None))
|
|
40
41
|
)
|
|
42
|
+
self.arg_vvars = arg_vvars or []
|
|
41
43
|
|
|
42
44
|
self.model = SLivenessModel()
|
|
43
45
|
|
|
@@ -147,6 +149,12 @@ class SLivenessAnalysis(Analysis):
|
|
|
147
149
|
live.discard(def_vvar)
|
|
148
150
|
live |= vvar_use_collector.vvars
|
|
149
151
|
|
|
152
|
+
if block.addr == self.func_addr:
|
|
153
|
+
# deal with function arguments
|
|
154
|
+
for arg_vvar in self.arg_vvars:
|
|
155
|
+
for live_vvar in live:
|
|
156
|
+
graph.add_edge(arg_vvar.varid, live_vvar)
|
|
157
|
+
|
|
150
158
|
return graph
|
|
151
159
|
|
|
152
160
|
|
angr/analyses/s_propagator.py
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import contextlib
|
|
4
|
+
from collections.abc import Mapping
|
|
4
5
|
from collections import defaultdict
|
|
5
6
|
|
|
6
7
|
from ailment.block import Block
|
|
7
|
-
from ailment.expression import
|
|
8
|
+
from ailment.expression import (
|
|
9
|
+
Const,
|
|
10
|
+
VirtualVariable,
|
|
11
|
+
VirtualVariableCategory,
|
|
12
|
+
StackBaseOffset,
|
|
13
|
+
Load,
|
|
14
|
+
Convert,
|
|
15
|
+
Expression,
|
|
16
|
+
)
|
|
8
17
|
from ailment.statement import Assignment, Store, Return, Jump
|
|
9
18
|
|
|
10
19
|
from angr.knowledge_plugins.functions import Function
|
|
@@ -31,7 +40,7 @@ class SPropagatorModel:
|
|
|
31
40
|
"""
|
|
32
41
|
|
|
33
42
|
def __init__(self):
|
|
34
|
-
self.replacements = {}
|
|
43
|
+
self.replacements: Mapping[CodeLocation, Mapping[Expression, Expression]] = {}
|
|
35
44
|
|
|
36
45
|
|
|
37
46
|
class SPropagatorAnalysis(Analysis):
|
|
@@ -41,7 +50,7 @@ class SPropagatorAnalysis(Analysis):
|
|
|
41
50
|
|
|
42
51
|
def __init__( # pylint: disable=too-many-positional-arguments
|
|
43
52
|
self,
|
|
44
|
-
subject,
|
|
53
|
+
subject: Block | Function,
|
|
45
54
|
func_graph=None,
|
|
46
55
|
only_consts: bool = True,
|
|
47
56
|
immediate_stmt_removal: bool = False,
|
|
@@ -86,10 +95,13 @@ class SPropagatorAnalysis(Analysis):
|
|
|
86
95
|
return self.model.replacements
|
|
87
96
|
|
|
88
97
|
def _analyze(self):
|
|
98
|
+
blocks: dict[tuple[int, int | None], Block]
|
|
89
99
|
match self.mode:
|
|
90
100
|
case "block":
|
|
101
|
+
assert self.block is not None
|
|
91
102
|
blocks = {(self.block.addr, self.block.idx): self.block}
|
|
92
103
|
case "function":
|
|
104
|
+
assert self.func_graph is not None
|
|
93
105
|
blocks = {(block.addr, block.idx): block for block in self.func_graph}
|
|
94
106
|
case _:
|
|
95
107
|
raise NotImplementedError
|
|
@@ -120,11 +132,14 @@ class SPropagatorAnalysis(Analysis):
|
|
|
120
132
|
|
|
121
133
|
vvarid_to_vvar[vvar.varid] = vvar
|
|
122
134
|
defloc = vvar_deflocs[vvar]
|
|
135
|
+
assert defloc.block_addr is not None
|
|
136
|
+
assert defloc.stmt_idx is not None
|
|
123
137
|
block = blocks[(defloc.block_addr, defloc.block_idx)]
|
|
124
138
|
stmt = block.statements[defloc.stmt_idx]
|
|
125
139
|
r, v = is_const_assignment(stmt)
|
|
126
140
|
if r:
|
|
127
141
|
# replace wherever it's used
|
|
142
|
+
assert v is not None
|
|
128
143
|
const_vvars[vvar.varid] = v
|
|
129
144
|
for vvar_at_use, useloc in vvar_uselocs[vvar.varid]:
|
|
130
145
|
replacements[useloc][vvar_at_use] = v
|
|
@@ -171,11 +171,8 @@ class SRDAView:
|
|
|
171
171
|
starting_stmt_idx = stmt_idx
|
|
172
172
|
continue
|
|
173
173
|
|
|
174
|
-
if (
|
|
175
|
-
op_type == ObservationPointType.
|
|
176
|
-
and stmt.ins_addr == addr
|
|
177
|
-
or op_type == ObservationPointType.OP_AFTER
|
|
178
|
-
and stmt.ins_addr > addr
|
|
174
|
+
if (op_type == ObservationPointType.OP_BEFORE and stmt.ins_addr == addr) or (
|
|
175
|
+
op_type == ObservationPointType.OP_AFTER and stmt.ins_addr > addr
|
|
179
176
|
):
|
|
180
177
|
starting_stmt_idx = stmt_idx
|
|
181
178
|
break
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from ailment.block import Block
|
|
4
4
|
from ailment.statement import Assignment, Call, Return
|
|
5
|
+
import networkx
|
|
5
6
|
|
|
6
7
|
from angr.knowledge_plugins.functions import Function
|
|
7
8
|
from angr.knowledge_plugins.key_definitions.constants import ObservationPointType
|
|
@@ -22,9 +23,8 @@ class SReachingDefinitionsAnalysis(Analysis):
|
|
|
22
23
|
self,
|
|
23
24
|
subject,
|
|
24
25
|
func_addr: int | None = None,
|
|
25
|
-
func_graph=None,
|
|
26
|
+
func_graph: networkx.DiGraph[Block] | None = None,
|
|
26
27
|
track_tmps: bool = False,
|
|
27
|
-
stack_pointer_tracker=None,
|
|
28
28
|
):
|
|
29
29
|
if isinstance(subject, Block):
|
|
30
30
|
self.block = subject
|
|
@@ -40,7 +40,6 @@ class SReachingDefinitionsAnalysis(Analysis):
|
|
|
40
40
|
self.func_graph = func_graph
|
|
41
41
|
self.func_addr = func_addr if func_addr is not None else self.func.addr if self.func is not None else None
|
|
42
42
|
self._track_tmps = track_tmps
|
|
43
|
-
self._sp_tracker = stack_pointer_tracker # FIXME: Is it still used?
|
|
44
43
|
|
|
45
44
|
self._bp_as_gpr = False
|
|
46
45
|
if self.func is not None:
|
|
@@ -53,8 +52,10 @@ class SReachingDefinitionsAnalysis(Analysis):
|
|
|
53
52
|
def _analyze(self):
|
|
54
53
|
match self.mode:
|
|
55
54
|
case "block":
|
|
55
|
+
assert self.block is not None
|
|
56
56
|
blocks = {(self.block.addr, self.block.idx): self.block}
|
|
57
57
|
case "function":
|
|
58
|
+
assert self.func_graph is not None
|
|
58
59
|
blocks = {(block.addr, block.idx): block for block in self.func_graph}
|
|
59
60
|
case _:
|
|
60
61
|
raise NotImplementedError
|
|
@@ -115,9 +116,10 @@ class SReachingDefinitionsAnalysis(Analysis):
|
|
|
115
116
|
stmt = block.statements[stmt_idx]
|
|
116
117
|
assert isinstance(stmt, (Call, Assignment, Return))
|
|
117
118
|
|
|
118
|
-
call
|
|
119
|
+
call = (
|
|
119
120
|
stmt if isinstance(stmt, Call) else stmt.src if isinstance(stmt, Assignment) else stmt.ret_exprs[0]
|
|
120
121
|
)
|
|
122
|
+
assert isinstance(call, Call)
|
|
121
123
|
if call.prototype is None:
|
|
122
124
|
# without knowing the prototype, we must conservatively add uses to all registers that are
|
|
123
125
|
# potentially used here
|
|
@@ -126,7 +128,9 @@ class SReachingDefinitionsAnalysis(Analysis):
|
|
|
126
128
|
else:
|
|
127
129
|
# just use all registers in the default calling convention because we don't know anything about
|
|
128
130
|
# the calling convention yet
|
|
129
|
-
|
|
131
|
+
cc_cls = default_cc(self.project.arch.name)
|
|
132
|
+
assert cc_cls is not None
|
|
133
|
+
cc = cc_cls(self.project.arch)
|
|
130
134
|
|
|
131
135
|
codeloc = CodeLocation(block_addr, stmt_idx, block_idx=block_idx, ins_addr=stmt.ins_addr)
|
|
132
136
|
arg_locs = cc.ARG_REGS
|
|
@@ -79,7 +79,7 @@ class Register:
|
|
|
79
79
|
Represent a register.
|
|
80
80
|
"""
|
|
81
81
|
|
|
82
|
-
__slots__ = ("
|
|
82
|
+
__slots__ = ("bitlen", "offset")
|
|
83
83
|
|
|
84
84
|
def __init__(self, offset, bitlen):
|
|
85
85
|
self.offset = offset
|
|
@@ -103,8 +103,8 @@ class OffsetVal:
|
|
|
103
103
|
"""
|
|
104
104
|
|
|
105
105
|
__slots__ = (
|
|
106
|
-
"_reg",
|
|
107
106
|
"_offset",
|
|
107
|
+
"_reg",
|
|
108
108
|
)
|
|
109
109
|
|
|
110
110
|
def __init__(self, reg, offset):
|
|
@@ -177,7 +177,7 @@ class FrozenStackPointerTrackerState:
|
|
|
177
177
|
Abstract state for StackPointerTracker analysis with registers and memory values being in frozensets.
|
|
178
178
|
"""
|
|
179
179
|
|
|
180
|
-
__slots__ = "
|
|
180
|
+
__slots__ = "is_tracking_memory", "memory", "regs", "resilient"
|
|
181
181
|
|
|
182
182
|
def __init__(
|
|
183
183
|
self,
|
|
@@ -218,7 +218,7 @@ class StackPointerTrackerState:
|
|
|
218
218
|
Abstract state for StackPointerTracker analysis.
|
|
219
219
|
"""
|
|
220
220
|
|
|
221
|
-
__slots__ = "
|
|
221
|
+
__slots__ = "is_tracking_memory", "memory", "regs", "resilient"
|
|
222
222
|
|
|
223
223
|
def __init__(self, regs, memory, is_tracking_memory, resilient: bool):
|
|
224
224
|
self.regs = regs
|