angr 9.2.135__py3-none-macosx_11_0_arm64.whl → 9.2.136__py3-none-macosx_11_0_arm64.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 +4 -3
- angr/analyses/calling_convention/fact_collector.py +0 -1
- 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/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/stack_canary_simplifier.py +1 -1
- 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/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 +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/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 +70 -73
- 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 +16 -16
- angr/knowledge_plugins/propagations/propagation_model.py +4 -5
- angr/knowledge_plugins/propagations/states.py +0 -511
- angr/lib/angr_native.dylib +0 -0
- 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.136.dist-info}/METADATA +6 -6
- {angr-9.2.135.dist-info → angr-9.2.136.dist-info}/RECORD +161 -160
- {angr-9.2.135.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.135.dist-info → angr-9.2.136.dist-info}/LICENSE +0 -0
- {angr-9.2.135.dist-info → angr-9.2.136.dist-info}/entry_points.txt +0 -0
- {angr-9.2.135.dist-info → angr-9.2.136.dist-info}/top_level.txt +0 -0
angr/__init__.py
CHANGED
angr/analyses/__init__.py
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
# " pylint:disable=wrong-import-position
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
|
-
from .analysis import Analysis, AnalysesHub
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def register_analysis(cls, name):
|
|
8
|
-
AnalysesHub.register_default(name, cls)
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
from .analysis import Analysis, AnalysesHub, register_analysis
|
|
11
5
|
from .forward_analysis import ForwardAnalysis, visitors
|
|
12
6
|
from .propagator import PropagatorAnalysis
|
|
13
7
|
from .cfg import CFGFast, CFGEmulated, CFG, CFGArchOptions, CFGFastSoot
|
|
@@ -54,6 +48,7 @@ from .patchfinder import PatchFinderAnalysis
|
|
|
54
48
|
from .pathfinder import Pathfinder
|
|
55
49
|
from .smc import SelfModifyingCodeAnalysis
|
|
56
50
|
from .unpacker import PackingDetector
|
|
51
|
+
from .fcp import FastConstantPropagation
|
|
57
52
|
from . import deobfuscator
|
|
58
53
|
|
|
59
54
|
|
|
@@ -85,6 +80,7 @@ __all__ = (
|
|
|
85
80
|
"Disassembly",
|
|
86
81
|
"DominanceFrontier",
|
|
87
82
|
"FactCollector",
|
|
83
|
+
"FastConstantPropagation",
|
|
88
84
|
"FlirtAnalysis",
|
|
89
85
|
"ForwardAnalysis",
|
|
90
86
|
"Identifier",
|
angr/analyses/analysis.py
CHANGED
angr/analyses/backward_slice.py
CHANGED
|
@@ -6,6 +6,7 @@ import networkx
|
|
|
6
6
|
import pyvex
|
|
7
7
|
from . import Analysis
|
|
8
8
|
|
|
9
|
+
from angr.analyses import AnalysesHub
|
|
9
10
|
from angr.code_location import CodeLocation
|
|
10
11
|
from angr.annocfg import AnnotatedCFG
|
|
11
12
|
from angr.errors import AngrBackwardSlicingError
|
|
@@ -682,6 +683,4 @@ class BackwardSlice(Analysis):
|
|
|
682
683
|
return cmp_stmt_id, cmp_tmp_id
|
|
683
684
|
|
|
684
685
|
|
|
685
|
-
from angr.analyses import AnalysesHub
|
|
686
|
-
|
|
687
686
|
AnalysesHub.register_default("BackwardSlice", BackwardSlice)
|
|
@@ -4,6 +4,7 @@ import re
|
|
|
4
4
|
from typing import TYPE_CHECKING
|
|
5
5
|
from collections import defaultdict
|
|
6
6
|
|
|
7
|
+
from angr.analyses import AnalysesHub
|
|
7
8
|
from angr.knowledge_base import KnowledgeBase
|
|
8
9
|
from angr.codenode import HookNode
|
|
9
10
|
from angr.sim_variable import SimConstantVariable, SimRegisterVariable, SimMemoryVariable, SimStackVariable
|
|
@@ -430,7 +431,7 @@ class BinaryOptimizer(Analysis):
|
|
|
430
431
|
|
|
431
432
|
# find out all call instructions
|
|
432
433
|
call_insns = set()
|
|
433
|
-
for src,
|
|
434
|
+
for src, _dst, data in function.transition_graph.edges(data=True):
|
|
434
435
|
if "type" in data and data["type"] == "call":
|
|
435
436
|
src_block = function._get_block(src.addr)
|
|
436
437
|
call_insns.add(src_block.instruction_addrs[-1])
|
|
@@ -460,7 +461,7 @@ class BinaryOptimizer(Analysis):
|
|
|
460
461
|
# make sure we never gets the address of those stack variables into any register
|
|
461
462
|
# say, lea edx, [ebp-0x4] is forbidden
|
|
462
463
|
# check all edges in data graph
|
|
463
|
-
for src, dst
|
|
464
|
+
for src, dst in data_graph.edges():
|
|
464
465
|
if (
|
|
465
466
|
isinstance(dst.variable, SimRegisterVariable)
|
|
466
467
|
and dst.variable.reg != ebp_offset
|
|
@@ -666,6 +667,4 @@ class BinaryOptimizer(Analysis):
|
|
|
666
667
|
self.dead_assignments.append(da)
|
|
667
668
|
|
|
668
669
|
|
|
669
|
-
from angr.analyses import AnalysesHub
|
|
670
|
-
|
|
671
670
|
AnalysesHub.register_default("BinaryOptimizer", BinaryOptimizer)
|
angr/analyses/bindiff.py
CHANGED
|
@@ -3,17 +3,17 @@ import logging
|
|
|
3
3
|
import math
|
|
4
4
|
import types
|
|
5
5
|
from collections import deque, defaultdict
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
6
7
|
|
|
7
8
|
import networkx
|
|
8
9
|
|
|
9
|
-
from
|
|
10
|
+
from angr.analyses import AnalysesHub, Analysis, CFGEmulated
|
|
11
|
+
from angr.errors import SimEngineError, SimMemoryError
|
|
12
|
+
|
|
10
13
|
|
|
11
14
|
if TYPE_CHECKING:
|
|
12
15
|
from angr.knowledge_plugins import Function
|
|
13
16
|
|
|
14
|
-
from . import Analysis, CFGEmulated
|
|
15
|
-
|
|
16
|
-
from angr.errors import SimEngineError, SimMemoryError
|
|
17
17
|
|
|
18
18
|
# todo include an explanation of the algorithm
|
|
19
19
|
# todo include a method that detects any change other than constants
|
|
@@ -1234,6 +1234,4 @@ class BinDiff(Analysis):
|
|
|
1234
1234
|
return matches
|
|
1235
1235
|
|
|
1236
1236
|
|
|
1237
|
-
from angr.analyses import AnalysesHub
|
|
1238
|
-
|
|
1239
1237
|
AnalysesHub.register_default("BinDiff", BinDiff)
|
angr/analyses/boyscout.py
CHANGED
|
@@ -6,7 +6,7 @@ from collections import defaultdict
|
|
|
6
6
|
from archinfo import all_arches
|
|
7
7
|
from archinfo.arch_arm import is_arm_arch
|
|
8
8
|
|
|
9
|
-
from . import Analysis
|
|
9
|
+
from angr.analyses import AnalysesHub, Analysis
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
l = logging.getLogger(name=__name__)
|
|
@@ -73,6 +73,4 @@ class BoyScout(Analysis):
|
|
|
73
73
|
l.debug("The architecture should be %s with %s", self.arch, self.endianness)
|
|
74
74
|
|
|
75
75
|
|
|
76
|
-
from angr.analyses import AnalysesHub
|
|
77
|
-
|
|
78
76
|
AnalysesHub.register_default("BoyScout", BoyScout)
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
-
from . import Analysis
|
|
3
|
-
from angr import SIM_PROCEDURES
|
|
4
2
|
|
|
5
3
|
import logging
|
|
6
4
|
|
|
5
|
+
from angr import SIM_PROCEDURES
|
|
6
|
+
from angr.analyses import AnalysesHub, Analysis
|
|
7
|
+
|
|
8
|
+
|
|
7
9
|
l = logging.getLogger(name=__name__)
|
|
8
10
|
|
|
9
11
|
|
|
@@ -69,6 +71,4 @@ class CalleeCleanupFinder(Analysis):
|
|
|
69
71
|
return None
|
|
70
72
|
|
|
71
73
|
|
|
72
|
-
from angr.analyses import AnalysesHub
|
|
73
|
-
|
|
74
74
|
AnalysesHub.register_default("CalleeCleanupFinder", CalleeCleanupFinder)
|
|
@@ -923,9 +923,10 @@ class CallingConventionAnalysis(Analysis):
|
|
|
923
923
|
if not set(spilled_regs).issubset(set(allowed_spilled_regs)):
|
|
924
924
|
return False, None
|
|
925
925
|
|
|
926
|
-
|
|
927
|
-
if reg in spilled_regs
|
|
928
|
-
|
|
926
|
+
i = next(
|
|
927
|
+
(i for i, reg in enumerate(allowed_spilled_regs) if reg in spilled_regs),
|
|
928
|
+
len(allowed_spilled_regs),
|
|
929
|
+
)
|
|
929
930
|
|
|
930
931
|
return True, i
|
|
931
932
|
|
angr/analyses/cdg.py
CHANGED
|
@@ -3,6 +3,7 @@ import logging
|
|
|
3
3
|
|
|
4
4
|
import networkx
|
|
5
5
|
|
|
6
|
+
from angr.analyses import AnalysesHub
|
|
6
7
|
from angr.utils.graph import compute_dominance_frontier, PostDominators, TemporaryNode
|
|
7
8
|
from . import Analysis
|
|
8
9
|
|
|
@@ -185,6 +186,4 @@ class CDG(Analysis):
|
|
|
185
186
|
_l.debug("%s is not in post dominator dict.", b2)
|
|
186
187
|
|
|
187
188
|
|
|
188
|
-
from angr.analyses import AnalysesHub
|
|
189
|
-
|
|
190
189
|
AnalysesHub.register_default("CDG", CDG)
|
angr/analyses/cfg/cfb.py
CHANGED
|
@@ -6,9 +6,9 @@ from collections.abc import Callable
|
|
|
6
6
|
import cle
|
|
7
7
|
from cle.backends.externs import KernelObject, ExternObject
|
|
8
8
|
from cle.backends.tls.elf_tls import ELFTLSObject
|
|
9
|
-
|
|
10
9
|
from sortedcontainers import SortedDict
|
|
11
10
|
|
|
11
|
+
from angr.analyses import AnalysesHub
|
|
12
12
|
from angr.knowledge_plugins.cfg.memory_data import MemoryDataSort, MemoryData
|
|
13
13
|
from angr.analyses.analysis import Analysis
|
|
14
14
|
|
|
@@ -424,7 +424,5 @@ class CFBlanket(Analysis):
|
|
|
424
424
|
addr = max_addr
|
|
425
425
|
|
|
426
426
|
|
|
427
|
-
from angr.analyses import AnalysesHub
|
|
428
|
-
|
|
429
427
|
AnalysesHub.register_default("CFB", CFBlanket)
|
|
430
428
|
AnalysesHub.register_default("CFBlanket", CFBlanket)
|
angr/analyses/cfg/cfg.py
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
+
|
|
2
3
|
import sys
|
|
3
4
|
|
|
5
|
+
from angr.analyses import AnalysesHub
|
|
4
6
|
from .cfg_fast import CFGFast
|
|
5
7
|
|
|
6
8
|
|
|
@@ -69,6 +71,4 @@ class CFG(CFGFast): # pylint: disable=abstract-method
|
|
|
69
71
|
CFGFast.__init__(self, **kwargs)
|
|
70
72
|
|
|
71
73
|
|
|
72
|
-
from angr.analyses import AnalysesHub
|
|
73
|
-
|
|
74
74
|
AnalysesHub.register_default("CFG", CFG)
|
angr/analyses/cfg/cfg_base.py
CHANGED
|
@@ -1570,13 +1570,13 @@ class CFGBase(Analysis):
|
|
|
1570
1570
|
# TODO: Is it required that PLT stubs are always aligned by 16? If so, on what architectures and platforms is it
|
|
1571
1571
|
# TODO: enforced?
|
|
1572
1572
|
|
|
1573
|
-
tmp_functions = self.kb.functions
|
|
1573
|
+
tmp_functions = self.kb.functions
|
|
1574
1574
|
|
|
1575
1575
|
for function in tmp_functions.values():
|
|
1576
1576
|
function.mark_nonreturning_calls_endpoints()
|
|
1577
1577
|
if function.returning is False:
|
|
1578
1578
|
# remove all FakeRet edges that are related to this function
|
|
1579
|
-
func_node = self.model.get_any_node(function.addr)
|
|
1579
|
+
func_node = self.model.get_any_node(function.addr, force_fastpath=True)
|
|
1580
1580
|
if func_node is not None:
|
|
1581
1581
|
callsite_nodes = [
|
|
1582
1582
|
src
|
|
@@ -1588,8 +1588,8 @@ class CFGBase(Analysis):
|
|
|
1588
1588
|
if data.get("jumpkind", None) == "Ijk_FakeRet":
|
|
1589
1589
|
self.graph.remove_edge(callsite_node, dst)
|
|
1590
1590
|
|
|
1591
|
-
# Clear old functions dict
|
|
1592
|
-
self.kb.functions.
|
|
1591
|
+
# Clear old functions dict by creating a new function manager
|
|
1592
|
+
self.kb.functions = FunctionManager(self.kb)
|
|
1593
1593
|
|
|
1594
1594
|
blockaddr_to_function = {}
|
|
1595
1595
|
traversed_cfg_nodes = set()
|
|
@@ -1602,7 +1602,7 @@ class CFGBase(Analysis):
|
|
|
1602
1602
|
if jumpkind == "Ijk_Call" or jumpkind.startswith("Ijk_Sys"):
|
|
1603
1603
|
function_nodes.add(dst)
|
|
1604
1604
|
|
|
1605
|
-
entry_node = self.model.get_any_node(self._binary.entry)
|
|
1605
|
+
entry_node = self.model.get_any_node(self._binary.entry, force_fastpath=True)
|
|
1606
1606
|
if entry_node is not None:
|
|
1607
1607
|
function_nodes.add(entry_node)
|
|
1608
1608
|
|
|
@@ -1663,7 +1663,7 @@ class CFGBase(Analysis):
|
|
|
1663
1663
|
secondary_function_nodes = set()
|
|
1664
1664
|
# add all function chunks ("functions" that are not called from anywhere)
|
|
1665
1665
|
for func_addr in tmp_functions:
|
|
1666
|
-
node = self.model.get_any_node(func_addr)
|
|
1666
|
+
node = self.model.get_any_node(func_addr, force_fastpath=True)
|
|
1667
1667
|
if node is None:
|
|
1668
1668
|
continue
|
|
1669
1669
|
if node.addr not in blockaddr_to_function:
|
|
@@ -1992,8 +1992,8 @@ class CFGBase(Analysis):
|
|
|
1992
1992
|
if not transition_found:
|
|
1993
1993
|
continue
|
|
1994
1994
|
|
|
1995
|
-
cfgnode_0 = self.model.get_any_node(block_node.addr)
|
|
1996
|
-
cfgnode_1 = self.model.get_any_node(addr_1)
|
|
1995
|
+
cfgnode_0 = self.model.get_any_node(block_node.addr, force_fastpath=True)
|
|
1996
|
+
cfgnode_1 = self.model.get_any_node(addr_1, force_fastpath=True)
|
|
1997
1997
|
|
|
1998
1998
|
if cfgnode_0 is None or cfgnode_1 is None:
|
|
1999
1999
|
continue
|
|
@@ -2089,7 +2089,7 @@ class CFGBase(Analysis):
|
|
|
2089
2089
|
continue
|
|
2090
2090
|
if func_addr in jumptable_entries:
|
|
2091
2091
|
# is there any call edge pointing to it?
|
|
2092
|
-
func_node = self.get_any_node(func_addr)
|
|
2092
|
+
func_node = self.get_any_node(func_addr, force_fastpath=True)
|
|
2093
2093
|
if func_node is not None:
|
|
2094
2094
|
in_edges = self.graph.in_edges(func_node, data=True)
|
|
2095
2095
|
has_transition_pred = None
|
|
@@ -2128,7 +2128,7 @@ class CFGBase(Analysis):
|
|
|
2128
2128
|
else:
|
|
2129
2129
|
is_syscall = self.project.simos.is_syscall_addr(addr)
|
|
2130
2130
|
|
|
2131
|
-
n = self.model.get_any_node(addr, is_syscall=is_syscall)
|
|
2131
|
+
n = self.model.get_any_node(addr, is_syscall=is_syscall, force_fastpath=True)
|
|
2132
2132
|
node = addr if n is None else self._to_snippet(n)
|
|
2133
2133
|
|
|
2134
2134
|
if isinstance(addr, SootAddressDescriptor):
|
|
@@ -2304,7 +2304,7 @@ class CFGBase(Analysis):
|
|
|
2304
2304
|
src_function = self._addr_to_function(src_addr, blockaddr_to_function, known_functions)
|
|
2305
2305
|
|
|
2306
2306
|
if src_addr not in src_function.block_addrs_set:
|
|
2307
|
-
n = self.model.get_any_node(src_addr)
|
|
2307
|
+
n = self.model.get_any_node(src_addr, force_fastpath=True)
|
|
2308
2308
|
node = src_addr if n is None else self._to_snippet(n)
|
|
2309
2309
|
self.kb.functions._add_node(src_function.addr, node)
|
|
2310
2310
|
|
|
@@ -2315,7 +2315,7 @@ class CFGBase(Analysis):
|
|
|
2315
2315
|
jumpkind = data["jumpkind"]
|
|
2316
2316
|
|
|
2317
2317
|
if jumpkind == "Ijk_Ret":
|
|
2318
|
-
n = self.model.get_any_node(src_addr)
|
|
2318
|
+
n = self.model.get_any_node(src_addr, force_fastpath=True)
|
|
2319
2319
|
from_node = src_addr if n is None else self._to_snippet(n)
|
|
2320
2320
|
self.kb.functions._add_return_from(src_function.addr, from_node, None)
|
|
2321
2321
|
|
|
@@ -2334,7 +2334,7 @@ class CFGBase(Analysis):
|
|
|
2334
2334
|
# It must be calling a function
|
|
2335
2335
|
dst_function = self._addr_to_function(dst_addr, blockaddr_to_function, known_functions)
|
|
2336
2336
|
|
|
2337
|
-
n = self.model.get_any_node(src_addr)
|
|
2337
|
+
n = self.model.get_any_node(src_addr, force_fastpath=True)
|
|
2338
2338
|
if n is None:
|
|
2339
2339
|
src_snippet = self._to_snippet(addr=src_addr, base_state=self._base_state)
|
|
2340
2340
|
else:
|
|
@@ -2349,21 +2349,12 @@ class CFGBase(Analysis):
|
|
|
2349
2349
|
else:
|
|
2350
2350
|
fakeret_node = self._one_fakeret_node(all_edges)
|
|
2351
2351
|
|
|
2352
|
-
fakeret_snippet = None if fakeret_node is None else self._to_snippet(cfg_node=fakeret_node)
|
|
2353
|
-
|
|
2354
2352
|
if isinstance(dst_addr, SootAddressDescriptor):
|
|
2355
2353
|
dst_addr = dst_addr.method
|
|
2356
2354
|
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
dst_addr,
|
|
2361
|
-
fakeret_snippet,
|
|
2362
|
-
syscall=is_syscall,
|
|
2363
|
-
ins_addr=ins_addr,
|
|
2364
|
-
stmt_idx=stmt_idx,
|
|
2365
|
-
)
|
|
2366
|
-
|
|
2355
|
+
# determining the returning target
|
|
2356
|
+
return_to_outside = False
|
|
2357
|
+
returning_snippet = None
|
|
2367
2358
|
if dst_function.returning and fakeret_node is not None:
|
|
2368
2359
|
returning_target = src.addr + src.size
|
|
2369
2360
|
if returning_target not in blockaddr_to_function:
|
|
@@ -2372,9 +2363,9 @@ class CFGBase(Analysis):
|
|
|
2372
2363
|
else:
|
|
2373
2364
|
self._addr_to_function(returning_target, blockaddr_to_function, known_functions)
|
|
2374
2365
|
|
|
2375
|
-
|
|
2366
|
+
return_to_outside = blockaddr_to_function[returning_target] is not src_function
|
|
2376
2367
|
|
|
2377
|
-
n = self.model.get_any_node(returning_target)
|
|
2368
|
+
n = self.model.get_any_node(returning_target, force_fastpath=True)
|
|
2378
2369
|
if n is None:
|
|
2379
2370
|
try:
|
|
2380
2371
|
returning_snippet = self._to_snippet(addr=returning_target, base_state=self._base_state)
|
|
@@ -2384,17 +2375,28 @@ class CFGBase(Analysis):
|
|
|
2384
2375
|
else:
|
|
2385
2376
|
returning_snippet = self._to_snippet(cfg_node=n)
|
|
2386
2377
|
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2378
|
+
self.kb.functions._add_call_to(
|
|
2379
|
+
src_function.addr,
|
|
2380
|
+
src_snippet,
|
|
2381
|
+
dst_addr,
|
|
2382
|
+
retn_node=returning_snippet,
|
|
2383
|
+
syscall=is_syscall,
|
|
2384
|
+
ins_addr=ins_addr,
|
|
2385
|
+
stmt_idx=stmt_idx,
|
|
2386
|
+
return_to_outside=return_to_outside,
|
|
2387
|
+
)
|
|
2388
|
+
|
|
2389
|
+
if returning_snippet is not None:
|
|
2390
|
+
self.kb.functions._add_fakeret_to(
|
|
2391
|
+
src_function.addr, src_snippet, returning_snippet, confirmed=True, to_outside=return_to_outside
|
|
2392
|
+
)
|
|
2391
2393
|
|
|
2392
2394
|
elif jumpkind in ("Ijk_Boring", "Ijk_InvalICache", "Ijk_Exception"):
|
|
2393
2395
|
# convert src_addr and dst_addr to CodeNodes
|
|
2394
|
-
n = self.model.get_any_node(src_addr)
|
|
2396
|
+
n = self.model.get_any_node(src_addr, force_fastpath=True)
|
|
2395
2397
|
src_node = src_addr if n is None else self._to_snippet(cfg_node=n)
|
|
2396
2398
|
|
|
2397
|
-
n = self.model.get_any_node(dst_addr)
|
|
2399
|
+
n = self.model.get_any_node(dst_addr, force_fastpath=True)
|
|
2398
2400
|
dst_node = dst_addr if n is None else self._to_snippet(cfg_node=n)
|
|
2399
2401
|
|
|
2400
2402
|
if self._skip_unmapped_addrs:
|
|
@@ -2460,10 +2462,10 @@ class CFGBase(Analysis):
|
|
|
2460
2462
|
|
|
2461
2463
|
elif jumpkind == "Ijk_FakeRet":
|
|
2462
2464
|
# convert src_addr and dst_addr to CodeNodes
|
|
2463
|
-
n = self.model.get_any_node(src_addr)
|
|
2465
|
+
n = self.model.get_any_node(src_addr, force_fastpath=True)
|
|
2464
2466
|
src_node = src_addr if n is None else self._to_snippet(n)
|
|
2465
2467
|
|
|
2466
|
-
n = self.model.get_any_node(dst_addr)
|
|
2468
|
+
n = self.model.get_any_node(dst_addr, force_fastpath=True)
|
|
2467
2469
|
dst_node = dst_addr if n is None else self._to_snippet(n)
|
|
2468
2470
|
|
|
2469
2471
|
if dst_addr not in blockaddr_to_function:
|
|
@@ -2083,7 +2083,7 @@ class CFGEmulated(ForwardAnalysis, CFGBase): # pylint: disable=abstract-method
|
|
|
2083
2083
|
if src_node_key is None:
|
|
2084
2084
|
if dst_node is None:
|
|
2085
2085
|
raise ValueError("Either src_node_key or dst_node_key must be specified.")
|
|
2086
|
-
self.kb.functions.function(dst_node.function_address, create=True).
|
|
2086
|
+
self.kb.functions.function(dst_node.function_address, create=True)._register_node(True, dst_codenode)
|
|
2087
2087
|
return
|
|
2088
2088
|
|
|
2089
2089
|
src_node = self._graph_get_node(src_node_key, terminator_for_nonexistent_node=True)
|
angr/analyses/cfg/cfg_fast.py
CHANGED
|
@@ -135,9 +135,9 @@ class PendingJobs:
|
|
|
135
135
|
A collection of pending jobs during CFG recovery.
|
|
136
136
|
"""
|
|
137
137
|
|
|
138
|
-
def __init__(self,
|
|
138
|
+
def __init__(self, kb, deregister_job_callback):
|
|
139
139
|
self._jobs = OrderedDict() # A mapping between function addresses and lists of pending jobs
|
|
140
|
-
self.
|
|
140
|
+
self._kb = kb
|
|
141
141
|
self._deregister_job_callback = deregister_job_callback
|
|
142
142
|
|
|
143
143
|
self._returning_functions = set()
|
|
@@ -145,6 +145,10 @@ class PendingJobs:
|
|
|
145
145
|
# consecutive calls to cleanup().
|
|
146
146
|
self._job_count = 0
|
|
147
147
|
|
|
148
|
+
@property
|
|
149
|
+
def _functions(self):
|
|
150
|
+
return self._kb.functions
|
|
151
|
+
|
|
148
152
|
def __len__(self):
|
|
149
153
|
return self._job_count
|
|
150
154
|
|
|
@@ -1316,7 +1320,7 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
|
|
|
1316
1320
|
self._known_thunks = self._find_thunks()
|
|
1317
1321
|
|
|
1318
1322
|
# Initialize variables used during analysis
|
|
1319
|
-
self._pending_jobs: PendingJobs = PendingJobs(self.
|
|
1323
|
+
self._pending_jobs: PendingJobs = PendingJobs(self.kb, self._deregister_analysis_job)
|
|
1320
1324
|
self._traced_addresses: set[int] = {a for a, n in self._nodes_by_addr.items() if n}
|
|
1321
1325
|
self._function_returns = defaultdict(set)
|
|
1322
1326
|
|
|
@@ -1498,6 +1502,18 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
|
|
|
1498
1502
|
pass
|
|
1499
1503
|
|
|
1500
1504
|
def _function_completed(self, func_addr: int):
|
|
1505
|
+
if self.project.arch.name == "AMD64":
|
|
1506
|
+
# determine if the function is __rust_probestack
|
|
1507
|
+
func = self.kb.functions.get_by_addr(func_addr) if self.kb.functions.contains_addr(func_addr) else None
|
|
1508
|
+
if func is not None and len(func.block_addrs_set) == 3:
|
|
1509
|
+
block_bytes = {func.get_block(block_addr).bytes for block_addr in func.block_addrs_set}
|
|
1510
|
+
if block_bytes == {
|
|
1511
|
+
b"UH\x89\xe5I\x89\xc3I\x81\xfb\x00\x10\x00\x00v\x1c",
|
|
1512
|
+
b"H\x81\xec\x00\x10\x00\x00H\x85d$\x08I\x81\xeb\x00\x10\x00\x00I\x81\xfb\x00\x10\x00\x00w\xe4",
|
|
1513
|
+
b"L)\xdcH\x85d$\x08H\x01\xc4\xc9\xc3",
|
|
1514
|
+
}:
|
|
1515
|
+
func.info["is_rust_probestack"] = True
|
|
1516
|
+
|
|
1501
1517
|
if self._collect_data_ref and self.project is not None and ":" in self.project.arch.name:
|
|
1502
1518
|
# this is a pcode arch - use Clinic to recover data references
|
|
1503
1519
|
|
|
@@ -1744,6 +1760,7 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
|
|
|
1744
1760
|
# Clean up
|
|
1745
1761
|
self._traced_addresses = None
|
|
1746
1762
|
self._lifter_deregister_readonly_regions()
|
|
1763
|
+
self._function_returns = None
|
|
1747
1764
|
|
|
1748
1765
|
self._finish_progress()
|
|
1749
1766
|
|
|
@@ -1825,19 +1842,18 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
|
|
|
1825
1842
|
break
|
|
1826
1843
|
|
|
1827
1844
|
# special handling: some binaries do not have SecurityCookie set, but still contain _security_init_cookie
|
|
1828
|
-
if security_init_cookie_found is False:
|
|
1845
|
+
if security_init_cookie_found is False and self.functions.contains_addr(self.project.entry):
|
|
1829
1846
|
start_func = self.functions.get_by_addr(self.project.entry)
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
break
|
|
1847
|
+
for callee in start_func.transition_graph:
|
|
1848
|
+
if (
|
|
1849
|
+
isinstance(callee, Function)
|
|
1850
|
+
and not security_init_cookie_found
|
|
1851
|
+
and is_function_likely_security_init_cookie(callee)
|
|
1852
|
+
):
|
|
1853
|
+
security_init_cookie_found = True
|
|
1854
|
+
callee.is_default_name = False
|
|
1855
|
+
callee.name = "_security_init_cookie"
|
|
1856
|
+
break
|
|
1841
1857
|
|
|
1842
1858
|
def _post_process_string_references(self) -> None:
|
|
1843
1859
|
"""
|
|
@@ -4765,6 +4781,37 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
|
|
|
4765
4781
|
func = self.kb.functions.get_by_addr(func_addr)
|
|
4766
4782
|
func.info["get_pc"] = "ebx"
|
|
4767
4783
|
|
|
4784
|
+
# determine if the function uses ebp as a general purpose register or not
|
|
4785
|
+
if addr == func_addr or 0 < addr - func_addr <= 0x20:
|
|
4786
|
+
ebp_as_gpr = True
|
|
4787
|
+
cap = self._lift(addr, size=cfg_node.size).capstone
|
|
4788
|
+
for insn in cap.insns:
|
|
4789
|
+
if (
|
|
4790
|
+
insn.mnemonic == "mov"
|
|
4791
|
+
and len(insn.operands) == 2
|
|
4792
|
+
and insn.operands[0].type == capstone.x86.X86_OP_REG
|
|
4793
|
+
and insn.operands[1].type == capstone.x86.X86_OP_REG
|
|
4794
|
+
):
|
|
4795
|
+
if (
|
|
4796
|
+
insn.operands[0].reg == capstone.x86.X86_REG_EBP
|
|
4797
|
+
and insn.operands[1].reg == capstone.x86.X86_REG_ESP
|
|
4798
|
+
):
|
|
4799
|
+
ebp_as_gpr = False
|
|
4800
|
+
break
|
|
4801
|
+
elif (
|
|
4802
|
+
insn.mnemonic == "lea"
|
|
4803
|
+
and len(insn.operands) == 2
|
|
4804
|
+
and insn.operands[0].type == capstone.x86.X86_OP_REG
|
|
4805
|
+
and insn.operands[1].type == capstone.x86.X86_OP_MEM
|
|
4806
|
+
) and (
|
|
4807
|
+
insn.operands[0].reg == capstone.x86.X86_REG_EBP
|
|
4808
|
+
and insn.operands[1].mem.base == capstone.x86.X86_REG_ESP
|
|
4809
|
+
):
|
|
4810
|
+
ebp_as_gpr = False
|
|
4811
|
+
break
|
|
4812
|
+
func = self.kb.functions.get_by_addr(func_addr)
|
|
4813
|
+
func.info["bp_as_gpr"] = ebp_as_gpr
|
|
4814
|
+
|
|
4768
4815
|
elif self.project.arch.name == "AMD64":
|
|
4769
4816
|
# determine if the function uses rbp as a general purpose register or not
|
|
4770
4817
|
if addr == func_addr or 0 < addr - func_addr <= 0x20:
|
|
@@ -50,7 +50,7 @@ class CFGFastSoot(CFGFast):
|
|
|
50
50
|
self._initialize_cfg()
|
|
51
51
|
|
|
52
52
|
# Initialize variables used during analysis
|
|
53
|
-
self._pending_jobs = PendingJobs(self.
|
|
53
|
+
self._pending_jobs = PendingJobs(self.kb, self._deregister_analysis_job)
|
|
54
54
|
self._traced_addresses = set()
|
|
55
55
|
self._changed_functions = set()
|
|
56
56
|
self._updated_nonreturning_functions = set()
|
|
@@ -9,6 +9,7 @@ from .amd64_elf_got import AMD64ElfGotResolver
|
|
|
9
9
|
from .arm_elf_fast import ArmElfFastResolver
|
|
10
10
|
from .const_resolver import ConstantResolver
|
|
11
11
|
from .amd64_pe_iat import AMD64PeIatResolver
|
|
12
|
+
from .memload_resolver import MemoryLoadResolver
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
__all__ = (
|
|
@@ -17,6 +18,7 @@ __all__ = (
|
|
|
17
18
|
"ArmElfFastResolver",
|
|
18
19
|
"ConstantResolver",
|
|
19
20
|
"JumpTableResolver",
|
|
21
|
+
"MemoryLoadResolver",
|
|
20
22
|
"MipsElfFastResolver",
|
|
21
23
|
"MipsElfGotResolver",
|
|
22
24
|
"X86ElfPicPltResolver",
|