angr 9.2.134__py3-none-manylinux2014_x86_64.whl → 9.2.136__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/__init__.py +5 -8
- 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/__init__.py +6 -0
- angr/analyses/{calling_convention.py → calling_convention/calling_convention.py} +32 -64
- angr/analyses/calling_convention/fact_collector.py +502 -0
- angr/analyses/calling_convention/utils.py +57 -0
- 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 +37 -35
- angr/analyses/cfg/cfg_emulated.py +1 -1
- angr/analyses/cfg/cfg_fast.py +62 -15
- 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 +50 -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/complete_calling_conventions.py +32 -3
- 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 +3 -4
- angr/analyses/decompiler/clinic.py +42 -7
- 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/register_save_area_simplifier.py +0 -6
- angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +2 -7
- angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +0 -6
- angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +0 -6
- angr/analyses/decompiler/structuring/phoenix.py +1 -1
- 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/reassembler.py +1 -2
- angr/analyses/s_propagator.py +1 -3
- angr/analyses/soot_class_hierarchy.py +1 -2
- angr/analyses/stack_pointer_tracker.py +18 -2
- angr/analyses/static_hooker.py +1 -2
- angr/analyses/typehoon/simple_solver.py +2 -2
- angr/analyses/variable_recovery/engine_vex.py +5 -0
- angr/analyses/variable_recovery/variable_recovery_fast.py +1 -2
- angr/analyses/veritesting.py +4 -7
- angr/analyses/vfg.py +1 -1
- angr/analyses/vsa_ddg.py +1 -2
- angr/block.py +3 -2
- angr/callable.py +1 -3
- angr/calling_conventions.py +15 -7
- 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/procedure.py +5 -7
- angr/engines/soot/expressions/__init__.py +22 -23
- angr/engines/soot/expressions/base.py +4 -4
- angr/engines/soot/expressions/invoke.py +1 -2
- angr/engines/soot/statements/__init__.py +9 -10
- angr/engines/soot/values/__init__.py +9 -10
- angr/engines/soot/values/arrayref.py +3 -3
- angr/engines/soot/values/instancefieldref.py +3 -2
- angr/engines/successors.py +7 -6
- 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/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/knowledge_plugins/cfg/cfg_model.py +20 -17
- angr/knowledge_plugins/functions/function.py +74 -77
- angr/knowledge_plugins/functions/function_manager.py +14 -7
- angr/knowledge_plugins/functions/function_parser.py +1 -1
- angr/knowledge_plugins/functions/soot_function.py +16 -16
- angr/knowledge_plugins/propagations/propagation_model.py +4 -5
- angr/knowledge_plugins/propagations/states.py +0 -511
- 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/bits.py +13 -0
- 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.134.dist-info → angr-9.2.136.dist-info}/METADATA +6 -6
- {angr-9.2.134.dist-info → angr-9.2.136.dist-info}/RECORD +168 -164
- {angr-9.2.134.dist-info → angr-9.2.136.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.134.dist-info → angr-9.2.136.dist-info}/LICENSE +0 -0
- {angr-9.2.134.dist-info → angr-9.2.136.dist-info}/entry_points.txt +0 -0
- {angr-9.2.134.dist-info → angr-9.2.136.dist-info}/top_level.txt +0 -0
angr/analyses/s_propagator.py
CHANGED
|
@@ -53,7 +53,6 @@ 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,
|
|
58
57
|
func_addr: int | None = None,
|
|
59
58
|
):
|
|
@@ -71,7 +70,6 @@ class SPropagatorAnalysis(Analysis):
|
|
|
71
70
|
self.func_graph = func_graph
|
|
72
71
|
self.func_addr = func_addr
|
|
73
72
|
self.only_consts = only_consts
|
|
74
|
-
self.immediate_stmt_removal = immediate_stmt_removal
|
|
75
73
|
self._sp_tracker = stack_pointer_tracker
|
|
76
74
|
|
|
77
75
|
bp_as_gpr = False
|
|
@@ -209,7 +207,7 @@ class SPropagatorAnalysis(Analysis):
|
|
|
209
207
|
stmt_src = stmt_src.operand
|
|
210
208
|
if isinstance(stmt_src, Load) and isinstance(stmt_src.addr, Const):
|
|
211
209
|
gv_updated = False
|
|
212
|
-
for
|
|
210
|
+
for _vvar_used, vvar_useloc in vvar_uselocs[vvar.varid]:
|
|
213
211
|
gv_updated |= self.is_global_variable_updated(
|
|
214
212
|
self.func_graph,
|
|
215
213
|
blocks,
|
|
@@ -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)
|
|
@@ -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,22 @@ 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 (
|
|
706
|
+
len(callees) == 1
|
|
707
|
+
and callees[0].info.get("is_rust_probestack", False) is True
|
|
708
|
+
and self.project.arch.name == "AMD64"
|
|
709
|
+
):
|
|
710
|
+
# special-case for rust_probestack: sp = sp - rax right after returning from the call, so we need
|
|
711
|
+
# to keep track of rax
|
|
712
|
+
for stmt in reversed(vex_block.statements):
|
|
713
|
+
if (
|
|
714
|
+
isinstance(stmt, pyvex.IRStmt.Put)
|
|
715
|
+
and stmt.offset == self.project.arch.registers["rax"][0]
|
|
716
|
+
and isinstance(stmt.data, pyvex.IRExpr.Const)
|
|
717
|
+
):
|
|
718
|
+
state.put(stmt.offset, Constant(stmt.data.con.value), force=True)
|
|
719
|
+
break
|
|
720
|
+
|
|
705
721
|
callee_cleanups = [
|
|
706
722
|
callee
|
|
707
723
|
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
|
|
@@ -215,6 +215,11 @@ class SimEngineVRVEX(
|
|
|
215
215
|
addr = RichR(loc.stack_offset + one_sp)
|
|
216
216
|
self._load(addr, loc.size)
|
|
217
217
|
|
|
218
|
+
# clobber caller-saved registers
|
|
219
|
+
for reg_name in func.calling_convention.CALLER_SAVED_REGS:
|
|
220
|
+
reg_offset, reg_size = self.arch.registers[reg_name]
|
|
221
|
+
self._assign_to_register(reg_offset, self._top(reg_size * self.arch.byte_width), reg_size)
|
|
222
|
+
|
|
218
223
|
def _process_block_end(self, stmt_result, whitelist):
|
|
219
224
|
# handles block-end calls
|
|
220
225
|
current_addr = self.state.block_addr
|
|
@@ -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
|
|
@@ -600,6 +601,4 @@ class VariableRecoveryFast(ForwardAnalysis, VariableRecoveryBase): # pylint:dis
|
|
|
600
601
|
state.register_region.store(self.project.arch.sp_offset, sp_v)
|
|
601
602
|
|
|
602
603
|
|
|
603
|
-
from angr.analyses import AnalysesHub
|
|
604
|
-
|
|
605
604
|
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)
|
angr/block.py
CHANGED
|
@@ -6,13 +6,14 @@ import pyvex
|
|
|
6
6
|
from pyvex import IRSB
|
|
7
7
|
from archinfo import ArchARM
|
|
8
8
|
|
|
9
|
+
from .protos import primitives_pb2 as pb2
|
|
10
|
+
from .serializable import Serializable
|
|
11
|
+
|
|
9
12
|
try:
|
|
10
13
|
from .engines import pcode
|
|
11
14
|
except ImportError:
|
|
12
15
|
pcode = None
|
|
13
16
|
|
|
14
|
-
from .protos import primitives_pb2 as pb2
|
|
15
|
-
from .serializable import Serializable
|
|
16
17
|
|
|
17
18
|
l = logging.getLogger(name=__name__)
|
|
18
19
|
|
angr/callable.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
import pycparser
|
|
3
3
|
|
|
4
|
+
from .errors import AngrCallableError, AngrCallableMultistateError
|
|
4
5
|
from .calling_conventions import default_cc, SimCC
|
|
5
6
|
|
|
6
7
|
|
|
@@ -158,6 +159,3 @@ class Callable:
|
|
|
158
159
|
raise AngrCallableError(f"Unsupported expression type {type(expr)}.")
|
|
159
160
|
|
|
160
161
|
return self.__call__(*args)
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
from .errors import AngrCallableError, AngrCallableMultistateError
|
angr/calling_conventions.py
CHANGED
|
@@ -4,6 +4,7 @@ import logging
|
|
|
4
4
|
from typing import cast
|
|
5
5
|
from collections.abc import Iterable
|
|
6
6
|
from collections import defaultdict
|
|
7
|
+
import contextlib
|
|
7
8
|
|
|
8
9
|
import claripy
|
|
9
10
|
import archinfo
|
|
@@ -33,7 +34,6 @@ from .sim_type import (
|
|
|
33
34
|
)
|
|
34
35
|
from .state_plugins.sim_action_object import SimActionObject
|
|
35
36
|
from .engines.soot.engine import SootMixin
|
|
36
|
-
import contextlib
|
|
37
37
|
|
|
38
38
|
l = logging.getLogger(name=__name__)
|
|
39
39
|
l.addFilter(UniqueLogFilter())
|
|
@@ -656,7 +656,7 @@ class SimCC:
|
|
|
656
656
|
self.next_arg(session, SimTypePointer(SimTypeBottom()))
|
|
657
657
|
return session
|
|
658
658
|
|
|
659
|
-
def return_in_implicit_outparam(self, ty):
|
|
659
|
+
def return_in_implicit_outparam(self, ty): # pylint:disable=unused-argument
|
|
660
660
|
return False
|
|
661
661
|
|
|
662
662
|
def stack_space(self, args):
|
|
@@ -1098,7 +1098,8 @@ class SimCC:
|
|
|
1098
1098
|
all_fp_args: set[int | str] = {_arg_ident(a) for a in sample_inst.fp_args}
|
|
1099
1099
|
all_int_args: set[int | str] = {_arg_ident(a) for a in sample_inst.int_args}
|
|
1100
1100
|
both_iter = sample_inst.memory_args
|
|
1101
|
-
|
|
1101
|
+
max_args = cls._guess_arg_count(args)
|
|
1102
|
+
some_both_args: set[int | str] = {_arg_ident(next(both_iter)) for _ in range(max_args)}
|
|
1102
1103
|
|
|
1103
1104
|
new_args = []
|
|
1104
1105
|
for arg in args:
|
|
@@ -1115,6 +1116,13 @@ class SimCC:
|
|
|
1115
1116
|
|
|
1116
1117
|
return True
|
|
1117
1118
|
|
|
1119
|
+
@classmethod
|
|
1120
|
+
def _guess_arg_count(cls, args, limit: int = 64) -> int:
|
|
1121
|
+
# pylint:disable=not-callable
|
|
1122
|
+
stack_args = [a for a in args if isinstance(a, SimStackArg)]
|
|
1123
|
+
stack_arg_count = (max(a.stack_offset for a in stack_args) // cls.ARCH().bytes + 1) if stack_args else 0
|
|
1124
|
+
return min(limit, max(len(args), stack_arg_count))
|
|
1125
|
+
|
|
1118
1126
|
@staticmethod
|
|
1119
1127
|
def find_cc(
|
|
1120
1128
|
arch: archinfo.Arch, args: list[SimFunctionArgument], sp_delta: int, platform: str = "Linux"
|
|
@@ -1592,7 +1600,7 @@ class SimCCSystemVAMD64(SimCC):
|
|
|
1592
1600
|
# TODO I think we need an explicit stride field on array types
|
|
1593
1601
|
result[idx * ty.elem_type.size // self.arch.byte_width + suboffset] += subsubty_list
|
|
1594
1602
|
elif isinstance(ty, SimUnion):
|
|
1595
|
-
for
|
|
1603
|
+
for subty in ty.members.values():
|
|
1596
1604
|
subresult = self._flatten(subty)
|
|
1597
1605
|
if subresult is None:
|
|
1598
1606
|
return None
|
|
@@ -1687,7 +1695,7 @@ class SimCCARM(SimCC):
|
|
|
1687
1695
|
raise NotImplementedError("Bug. Report to @rhelmot")
|
|
1688
1696
|
elif cls == "MEMORY":
|
|
1689
1697
|
mapped_classes.append(next(session.both_iter))
|
|
1690
|
-
elif cls
|
|
1698
|
+
elif cls in {"INTEGER", "SINGLEP"}:
|
|
1691
1699
|
try:
|
|
1692
1700
|
mapped_classes.append(next(session.int_iter))
|
|
1693
1701
|
except StopIteration:
|
|
@@ -1764,7 +1772,7 @@ class SimCCARM(SimCC):
|
|
|
1764
1772
|
# TODO I think we need an explicit stride field on array types
|
|
1765
1773
|
result[idx * ty.elem_type.size // self.arch.byte_width + suboffset] += subsubty_list
|
|
1766
1774
|
elif isinstance(ty, SimUnion):
|
|
1767
|
-
for
|
|
1775
|
+
for subty in ty.members.values():
|
|
1768
1776
|
subresult = self._flatten(subty)
|
|
1769
1777
|
if subresult is None:
|
|
1770
1778
|
return None
|
|
@@ -1983,7 +1991,7 @@ class SimCCO32(SimCC):
|
|
|
1983
1991
|
# TODO I think we need an explicit stride field on array types
|
|
1984
1992
|
result[idx * ty.elem_type.size // self.arch.byte_width + suboffset] += subsubty_list
|
|
1985
1993
|
elif isinstance(ty, SimUnion):
|
|
1986
|
-
for
|
|
1994
|
+
for subty in ty.members.values():
|
|
1987
1995
|
subresult = self._flatten(subty)
|
|
1988
1996
|
if subresult is None:
|
|
1989
1997
|
return None
|
angr/codenode.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
import logging
|
|
3
|
+
import weakref
|
|
3
4
|
|
|
4
5
|
l = logging.getLogger(name=__name__)
|
|
5
6
|
|
|
@@ -17,7 +18,7 @@ class CodeNode:
|
|
|
17
18
|
self.addr: int = addr
|
|
18
19
|
self.size: int = size
|
|
19
20
|
self.thumb = thumb
|
|
20
|
-
self._graph = graph
|
|
21
|
+
self._graph = weakref.proxy(graph) if graph is not None else None
|
|
21
22
|
|
|
22
23
|
self._hash = None
|
|
23
24
|
|
|
@@ -46,6 +47,9 @@ class CodeNode:
|
|
|
46
47
|
self._hash = hash((self.addr, self.size))
|
|
47
48
|
return self._hash
|
|
48
49
|
|
|
50
|
+
def set_graph(self, graph):
|
|
51
|
+
self._graph = weakref.proxy(graph)
|
|
52
|
+
|
|
49
53
|
def successors(self) -> list[CodeNode]:
|
|
50
54
|
if self._graph is None:
|
|
51
55
|
raise ValueError("Cannot calculate successors for graphless node")
|
|
@@ -1,89 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
class SimConcretizationStrategy:
|
|
5
|
-
"""
|
|
6
|
-
Concretization strategies control the resolution of symbolic memory indices
|
|
7
|
-
in SimuVEX. By subclassing this class and setting it as a concretization strategy
|
|
8
|
-
(on state.memory.read_strategies and state.memory.write_strategies), SimuVEX's
|
|
9
|
-
memory index concretization behavior can be modified.
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
def __init__(self, filter=None, exact=True): # pylint:disable=redefined-builtin
|
|
13
|
-
"""
|
|
14
|
-
Initializes the base SimConcretizationStrategy.
|
|
15
|
-
|
|
16
|
-
:param filter: A function, taking arguments of (SimMemory, claripy.AST) that determines
|
|
17
|
-
if this strategy can handle resolving the provided AST.
|
|
18
|
-
:param exact: A flag (default: True) that determines if the convenience resolution
|
|
19
|
-
functions provided by this class use exact or approximate resolution.
|
|
20
|
-
"""
|
|
21
|
-
self._exact = exact
|
|
22
|
-
self._filter = filter
|
|
23
|
-
|
|
24
|
-
def _min(self, memory, addr, **kwargs):
|
|
25
|
-
"""
|
|
26
|
-
Gets the minimum solution of an address.
|
|
27
|
-
"""
|
|
28
|
-
return memory.state.solver.min(addr, exact=kwargs.pop("exact", self._exact), **kwargs)
|
|
29
|
-
|
|
30
|
-
def _max(self, memory, addr, **kwargs):
|
|
31
|
-
"""
|
|
32
|
-
Gets the maximum solution of an address.
|
|
33
|
-
"""
|
|
34
|
-
return memory.state.solver.max(addr, exact=kwargs.pop("exact", self._exact), **kwargs)
|
|
35
|
-
|
|
36
|
-
def _any(self, memory, addr, **kwargs):
|
|
37
|
-
"""
|
|
38
|
-
Gets any solution of an address.
|
|
39
|
-
"""
|
|
40
|
-
return memory.state.solver.eval(addr, exact=kwargs.pop("exact", self._exact), **kwargs)
|
|
41
|
-
|
|
42
|
-
def _eval(self, memory, addr, n, **kwargs):
|
|
43
|
-
"""
|
|
44
|
-
Gets n solutions for an address.
|
|
45
|
-
"""
|
|
46
|
-
return memory.state.solver.eval_upto(addr, n, exact=kwargs.pop("exact", self._exact), **kwargs)
|
|
47
|
-
|
|
48
|
-
def _range(self, memory, addr, **kwargs):
|
|
49
|
-
"""
|
|
50
|
-
Gets the (min, max) range of solutions for an address.
|
|
51
|
-
"""
|
|
52
|
-
return (self._min(memory, addr, **kwargs), self._max(memory, addr, **kwargs))
|
|
53
|
-
|
|
54
|
-
def concretize(self, memory, addr, **kwargs):
|
|
55
|
-
"""
|
|
56
|
-
Concretizes the address into a list of values.
|
|
57
|
-
If this strategy cannot handle this address, returns None.
|
|
58
|
-
"""
|
|
59
|
-
if self._filter is None or self._filter(memory, addr):
|
|
60
|
-
return self._concretize(memory, addr, **kwargs)
|
|
61
|
-
return None
|
|
62
|
-
|
|
63
|
-
def _concretize(self, memory, addr, **kwargs):
|
|
64
|
-
"""
|
|
65
|
-
Should be implemented by child classes to handle concretization.
|
|
66
|
-
:param **kwargs:
|
|
67
|
-
"""
|
|
68
|
-
raise NotImplementedError
|
|
69
|
-
|
|
70
|
-
def copy(self):
|
|
71
|
-
"""
|
|
72
|
-
Returns a copy of the strategy, if there is data that should be kept separate between
|
|
73
|
-
states. If not, returns self.
|
|
74
|
-
"""
|
|
75
|
-
return self
|
|
76
|
-
|
|
77
|
-
def merge(self, others):
|
|
78
|
-
"""
|
|
79
|
-
Merges this strategy with others (if there is data that should be kept separate between
|
|
80
|
-
states. If not, is a no-op.
|
|
81
|
-
"""
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
# pylint: disable=wrong-import-position
|
|
85
|
-
# FIXME: This is a circular import, move base class to a separate file
|
|
86
3
|
from .any import SimConcretizationStrategyAny
|
|
4
|
+
from .base import SimConcretizationStrategy
|
|
87
5
|
from .controlled_data import SimConcretizationStrategyControlledData
|
|
88
6
|
from .eval import SimConcretizationStrategyEval
|
|
89
7
|
from .max import SimConcretizationStrategyMax
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class SimConcretizationStrategy:
|
|
5
|
+
"""
|
|
6
|
+
Concretization strategies control the resolution of symbolic memory indices
|
|
7
|
+
in SimuVEX. By subclassing this class and setting it as a concretization strategy
|
|
8
|
+
(on state.memory.read_strategies and state.memory.write_strategies), SimuVEX's
|
|
9
|
+
memory index concretization behavior can be modified.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, filter=None, exact=True): # pylint:disable=redefined-builtin
|
|
13
|
+
"""
|
|
14
|
+
Initializes the base SimConcretizationStrategy.
|
|
15
|
+
|
|
16
|
+
:param filter: A function, taking arguments of (SimMemory, claripy.AST) that determines
|
|
17
|
+
if this strategy can handle resolving the provided AST.
|
|
18
|
+
:param exact: A flag (default: True) that determines if the convenience resolution
|
|
19
|
+
functions provided by this class use exact or approximate resolution.
|
|
20
|
+
"""
|
|
21
|
+
self._exact = exact
|
|
22
|
+
self._filter = filter
|
|
23
|
+
|
|
24
|
+
def _min(self, memory, addr, **kwargs):
|
|
25
|
+
"""
|
|
26
|
+
Gets the minimum solution of an address.
|
|
27
|
+
"""
|
|
28
|
+
return memory.state.solver.min(addr, exact=kwargs.pop("exact", self._exact), **kwargs)
|
|
29
|
+
|
|
30
|
+
def _max(self, memory, addr, **kwargs):
|
|
31
|
+
"""
|
|
32
|
+
Gets the maximum solution of an address.
|
|
33
|
+
"""
|
|
34
|
+
return memory.state.solver.max(addr, exact=kwargs.pop("exact", self._exact), **kwargs)
|
|
35
|
+
|
|
36
|
+
def _any(self, memory, addr, **kwargs):
|
|
37
|
+
"""
|
|
38
|
+
Gets any solution of an address.
|
|
39
|
+
"""
|
|
40
|
+
return memory.state.solver.eval(addr, exact=kwargs.pop("exact", self._exact), **kwargs)
|
|
41
|
+
|
|
42
|
+
def _eval(self, memory, addr, n, **kwargs):
|
|
43
|
+
"""
|
|
44
|
+
Gets n solutions for an address.
|
|
45
|
+
"""
|
|
46
|
+
return memory.state.solver.eval_upto(addr, n, exact=kwargs.pop("exact", self._exact), **kwargs)
|
|
47
|
+
|
|
48
|
+
def _range(self, memory, addr, **kwargs):
|
|
49
|
+
"""
|
|
50
|
+
Gets the (min, max) range of solutions for an address.
|
|
51
|
+
"""
|
|
52
|
+
return (self._min(memory, addr, **kwargs), self._max(memory, addr, **kwargs))
|
|
53
|
+
|
|
54
|
+
def concretize(self, memory, addr, **kwargs):
|
|
55
|
+
"""
|
|
56
|
+
Concretizes the address into a list of values.
|
|
57
|
+
If this strategy cannot handle this address, returns None.
|
|
58
|
+
"""
|
|
59
|
+
if self._filter is None or self._filter(memory, addr):
|
|
60
|
+
return self._concretize(memory, addr, **kwargs)
|
|
61
|
+
return None
|
|
62
|
+
|
|
63
|
+
def _concretize(self, memory, addr, **kwargs):
|
|
64
|
+
"""
|
|
65
|
+
Should be implemented by child classes to handle concretization.
|
|
66
|
+
:param **kwargs:
|
|
67
|
+
"""
|
|
68
|
+
raise NotImplementedError
|
|
69
|
+
|
|
70
|
+
def copy(self):
|
|
71
|
+
"""
|
|
72
|
+
Returns a copy of the strategy, if there is data that should be kept separate between
|
|
73
|
+
states. If not, returns self.
|
|
74
|
+
"""
|
|
75
|
+
return self
|
|
76
|
+
|
|
77
|
+
def merge(self, others):
|
|
78
|
+
"""
|
|
79
|
+
Merges this strategy with others (if there is data that should be kept separate between
|
|
80
|
+
states. If not, is a no-op.
|
|
81
|
+
"""
|