angr 9.2.135__py3-none-manylinux2014_aarch64.whl → 9.2.137__py3-none-manylinux2014_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of angr might be problematic. Click here for more details.
- angr/__init__.py +1 -1
- angr/analyses/__init__.py +3 -7
- angr/analyses/analysis.py +4 -0
- angr/analyses/backward_slice.py +1 -2
- angr/analyses/binary_optimizer.py +3 -4
- angr/analyses/bindiff.py +4 -6
- angr/analyses/boyscout.py +1 -3
- angr/analyses/callee_cleanup_finder.py +4 -4
- angr/analyses/calling_convention/calling_convention.py +6 -4
- angr/analyses/calling_convention/fact_collector.py +10 -3
- angr/analyses/cdg.py +1 -2
- angr/analyses/cfg/cfb.py +1 -3
- angr/analyses/cfg/cfg.py +2 -2
- angr/analyses/cfg/cfg_base.py +40 -68
- angr/analyses/cfg/cfg_emulated.py +1 -104
- angr/analyses/cfg/cfg_fast.py +90 -27
- angr/analyses/cfg/cfg_fast_soot.py +1 -1
- angr/analyses/cfg/indirect_jump_resolvers/__init__.py +2 -0
- angr/analyses/cfg/indirect_jump_resolvers/const_resolver.py +46 -10
- angr/analyses/cfg/indirect_jump_resolvers/default_resolvers.py +5 -1
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +65 -14
- angr/analyses/cfg/indirect_jump_resolvers/memload_resolver.py +81 -0
- angr/analyses/cfg/indirect_jump_resolvers/propagator_utils.py +24 -5
- angr/analyses/cfg/indirect_jump_resolvers/x86_pe_iat.py +2 -5
- angr/analyses/class_identifier.py +1 -2
- angr/analyses/complete_calling_conventions.py +3 -0
- angr/analyses/congruency_check.py +2 -3
- angr/analyses/data_dep/data_dependency_analysis.py +2 -2
- angr/analyses/ddg.py +1 -4
- angr/analyses/decompiler/ail_simplifier.py +15 -5
- angr/analyses/decompiler/block_simplifier.py +2 -2
- angr/analyses/decompiler/ccall_rewriters/__init__.py +2 -0
- angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +1 -1
- angr/analyses/decompiler/ccall_rewriters/x86_ccalls.py +69 -0
- angr/analyses/decompiler/clinic.py +119 -72
- angr/analyses/decompiler/condition_processor.py +2 -0
- angr/analyses/decompiler/decompiler.py +1 -0
- angr/analyses/decompiler/dephication/dephication_base.py +2 -0
- angr/analyses/decompiler/dephication/rewriting_engine.py +8 -6
- angr/analyses/decompiler/dephication/seqnode_dephication.py +10 -1
- angr/analyses/decompiler/optimization_passes/duplication_reverter/ail_merge_graph.py +2 -2
- angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +2 -2
- angr/analyses/decompiler/optimization_passes/ite_region_converter.py +1 -1
- angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +1 -1
- angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +1 -2
- angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +1 -1
- angr/analyses/decompiler/sequence_walker.py +6 -2
- angr/analyses/decompiler/ssailification/rewriting.py +11 -1
- angr/analyses/decompiler/ssailification/rewriting_engine.py +56 -19
- angr/analyses/decompiler/ssailification/ssailification.py +13 -3
- angr/analyses/decompiler/ssailification/traversal.py +28 -2
- angr/analyses/decompiler/ssailification/traversal_state.py +6 -1
- angr/analyses/decompiler/structured_codegen/c.py +44 -21
- angr/analyses/decompiler/structuring/phoenix.py +118 -15
- angr/analyses/decompiler/utils.py +113 -8
- angr/analyses/disassembly.py +5 -5
- angr/analyses/fcp/__init__.py +4 -0
- angr/analyses/fcp/fcp.py +429 -0
- angr/analyses/identifier/identify.py +1 -3
- angr/analyses/loopfinder.py +4 -3
- angr/analyses/patchfinder.py +1 -1
- angr/analyses/propagator/engine_base.py +4 -3
- angr/analyses/propagator/propagator.py +14 -53
- angr/analyses/reaching_definitions/function_handler.py +1 -1
- angr/analyses/reassembler.py +1 -2
- angr/analyses/s_liveness.py +5 -1
- angr/analyses/s_propagator.py +26 -7
- angr/analyses/s_reaching_definitions/s_rda_model.py +2 -1
- angr/analyses/s_reaching_definitions/s_rda_view.py +20 -1
- angr/analyses/s_reaching_definitions/s_reaching_definitions.py +11 -1
- angr/analyses/soot_class_hierarchy.py +1 -2
- angr/analyses/stack_pointer_tracker.py +29 -3
- angr/analyses/static_hooker.py +1 -2
- angr/analyses/typehoon/simple_solver.py +2 -2
- angr/analyses/variable_recovery/engine_ail.py +19 -7
- angr/analyses/variable_recovery/engine_base.py +16 -14
- angr/analyses/variable_recovery/engine_vex.py +2 -2
- angr/analyses/variable_recovery/variable_recovery_fast.py +23 -3
- angr/analyses/veritesting.py +4 -7
- angr/analyses/vfg.py +1 -1
- angr/analyses/vsa_ddg.py +1 -2
- angr/block.py +62 -22
- angr/callable.py +1 -3
- angr/calling_conventions.py +3 -3
- angr/codenode.py +5 -1
- angr/concretization_strategies/__init__.py +1 -83
- angr/concretization_strategies/any.py +2 -1
- angr/concretization_strategies/any_named.py +1 -1
- angr/concretization_strategies/base.py +81 -0
- angr/concretization_strategies/controlled_data.py +2 -1
- angr/concretization_strategies/eval.py +2 -1
- angr/concretization_strategies/logging.py +3 -1
- angr/concretization_strategies/max.py +2 -1
- angr/concretization_strategies/nonzero.py +2 -1
- angr/concretization_strategies/nonzero_range.py +2 -1
- angr/concretization_strategies/norepeats.py +2 -1
- angr/concretization_strategies/norepeats_range.py +2 -1
- angr/concretization_strategies/range.py +2 -1
- angr/concretization_strategies/signed_add.py +2 -1
- angr/concretization_strategies/single.py +2 -1
- angr/concretization_strategies/solutions.py +2 -1
- angr/concretization_strategies/unlimited_range.py +2 -1
- angr/engines/__init__.py +8 -5
- angr/engines/engine.py +3 -5
- angr/engines/failure.py +4 -5
- angr/engines/pcode/emulate.py +1 -1
- angr/engines/pcode/lifter.py +31 -18
- angr/engines/procedure.py +5 -7
- angr/engines/soot/expressions/__init__.py +20 -23
- angr/engines/soot/expressions/base.py +4 -4
- angr/engines/soot/expressions/invoke.py +1 -2
- angr/engines/soot/statements/__init__.py +10 -12
- angr/engines/soot/values/__init__.py +10 -12
- angr/engines/soot/values/arrayref.py +3 -3
- angr/engines/soot/values/instancefieldref.py +3 -2
- angr/engines/successors.py +18 -12
- angr/engines/syscall.py +4 -6
- angr/engines/unicorn.py +3 -2
- angr/engines/vex/claripy/ccall.py +8 -10
- angr/engines/vex/claripy/datalayer.py +4 -5
- angr/engines/vex/lifter.py +9 -6
- angr/exploration_techniques/__init__.py +0 -2
- angr/exploration_techniques/spiller.py +1 -3
- angr/exploration_techniques/stochastic.py +2 -3
- angr/factory.py +3 -9
- angr/flirt/build_sig.py +8 -15
- angr/knowledge_plugins/cfg/cfg_model.py +20 -17
- angr/knowledge_plugins/functions/function.py +70 -79
- angr/knowledge_plugins/functions/function_manager.py +8 -7
- angr/knowledge_plugins/functions/function_parser.py +1 -1
- angr/knowledge_plugins/functions/soot_function.py +21 -24
- angr/knowledge_plugins/propagations/propagation_model.py +4 -5
- angr/knowledge_plugins/propagations/states.py +0 -511
- angr/knowledge_plugins/variables/variable_manager.py +16 -10
- angr/procedures/libc/memcpy.py +4 -4
- angr/procedures/procedure_dict.py +3 -2
- angr/protos/__init__.py +2 -5
- angr/protos/cfg_pb2.py +21 -18
- angr/protos/function_pb2.py +17 -14
- angr/protos/primitives_pb2.py +44 -39
- angr/protos/variables_pb2.py +36 -31
- angr/protos/xrefs_pb2.py +15 -12
- angr/sim_procedure.py +15 -16
- angr/sim_variable.py +13 -1
- angr/simos/__init__.py +2 -0
- angr/simos/javavm.py +4 -6
- angr/simos/xbox.py +32 -0
- angr/state_plugins/__init__.py +0 -2
- angr/state_plugins/callstack.py +4 -4
- angr/state_plugins/cgc.py +3 -2
- angr/state_plugins/gdb.py +6 -5
- angr/state_plugins/globals.py +1 -2
- angr/state_plugins/heap/heap_brk.py +1 -2
- angr/state_plugins/history.py +10 -12
- angr/state_plugins/inspect.py +3 -5
- angr/state_plugins/libc.py +2 -2
- angr/state_plugins/log.py +8 -10
- angr/state_plugins/loop_data.py +1 -2
- angr/state_plugins/posix.py +7 -7
- angr/state_plugins/preconstrainer.py +2 -3
- angr/state_plugins/scratch.py +5 -8
- angr/state_plugins/sim_action.py +3 -3
- angr/state_plugins/solver.py +8 -3
- angr/state_plugins/symbolizer.py +5 -4
- angr/state_plugins/uc_manager.py +3 -3
- angr/state_plugins/unicorn_engine.py +5 -1
- angr/state_plugins/view.py +3 -5
- angr/storage/file.py +3 -5
- angr/storage/memory_mixins/address_concretization_mixin.py +2 -2
- angr/storage/memory_mixins/bvv_conversion_mixin.py +3 -3
- angr/storage/memory_mixins/clouseau_mixin.py +1 -3
- angr/storage/memory_mixins/name_resolution_mixin.py +1 -3
- angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +13 -15
- angr/storage/memory_mixins/paged_memory/pages/__init__.py +1 -22
- angr/storage/memory_mixins/paged_memory/pages/base.py +31 -0
- angr/storage/memory_mixins/paged_memory/pages/list_page.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/paged_memory/privileged_mixin.py +3 -4
- angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +4 -2
- angr/storage/memory_mixins/smart_find_mixin.py +1 -1
- angr/storage/memory_mixins/underconstrained_mixin.py +1 -1
- angr/storage/memory_mixins/unwrapper_mixin.py +1 -3
- angr/utils/enums_conv.py +28 -12
- angr/utils/segment_list.py +25 -22
- angr/utils/timing.py +18 -1
- angr/vaults.py +5 -6
- {angr-9.2.135.dist-info → angr-9.2.137.dist-info}/METADATA +7 -7
- {angr-9.2.135.dist-info → angr-9.2.137.dist-info}/RECORD +193 -191
- {angr-9.2.135.dist-info → angr-9.2.137.dist-info}/WHEEL +1 -1
- angr/analyses/propagator/outdated_definition_walker.py +0 -159
- angr/analyses/propagator/tmpvar_finder.py +0 -18
- angr/engines/concrete.py +0 -180
- angr/exploration_techniques/symbion.py +0 -80
- angr/state_plugins/concrete.py +0 -295
- {angr-9.2.135.dist-info → angr-9.2.137.dist-info}/LICENSE +0 -0
- {angr-9.2.135.dist-info → angr-9.2.137.dist-info}/entry_points.txt +0 -0
- {angr-9.2.135.dist-info → angr-9.2.137.dist-info}/top_level.txt +0 -0
angr/analyses/reassembler.py
CHANGED
|
@@ -12,6 +12,7 @@ import cle
|
|
|
12
12
|
import networkx
|
|
13
13
|
import pyvex
|
|
14
14
|
|
|
15
|
+
from angr.analyses import AnalysesHub
|
|
15
16
|
from . import Analysis
|
|
16
17
|
from .cfg.cfg_emulated import CFGEmulated
|
|
17
18
|
from .ddg import DDG
|
|
@@ -2896,6 +2897,4 @@ class Reassembler(Analysis):
|
|
|
2896
2897
|
return None
|
|
2897
2898
|
|
|
2898
2899
|
|
|
2899
|
-
from angr.analyses import AnalysesHub
|
|
2900
|
-
|
|
2901
2900
|
AnalysesHub.register_default("Reassembler", Reassembler)
|
angr/analyses/s_liveness.py
CHANGED
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import networkx
|
|
4
4
|
from ailment.expression import VirtualVariable
|
|
5
|
-
from ailment.statement import Assignment
|
|
5
|
+
from ailment.statement import Assignment, Call
|
|
6
6
|
|
|
7
7
|
from angr.analyses import Analysis, register_analysis
|
|
8
8
|
from angr.utils.ssa import VVarUsesCollector, phi_assignment_get_src
|
|
@@ -86,6 +86,8 @@ class SLivenessAnalysis(Analysis):
|
|
|
86
86
|
# handle assignments: a defined vvar is not live before the assignment
|
|
87
87
|
if isinstance(stmt, Assignment) and isinstance(stmt.dst, VirtualVariable):
|
|
88
88
|
live.discard(stmt.dst.varid)
|
|
89
|
+
elif isinstance(stmt, Call) and isinstance(stmt.ret_expr, VirtualVariable):
|
|
90
|
+
live.discard(stmt.ret_expr.varid)
|
|
89
91
|
|
|
90
92
|
phi_expr = phi_assignment_get_src(stmt)
|
|
91
93
|
if phi_expr is not None:
|
|
@@ -136,6 +138,8 @@ class SLivenessAnalysis(Analysis):
|
|
|
136
138
|
for stmt in reversed(block.statements):
|
|
137
139
|
if isinstance(stmt, Assignment) and isinstance(stmt.dst, VirtualVariable):
|
|
138
140
|
def_vvar = stmt.dst.varid
|
|
141
|
+
elif isinstance(stmt, Call) and isinstance(stmt.ret_expr, VirtualVariable):
|
|
142
|
+
def_vvar = stmt.ret_expr.varid
|
|
139
143
|
else:
|
|
140
144
|
def_vvar = None
|
|
141
145
|
|
angr/analyses/s_propagator.py
CHANGED
|
@@ -17,7 +17,7 @@ from ailment.expression import (
|
|
|
17
17
|
from ailment.statement import Assignment, Store, Return, Jump
|
|
18
18
|
|
|
19
19
|
from angr.knowledge_plugins.functions import Function
|
|
20
|
-
from angr.code_location import CodeLocation
|
|
20
|
+
from angr.code_location import CodeLocation, ExternalCodeLocation
|
|
21
21
|
from angr.analyses import Analysis, register_analysis
|
|
22
22
|
from angr.utils.ssa import (
|
|
23
23
|
get_vvar_uselocs,
|
|
@@ -53,8 +53,8 @@ class SPropagatorAnalysis(Analysis):
|
|
|
53
53
|
subject: Block | Function,
|
|
54
54
|
func_graph=None,
|
|
55
55
|
only_consts: bool = True,
|
|
56
|
-
immediate_stmt_removal: bool = False,
|
|
57
56
|
stack_pointer_tracker=None,
|
|
57
|
+
func_args: set[VirtualVariable] | None = None,
|
|
58
58
|
func_addr: int | None = None,
|
|
59
59
|
):
|
|
60
60
|
if isinstance(subject, Block):
|
|
@@ -70,8 +70,8 @@ class SPropagatorAnalysis(Analysis):
|
|
|
70
70
|
|
|
71
71
|
self.func_graph = func_graph
|
|
72
72
|
self.func_addr = func_addr
|
|
73
|
+
self.func_args = func_args
|
|
73
74
|
self.only_consts = only_consts
|
|
74
|
-
self.immediate_stmt_removal = immediate_stmt_removal
|
|
75
75
|
self._sp_tracker = stack_pointer_tracker
|
|
76
76
|
|
|
77
77
|
bp_as_gpr = False
|
|
@@ -111,6 +111,11 @@ class SPropagatorAnalysis(Analysis):
|
|
|
111
111
|
# find all vvar uses
|
|
112
112
|
vvar_uselocs = get_vvar_uselocs(blocks.values())
|
|
113
113
|
|
|
114
|
+
# update vvar_deflocs using function arguments
|
|
115
|
+
if self.func_args:
|
|
116
|
+
for func_arg in self.func_args:
|
|
117
|
+
vvar_deflocs[func_arg] = ExternalCodeLocation()
|
|
118
|
+
|
|
114
119
|
# find all ret sites and indirect jump sites
|
|
115
120
|
retsites: set[tuple[int, int | None, int]] = set()
|
|
116
121
|
jumpsites: set[tuple[int, int | None, int]] = set()
|
|
@@ -132,8 +137,9 @@ class SPropagatorAnalysis(Analysis):
|
|
|
132
137
|
|
|
133
138
|
vvarid_to_vvar[vvar.varid] = vvar
|
|
134
139
|
defloc = vvar_deflocs[vvar]
|
|
135
|
-
|
|
136
|
-
|
|
140
|
+
if isinstance(defloc, ExternalCodeLocation):
|
|
141
|
+
continue
|
|
142
|
+
|
|
137
143
|
block = blocks[(defloc.block_addr, defloc.block_idx)]
|
|
138
144
|
stmt = block.statements[defloc.stmt_idx]
|
|
139
145
|
r, v = is_const_assignment(stmt)
|
|
@@ -181,7 +187,20 @@ class SPropagatorAnalysis(Analysis):
|
|
|
181
187
|
continue
|
|
182
188
|
|
|
183
189
|
if is_const_and_vvar_assignment(stmt):
|
|
184
|
-
|
|
190
|
+
# if the useloc is a phi assignment statement, ensure that stmt.src is the same as the phi
|
|
191
|
+
# variable
|
|
192
|
+
useloc_stmt = blocks[(vvar_useloc.block_addr, vvar_useloc.block_idx)].statements[
|
|
193
|
+
vvar_useloc.stmt_idx
|
|
194
|
+
]
|
|
195
|
+
if is_phi_assignment(useloc_stmt):
|
|
196
|
+
if (
|
|
197
|
+
isinstance(stmt.src, VirtualVariable)
|
|
198
|
+
and stmt.src.oident == useloc_stmt.dst.oident
|
|
199
|
+
and stmt.src.category == useloc_stmt.dst.category
|
|
200
|
+
):
|
|
201
|
+
replacements[vvar_useloc][vvar_used] = stmt.src
|
|
202
|
+
else:
|
|
203
|
+
replacements[vvar_useloc][vvar_used] = stmt.src
|
|
185
204
|
continue
|
|
186
205
|
|
|
187
206
|
elif (
|
|
@@ -209,7 +228,7 @@ class SPropagatorAnalysis(Analysis):
|
|
|
209
228
|
stmt_src = stmt_src.operand
|
|
210
229
|
if isinstance(stmt_src, Load) and isinstance(stmt_src.addr, Const):
|
|
211
230
|
gv_updated = False
|
|
212
|
-
for
|
|
231
|
+
for _vvar_used, vvar_useloc in vvar_uselocs[vvar.varid]:
|
|
213
232
|
gv_updated |= self.is_global_variable_updated(
|
|
214
233
|
self.func_graph,
|
|
215
234
|
blocks,
|
|
@@ -15,8 +15,9 @@ class SRDAModel:
|
|
|
15
15
|
The model for SRDA.
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
-
def __init__(self, func_graph, arch):
|
|
18
|
+
def __init__(self, func_graph, func_args, arch):
|
|
19
19
|
self.func_graph = func_graph
|
|
20
|
+
self.func_args = func_args
|
|
20
21
|
self.arch = arch
|
|
21
22
|
self.varid_to_vvar: dict[int, VirtualVariable] = {}
|
|
22
23
|
self.all_vvar_definitions: dict[VirtualVariable, CodeLocation] = {}
|
|
@@ -4,7 +4,7 @@ import logging
|
|
|
4
4
|
from collections import defaultdict
|
|
5
5
|
|
|
6
6
|
from ailment.statement import Statement, Assignment, Call, Label
|
|
7
|
-
from ailment.expression import VirtualVariable, Expression
|
|
7
|
+
from ailment.expression import VirtualVariable, VirtualVariableCategory, Expression
|
|
8
8
|
|
|
9
9
|
from angr.utils.ail import is_phi_assignment
|
|
10
10
|
from angr.utils.graph import GraphUtils
|
|
@@ -133,6 +133,16 @@ class SRDAView:
|
|
|
133
133
|
predicater = RegVVarPredicate(reg_offset, vvars, self.model.arch)
|
|
134
134
|
self._get_vvar_by_stmt(block_addr, block_idx, stmt_idx, op_type, predicater.predicate)
|
|
135
135
|
|
|
136
|
+
if not vvars:
|
|
137
|
+
# not found - check function arguments
|
|
138
|
+
for func_arg in self.model.func_args:
|
|
139
|
+
if isinstance(func_arg, VirtualVariable):
|
|
140
|
+
func_arg_category = func_arg.oident[0]
|
|
141
|
+
if func_arg_category == VirtualVariableCategory.REGISTER:
|
|
142
|
+
func_arg_regoff = func_arg.oident[1]
|
|
143
|
+
if func_arg_regoff == reg_offset:
|
|
144
|
+
vvars.add(func_arg)
|
|
145
|
+
|
|
136
146
|
assert len(vvars) <= 1
|
|
137
147
|
return next(iter(vvars), None)
|
|
138
148
|
|
|
@@ -149,6 +159,15 @@ class SRDAView:
|
|
|
149
159
|
predicater = StackVVarPredicate(stack_offset, size, vvars)
|
|
150
160
|
self._get_vvar_by_stmt(block_addr, block_idx, stmt_idx, op_type, predicater.predicate)
|
|
151
161
|
|
|
162
|
+
if not vvars:
|
|
163
|
+
# not found - check function arguments
|
|
164
|
+
for func_arg in self.model.func_args:
|
|
165
|
+
if isinstance(func_arg, VirtualVariable):
|
|
166
|
+
func_arg_category = func_arg.oident[0]
|
|
167
|
+
if func_arg_category == VirtualVariableCategory.STACK:
|
|
168
|
+
func_arg_stackoff = func_arg.oident[1]
|
|
169
|
+
if func_arg_stackoff == stack_offset and func_arg.size == size:
|
|
170
|
+
vvars.add(func_arg)
|
|
152
171
|
assert len(vvars) <= 1
|
|
153
172
|
return next(iter(vvars), None)
|
|
154
173
|
|
|
@@ -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
|
+
from ailment.expression import VirtualVariable
|
|
5
6
|
import networkx
|
|
6
7
|
|
|
7
8
|
from angr.knowledge_plugins.functions import Function
|
|
@@ -24,6 +25,7 @@ class SReachingDefinitionsAnalysis(Analysis):
|
|
|
24
25
|
subject,
|
|
25
26
|
func_addr: int | None = None,
|
|
26
27
|
func_graph: networkx.DiGraph[Block] | None = None,
|
|
28
|
+
func_args: set[VirtualVariable] | None = None,
|
|
27
29
|
track_tmps: bool = False,
|
|
28
30
|
):
|
|
29
31
|
if isinstance(subject, Block):
|
|
@@ -39,13 +41,14 @@ class SReachingDefinitionsAnalysis(Analysis):
|
|
|
39
41
|
|
|
40
42
|
self.func_graph = func_graph
|
|
41
43
|
self.func_addr = func_addr if func_addr is not None else self.func.addr if self.func is not None else None
|
|
44
|
+
self.func_args = func_args
|
|
42
45
|
self._track_tmps = track_tmps
|
|
43
46
|
|
|
44
47
|
self._bp_as_gpr = False
|
|
45
48
|
if self.func is not None:
|
|
46
49
|
self._bp_as_gpr = self.func.info.get("bp_as_gpr", False)
|
|
47
50
|
|
|
48
|
-
self.model = SRDAModel(func_graph, self.project.arch)
|
|
51
|
+
self.model = SRDAModel(func_graph, func_args, self.project.arch)
|
|
49
52
|
|
|
50
53
|
self._analyze()
|
|
51
54
|
|
|
@@ -66,6 +69,13 @@ class SReachingDefinitionsAnalysis(Analysis):
|
|
|
66
69
|
# find all explicit vvar uses
|
|
67
70
|
vvar_uselocs = get_vvar_uselocs(blocks.values())
|
|
68
71
|
|
|
72
|
+
# update vvar definitions using function arguments
|
|
73
|
+
if self.func_args:
|
|
74
|
+
for vvar in self.func_args:
|
|
75
|
+
if vvar not in vvar_deflocs:
|
|
76
|
+
vvar_deflocs[vvar] = ExternalCodeLocation()
|
|
77
|
+
self.model.func_args = self.func_args
|
|
78
|
+
|
|
69
79
|
# update model
|
|
70
80
|
for vvar, defloc in vvar_deflocs.items():
|
|
71
81
|
self.model.varid_to_vvar[vvar.varid] = vvar
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
import logging
|
|
3
3
|
|
|
4
|
+
from angr.analyses import AnalysesHub
|
|
4
5
|
from . import Analysis
|
|
5
6
|
|
|
6
7
|
l = logging.getLogger(name=__name__)
|
|
@@ -269,6 +270,4 @@ class SootClassHierarchy(Analysis):
|
|
|
269
270
|
return targets
|
|
270
271
|
|
|
271
272
|
|
|
272
|
-
from angr.analyses import AnalysesHub
|
|
273
|
-
|
|
274
273
|
AnalysesHub.register_default("SootClassHierarchy", SootClassHierarchy)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
4
|
from typing import Any, TYPE_CHECKING
|
|
5
|
+
import contextlib
|
|
5
6
|
import re
|
|
6
7
|
import logging
|
|
7
8
|
from collections import defaultdict
|
|
@@ -15,7 +16,6 @@ from angr.knowledge_plugins import Function
|
|
|
15
16
|
from angr.block import BlockNode
|
|
16
17
|
from angr.errors import SimTranslationError
|
|
17
18
|
from .analysis import Analysis
|
|
18
|
-
import contextlib
|
|
19
19
|
|
|
20
20
|
try:
|
|
21
21
|
import pypcode
|
|
@@ -258,11 +258,11 @@ class StackPointerTrackerState:
|
|
|
258
258
|
pass
|
|
259
259
|
raise CouldNotResolveException
|
|
260
260
|
|
|
261
|
-
def put(self, reg, val):
|
|
261
|
+
def put(self, reg, val, force: bool = False):
|
|
262
262
|
# strong update, but we only update values for registers that are already in self.regs and ignore all other
|
|
263
263
|
# registers. obviously, self.regs should be initialized with registers that should be considered during
|
|
264
264
|
# tracking,
|
|
265
|
-
if reg in self.regs:
|
|
265
|
+
if reg in self.regs or force:
|
|
266
266
|
self.regs[reg] = val
|
|
267
267
|
|
|
268
268
|
def copy(self):
|
|
@@ -702,6 +702,32 @@ class StackPointerTracker(Analysis, ForwardAnalysis):
|
|
|
702
702
|
# who are we calling?
|
|
703
703
|
callees = [] if self._func is None else self._find_callees(node)
|
|
704
704
|
if callees:
|
|
705
|
+
if len(callees) == 1:
|
|
706
|
+
callee = callees[0]
|
|
707
|
+
|
|
708
|
+
if callee.info.get("is_rust_probestack", False) is True and self.project.arch.name == "AMD64":
|
|
709
|
+
# special-case for rust_probestack: sp = sp - rax right after returning from the call, so we
|
|
710
|
+
# need to keep track of rax
|
|
711
|
+
for stmt in reversed(vex_block.statements):
|
|
712
|
+
if (
|
|
713
|
+
isinstance(stmt, pyvex.IRStmt.Put)
|
|
714
|
+
and stmt.offset == self.project.arch.registers["rax"][0]
|
|
715
|
+
and isinstance(stmt.data, pyvex.IRExpr.Const)
|
|
716
|
+
):
|
|
717
|
+
state.put(stmt.offset, Constant(stmt.data.con.value), force=True)
|
|
718
|
+
break
|
|
719
|
+
elif callee.name == "__chkstk":
|
|
720
|
+
# special-case for __chkstk: sp = sp - rax right after returning from the call, so we need to
|
|
721
|
+
# keep track of rax
|
|
722
|
+
for stmt in reversed(vex_block.statements):
|
|
723
|
+
if (
|
|
724
|
+
isinstance(stmt, pyvex.IRStmt.Put)
|
|
725
|
+
and stmt.offset == self.project.arch.registers["rax"][0]
|
|
726
|
+
and isinstance(stmt.data, pyvex.IRExpr.Const)
|
|
727
|
+
):
|
|
728
|
+
state.put(stmt.offset, Constant(stmt.data.con.value), force=True)
|
|
729
|
+
break
|
|
730
|
+
|
|
705
731
|
callee_cleanups = [
|
|
706
732
|
callee
|
|
707
733
|
for callee in callees
|
angr/analyses/static_hooker.py
CHANGED
|
@@ -4,6 +4,7 @@ import logging
|
|
|
4
4
|
from . import Analysis
|
|
5
5
|
|
|
6
6
|
from angr import SIM_LIBRARIES
|
|
7
|
+
from angr.analyses import AnalysesHub
|
|
7
8
|
from angr.errors import AngrValueError
|
|
8
9
|
|
|
9
10
|
l = logging.getLogger(name=__name__)
|
|
@@ -47,6 +48,4 @@ class StaticHooker(Analysis):
|
|
|
47
48
|
l.debug("Failed to hook %s at %#x", func.name, func.rebased_addr)
|
|
48
49
|
|
|
49
50
|
|
|
50
|
-
from angr.analyses import AnalysesHub
|
|
51
|
-
|
|
52
51
|
AnalysesHub.register_default("StaticHooker", StaticHooker)
|
|
@@ -870,7 +870,7 @@ class SimpleSolver:
|
|
|
870
870
|
for x, y, data in graph.edges(data=True):
|
|
871
871
|
lbl = data.get("label")
|
|
872
872
|
if lbl and lbl[1] == "recall":
|
|
873
|
-
for
|
|
873
|
+
for _label, z in R[x]:
|
|
874
874
|
if not graph.has_edge(z, y):
|
|
875
875
|
changed = True
|
|
876
876
|
graph.add_edge(z, y)
|
|
@@ -1167,7 +1167,7 @@ class SimpleSolver:
|
|
|
1167
1167
|
|
|
1168
1168
|
candidate_bases = defaultdict(set)
|
|
1169
1169
|
|
|
1170
|
-
for labels,
|
|
1170
|
+
for labels, _succ in path_and_successors:
|
|
1171
1171
|
last_label = labels[-1] if labels else None
|
|
1172
1172
|
if isinstance(last_label, HasField):
|
|
1173
1173
|
# TODO: Really determine the maximum possible size of the field when MAX_POINTSTO_BITS is in use
|
|
@@ -74,17 +74,28 @@ class SimEngineVRAIL(
|
|
|
74
74
|
|
|
75
75
|
elif dst_type is ailment.Expr.VirtualVariable:
|
|
76
76
|
data = self._expr(stmt.src)
|
|
77
|
-
self._assign_to_vvar(
|
|
77
|
+
variable = self._assign_to_vvar(
|
|
78
78
|
stmt.dst, data, src=stmt.src, dst=stmt.dst, vvar_id=self._mapped_vvarid(stmt.dst.varid)
|
|
79
79
|
)
|
|
80
80
|
|
|
81
|
+
if variable is not None and isinstance(stmt.src, ailment.Expr.Phi):
|
|
82
|
+
# this is a phi node - we update variable manager's phi variable tracking
|
|
83
|
+
for _, vvar in stmt.src.src_and_vvars:
|
|
84
|
+
if vvar is not None:
|
|
85
|
+
r = self._read_from_vvar(vvar, expr=stmt.src, vvar_id=self._mapped_vvarid(vvar.varid))
|
|
86
|
+
if r.variable is not None:
|
|
87
|
+
pv = self.variable_manager[self.func_addr]._phi_variables
|
|
88
|
+
if variable not in pv:
|
|
89
|
+
pv[variable] = set()
|
|
90
|
+
pv[variable].add(r.variable)
|
|
91
|
+
|
|
81
92
|
if stmt.dst.was_stack and isinstance(stmt.dst.stack_offset, int):
|
|
82
93
|
# store it to the stack region in case it's directly referenced later
|
|
83
94
|
self._store(
|
|
84
95
|
RichR(self.state.stack_address(stmt.dst.stack_offset)),
|
|
85
96
|
data,
|
|
86
97
|
stmt.dst.bits // self.arch.byte_width,
|
|
87
|
-
|
|
98
|
+
atom=stmt.dst,
|
|
88
99
|
)
|
|
89
100
|
|
|
90
101
|
else:
|
|
@@ -94,10 +105,11 @@ class SimEngineVRAIL(
|
|
|
94
105
|
addr_r = self._expr_bv(stmt.addr)
|
|
95
106
|
data = self._expr(stmt.data)
|
|
96
107
|
size = stmt.size
|
|
97
|
-
self._store(addr_r, data, size,
|
|
108
|
+
self._store(addr_r, data, size, atom=stmt)
|
|
98
109
|
|
|
99
|
-
def _handle_stmt_Jump(self, stmt):
|
|
100
|
-
|
|
110
|
+
def _handle_stmt_Jump(self, stmt: ailment.Stmt.Jump):
|
|
111
|
+
if not isinstance(stmt.target, ailment.Expr.Const):
|
|
112
|
+
self._expr(stmt.target)
|
|
101
113
|
|
|
102
114
|
def _handle_stmt_ConditionalJump(self, stmt):
|
|
103
115
|
self._expr(stmt.condition)
|
|
@@ -149,7 +161,7 @@ class SimEngineVRAIL(
|
|
|
149
161
|
prototype_libname = func.prototype_libname
|
|
150
162
|
|
|
151
163
|
# dump the type of the return value
|
|
152
|
-
ret_ty = typevars.TypeVariable()
|
|
164
|
+
ret_ty = typevars.TypeVariable()
|
|
153
165
|
if isinstance(ret_ty, typeconsts.BottomType):
|
|
154
166
|
ret_ty = typevars.TypeVariable()
|
|
155
167
|
|
|
@@ -218,7 +230,7 @@ class SimEngineVRAIL(
|
|
|
218
230
|
prototype_libname = func.prototype_libname
|
|
219
231
|
|
|
220
232
|
# dump the type of the return value
|
|
221
|
-
ret_ty = typevars.TypeVariable()
|
|
233
|
+
ret_ty = typevars.TypeVariable()
|
|
222
234
|
if isinstance(ret_ty, typeconsts.BottomType):
|
|
223
235
|
ret_ty = typevars.TypeVariable()
|
|
224
236
|
|
|
@@ -387,7 +387,7 @@ class SimEngineVRBase(
|
|
|
387
387
|
) or not create_variable:
|
|
388
388
|
# only store the value. don't worry about variables.
|
|
389
389
|
self.vvar_region[vvar_id] = richr.data
|
|
390
|
-
return
|
|
390
|
+
return None
|
|
391
391
|
|
|
392
392
|
codeloc: CodeLocation = self._codeloc()
|
|
393
393
|
data = richr.data
|
|
@@ -463,10 +463,14 @@ class SimEngineVRBase(
|
|
|
463
463
|
else:
|
|
464
464
|
typevar = self.state.typevars.get_type_variable(variable, codeloc)
|
|
465
465
|
self.state.add_type_constraint(typevars.Subtype(richr.typevar, typevar))
|
|
466
|
+
# the constraint below is a default constraint that may conflict with more specific ones with different
|
|
467
|
+
# sizes; we post-process at the very end of VRA to remove conflicting default constraints.
|
|
466
468
|
self.state.add_type_constraint(typevars.Subtype(typevar, typeconsts.int_type(variable.size * 8)))
|
|
467
469
|
|
|
470
|
+
return variable
|
|
471
|
+
|
|
468
472
|
def _store(
|
|
469
|
-
self, richr_addr: RichR[claripy.ast.BV], data: RichR[claripy.ast.BV | claripy.ast.FP], size,
|
|
473
|
+
self, richr_addr: RichR[claripy.ast.BV], data: RichR[claripy.ast.BV | claripy.ast.FP], size, atom=None
|
|
470
474
|
): # pylint:disable=unused-argument
|
|
471
475
|
"""
|
|
472
476
|
|
|
@@ -481,19 +485,19 @@ class SimEngineVRBase(
|
|
|
481
485
|
|
|
482
486
|
if addr.concrete:
|
|
483
487
|
# fully concrete. this is a global address
|
|
484
|
-
self._store_to_global(addr.concrete_value, data, size, stmt=
|
|
488
|
+
self._store_to_global(addr.concrete_value, data, size, stmt=atom)
|
|
485
489
|
stored = True
|
|
486
490
|
elif self._addr_has_concrete_base(addr) and (parsed := self._parse_offsetted_addr(addr)) is not None:
|
|
487
491
|
# we are storing to a concrete global address with an offset
|
|
488
492
|
base_addr, offset, elem_size = parsed
|
|
489
|
-
self._store_to_global(base_addr.concrete_value, data, size, stmt=
|
|
493
|
+
self._store_to_global(base_addr.concrete_value, data, size, stmt=atom, offset=offset, elem_size=elem_size)
|
|
490
494
|
stored = True
|
|
491
495
|
else:
|
|
492
496
|
if self.state.is_stack_address(addr):
|
|
493
497
|
stack_offset = self.state.get_stack_offset(addr)
|
|
494
498
|
if stack_offset is not None:
|
|
495
499
|
# fast path: Storing data to stack
|
|
496
|
-
self._store_to_stack(stack_offset, data, size,
|
|
500
|
+
self._store_to_stack(stack_offset, data, size, atom=atom)
|
|
497
501
|
stored = True
|
|
498
502
|
|
|
499
503
|
if not stored:
|
|
@@ -504,21 +508,21 @@ class SimEngineVRBase(
|
|
|
504
508
|
codeloc = self._codeloc()
|
|
505
509
|
if existing_vars:
|
|
506
510
|
for existing_var, _ in list(existing_vars):
|
|
507
|
-
self.variable_manager[self.func_addr].remove_variable_by_atom(codeloc, existing_var,
|
|
511
|
+
self.variable_manager[self.func_addr].remove_variable_by_atom(codeloc, existing_var, atom)
|
|
508
512
|
|
|
509
513
|
# storing to a location specified by a pointer whose value cannot be determined at this point
|
|
510
|
-
self._store_to_variable(richr_addr, size
|
|
514
|
+
self._store_to_variable(richr_addr, size)
|
|
511
515
|
|
|
512
516
|
def _store_to_stack(
|
|
513
|
-
self, stack_offset, data: RichR[claripy.ast.BV | claripy.ast.FP], size, offset=0,
|
|
517
|
+
self, stack_offset, data: RichR[claripy.ast.BV | claripy.ast.FP], size, offset=0, atom=None, endness=None
|
|
514
518
|
):
|
|
515
|
-
if
|
|
519
|
+
if atom is None:
|
|
516
520
|
existing_vars = self.variable_manager[self.func_addr].find_variables_by_stmt(
|
|
517
521
|
self.block.addr, self.stmt_idx, "memory"
|
|
518
522
|
)
|
|
519
523
|
else:
|
|
520
524
|
existing_vars = self.variable_manager[self.func_addr].find_variables_by_atom(
|
|
521
|
-
self.block.addr, self.stmt_idx,
|
|
525
|
+
self.block.addr, self.stmt_idx, atom
|
|
522
526
|
)
|
|
523
527
|
if not existing_vars:
|
|
524
528
|
variable = SimStackVariable(
|
|
@@ -562,7 +566,7 @@ class SimEngineVRBase(
|
|
|
562
566
|
var,
|
|
563
567
|
offset_into_var,
|
|
564
568
|
codeloc,
|
|
565
|
-
atom=
|
|
569
|
+
atom=atom,
|
|
566
570
|
)
|
|
567
571
|
|
|
568
572
|
# create type constraints
|
|
@@ -673,9 +677,7 @@ class SimEngineVRBase(
|
|
|
673
677
|
self.state.add_type_constraint(typevars.Subtype(store_typevar, typeconsts.TopType()))
|
|
674
678
|
self.state.add_type_constraint(typevars.Subtype(data.typevar, store_typevar))
|
|
675
679
|
|
|
676
|
-
def _store_to_variable(
|
|
677
|
-
self, richr_addr: RichR[claripy.ast.BV], size: int, stmt=None
|
|
678
|
-
): # pylint:disable=unused-argument
|
|
680
|
+
def _store_to_variable(self, richr_addr: RichR[claripy.ast.BV], size: int):
|
|
679
681
|
addr_variable = richr_addr.variable
|
|
680
682
|
codeloc = self._codeloc()
|
|
681
683
|
|
|
@@ -74,7 +74,7 @@ class SimEngineVRVEX(
|
|
|
74
74
|
size = stmt.data.result_size(self.tyenv) // 8
|
|
75
75
|
r = self._expr(stmt.data)
|
|
76
76
|
|
|
77
|
-
self._store(addr_r, r, size,
|
|
77
|
+
self._store(addr_r, r, size, atom=stmt)
|
|
78
78
|
|
|
79
79
|
def _handle_stmt_StoreG(self, stmt):
|
|
80
80
|
guard = self._expr(stmt.guard)
|
|
@@ -82,7 +82,7 @@ class SimEngineVRVEX(
|
|
|
82
82
|
addr = self._expr_bv(stmt.addr)
|
|
83
83
|
size = stmt.data.result_size(self.tyenv) // 8
|
|
84
84
|
data = self._expr(stmt.data)
|
|
85
|
-
self._store(addr, data, size,
|
|
85
|
+
self._store(addr, data, size, atom=stmt)
|
|
86
86
|
|
|
87
87
|
def _handle_stmt_LoadG(self, stmt):
|
|
88
88
|
guard = self._expr(stmt.guard)
|
|
@@ -12,6 +12,7 @@ import ailment
|
|
|
12
12
|
from ailment.expression import VirtualVariable
|
|
13
13
|
|
|
14
14
|
import angr.errors
|
|
15
|
+
from angr.analyses import AnalysesHub
|
|
15
16
|
from angr.storage.memory_mixins.paged_memory.pages.multi_values import MultiValues
|
|
16
17
|
from angr.block import Block
|
|
17
18
|
from angr.errors import AngrVariableRecoveryError, SimEngineError
|
|
@@ -19,7 +20,8 @@ from angr.knowledge_plugins import Function
|
|
|
19
20
|
from angr.sim_variable import SimStackVariable, SimRegisterVariable, SimVariable, SimMemoryVariable
|
|
20
21
|
from angr.engines.vex.claripy.irop import vexop_to_simop
|
|
21
22
|
from angr.analyses import ForwardAnalysis, visitors
|
|
22
|
-
from angr.analyses.typehoon.typevars import Equivalence, TypeVariable, TypeVariables
|
|
23
|
+
from angr.analyses.typehoon.typevars import Equivalence, TypeVariable, TypeVariables, Subtype, DerivedTypeVariable
|
|
24
|
+
from angr.analyses.typehoon.typeconsts import Int
|
|
23
25
|
from .variable_recovery_base import VariableRecoveryBase, VariableRecoveryStateBase
|
|
24
26
|
from .engine_vex import SimEngineVRVEX
|
|
25
27
|
from .engine_ail import SimEngineVRAIL
|
|
@@ -499,6 +501,26 @@ class VariableRecoveryFast(ForwardAnalysis, VariableRecoveryBase): # pylint:dis
|
|
|
499
501
|
for tv in sorted_typevars[1:]:
|
|
500
502
|
self.type_constraints[self.func_typevar].add(Equivalence(sorted_typevars[0], tv))
|
|
501
503
|
|
|
504
|
+
# remove default constraints with size conflicts
|
|
505
|
+
for func_var in self.type_constraints:
|
|
506
|
+
var_to_subtyping: dict[TypeVariable, list[Subtype]] = defaultdict(list)
|
|
507
|
+
for constraint in self.type_constraints[func_var]:
|
|
508
|
+
if isinstance(constraint, Subtype) and isinstance(constraint.sub_type, TypeVariable):
|
|
509
|
+
var_to_subtyping[constraint.sub_type].append(constraint)
|
|
510
|
+
|
|
511
|
+
for constraints in var_to_subtyping.values():
|
|
512
|
+
if len(constraints) <= 1:
|
|
513
|
+
continue
|
|
514
|
+
default_subtyping_constraints = set()
|
|
515
|
+
has_nondefault_subtyping_constraints = False
|
|
516
|
+
for constraint in constraints:
|
|
517
|
+
if isinstance(constraint.super_type, Int):
|
|
518
|
+
default_subtyping_constraints.add(constraint)
|
|
519
|
+
elif isinstance(constraint.super_type, DerivedTypeVariable) and constraint.super_type.labels:
|
|
520
|
+
has_nondefault_subtyping_constraints = True
|
|
521
|
+
if has_nondefault_subtyping_constraints:
|
|
522
|
+
self.type_constraints[func_var].difference_update(default_subtyping_constraints)
|
|
523
|
+
|
|
502
524
|
self.variable_manager[self.function.addr].ret_val_size = self.ret_val_size
|
|
503
525
|
|
|
504
526
|
self.delayed_type_constraints = None
|
|
@@ -600,6 +622,4 @@ class VariableRecoveryFast(ForwardAnalysis, VariableRecoveryBase): # pylint:dis
|
|
|
600
622
|
state.register_region.store(self.project.arch.sp_offset, sp_v)
|
|
601
623
|
|
|
602
624
|
|
|
603
|
-
from angr.analyses import AnalysesHub
|
|
604
|
-
|
|
605
625
|
AnalysesHub.register_default("VariableRecoveryFast", VariableRecoveryFast)
|
angr/analyses/veritesting.py
CHANGED
|
@@ -4,11 +4,14 @@ from collections import defaultdict
|
|
|
4
4
|
from functools import cmp_to_key
|
|
5
5
|
|
|
6
6
|
import networkx
|
|
7
|
+
from claripy import ClaripyError
|
|
7
8
|
|
|
8
9
|
from angr import SIM_PROCEDURES
|
|
9
10
|
from angr import options as o
|
|
11
|
+
from angr.analyses import AnalysesHub
|
|
10
12
|
from angr.knowledge_base import KnowledgeBase
|
|
11
|
-
from angr.errors import AngrError, AngrCFGError
|
|
13
|
+
from angr.errors import AngrError, AngrCFGError, SimValueError, SimSolverModeError, SimError
|
|
14
|
+
from angr.sim_options import BYPASS_VERITESTING_EXCEPTIONS
|
|
12
15
|
from angr.sim_manager import SimulationManager
|
|
13
16
|
from angr.utils.graph import shallow_reverse
|
|
14
17
|
from . import Analysis, CFGEmulated
|
|
@@ -620,10 +623,4 @@ class Veritesting(Analysis):
|
|
|
620
623
|
return [(n.addr, n.looping_times) for n in nodes]
|
|
621
624
|
|
|
622
625
|
|
|
623
|
-
from angr.analyses import AnalysesHub
|
|
624
|
-
|
|
625
626
|
AnalysesHub.register_default("Veritesting", Veritesting)
|
|
626
|
-
|
|
627
|
-
from angr.errors import SimValueError, SimSolverModeError, SimError
|
|
628
|
-
from angr.sim_options import BYPASS_VERITESTING_EXCEPTIONS
|
|
629
|
-
from claripy import ClaripyError
|
angr/analyses/vfg.py
CHANGED
|
@@ -651,7 +651,7 @@ class VFG(ForwardAnalysis[SimState, VFGNode, VFGJob, BlockID], Analysis): # pyl
|
|
|
651
651
|
l.debug("%s is not recorded. Skip the job.", job)
|
|
652
652
|
raise AngrSkipJobNotice
|
|
653
653
|
# unwind the stack till the target, unless we see any pending jobs for each new top task
|
|
654
|
-
for
|
|
654
|
+
for _ in range(unwind_count):
|
|
655
655
|
if isinstance(self._top_task, FunctionAnalysis):
|
|
656
656
|
# are there any pending job belonging to the current function that we should handle first?
|
|
657
657
|
pending_job_key = self._get_pending_job(self._top_task.function_address)
|
angr/analyses/vsa_ddg.py
CHANGED
|
@@ -5,6 +5,7 @@ from collections import defaultdict
|
|
|
5
5
|
import networkx
|
|
6
6
|
from . import Analysis, VFG
|
|
7
7
|
|
|
8
|
+
from angr.analyses import AnalysesHub
|
|
8
9
|
from angr.code_location import CodeLocation
|
|
9
10
|
from angr.errors import AngrDDGError
|
|
10
11
|
from angr.sim_variable import SimRegisterVariable, SimMemoryVariable
|
|
@@ -416,6 +417,4 @@ class VSA_DDG(Analysis):
|
|
|
416
417
|
return nodes
|
|
417
418
|
|
|
418
419
|
|
|
419
|
-
from angr.analyses import AnalysesHub
|
|
420
|
-
|
|
421
420
|
AnalysesHub.register_default("VSA_DDG", VSA_DDG)
|