angr 9.2.135__py3-none-win_amd64.whl → 9.2.136__py3-none-win_amd64.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.dll +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
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
# pylint:disable=too-many-boolean-expressions
|
|
1
2
|
from __future__ import annotations
|
|
2
3
|
import os
|
|
3
4
|
import logging
|
|
4
|
-
import networkx
|
|
5
5
|
import itertools
|
|
6
6
|
from collections import defaultdict
|
|
7
7
|
from collections.abc import Iterable
|
|
8
|
+
import contextlib
|
|
9
|
+
from typing import overload
|
|
8
10
|
|
|
11
|
+
import networkx
|
|
9
12
|
from itanium_demangler import parse
|
|
10
13
|
|
|
11
14
|
from cle.backends.symbol import Symbol
|
|
@@ -13,7 +16,6 @@ from archinfo.arch_arm import get_real_address_if_arm
|
|
|
13
16
|
import claripy
|
|
14
17
|
|
|
15
18
|
from angr.knowledge_plugins.cfg.memory_data import MemoryDataSort
|
|
16
|
-
|
|
17
19
|
from angr.codenode import CodeNode, BlockNode, HookNode, SyscallNode
|
|
18
20
|
from angr.serializable import Serializable
|
|
19
21
|
from angr.errors import AngrValueError, SimEngineError, SimMemoryError
|
|
@@ -22,14 +24,12 @@ from angr.procedures.definitions import SimSyscallLibrary
|
|
|
22
24
|
from angr.protos import function_pb2
|
|
23
25
|
from angr.calling_conventions import DEFAULT_CC, default_cc
|
|
24
26
|
from angr.misc.ux import deprecated
|
|
25
|
-
from .function_parser import FunctionParser
|
|
26
|
-
|
|
27
|
-
l = logging.getLogger(name=__name__)
|
|
28
|
-
|
|
29
27
|
from angr.sim_type import SimTypeFunction, parse_defns
|
|
30
28
|
from angr.calling_conventions import SimCC
|
|
31
29
|
from angr.project import Project
|
|
32
|
-
import
|
|
30
|
+
from .function_parser import FunctionParser
|
|
31
|
+
|
|
32
|
+
l = logging.getLogger(name=__name__)
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
class Function(Serializable):
|
|
@@ -41,7 +41,6 @@ class Function(Serializable):
|
|
|
41
41
|
"_addr_to_block_node",
|
|
42
42
|
"_argument_registers",
|
|
43
43
|
"_argument_stack_variables",
|
|
44
|
-
"_block_cache",
|
|
45
44
|
"_block_sizes",
|
|
46
45
|
"_call_sites",
|
|
47
46
|
"_callout_sites",
|
|
@@ -158,7 +157,6 @@ class Function(Serializable):
|
|
|
158
157
|
# function, it may not be removed from _addr_to_block_node. if you want to list
|
|
159
158
|
# all blocks of a function, access .blocks.
|
|
160
159
|
self._block_sizes = {} # map addresses to block sizes
|
|
161
|
-
self._block_cache = {} # a cache of real, hard data Block objects
|
|
162
160
|
self._local_blocks = {} # a dict of all blocks inside the function
|
|
163
161
|
self._local_block_addrs = set() # a set of addresses of all blocks inside the function
|
|
164
162
|
|
|
@@ -374,13 +372,6 @@ class Function(Serializable):
|
|
|
374
372
|
:param byte_string:
|
|
375
373
|
:return:
|
|
376
374
|
"""
|
|
377
|
-
if addr in self._block_cache:
|
|
378
|
-
b = self._block_cache[addr]
|
|
379
|
-
if size is None or b.size == size:
|
|
380
|
-
return b
|
|
381
|
-
# size seems to be updated. remove this cached entry from the block cache
|
|
382
|
-
del self._block_cache[addr]
|
|
383
|
-
|
|
384
375
|
if size is None and addr in self.block_addrs:
|
|
385
376
|
# we know the size
|
|
386
377
|
size = self._block_sizes[addr]
|
|
@@ -389,7 +380,6 @@ class Function(Serializable):
|
|
|
389
380
|
if size is None:
|
|
390
381
|
# update block_size dict
|
|
391
382
|
self._block_sizes[addr] = block.size
|
|
392
|
-
self._block_cache[addr] = block
|
|
393
383
|
return block
|
|
394
384
|
|
|
395
385
|
# compatibility
|
|
@@ -440,7 +430,7 @@ class Function(Serializable):
|
|
|
440
430
|
|
|
441
431
|
@classmethod
|
|
442
432
|
def _get_cmsg(cls):
|
|
443
|
-
return function_pb2.Function()
|
|
433
|
+
return function_pb2.Function() # pylint:disable=no-member
|
|
444
434
|
|
|
445
435
|
def serialize_to_cmessage(self):
|
|
446
436
|
return FunctionParser.serialize(self)
|
|
@@ -613,7 +603,6 @@ class Function(Serializable):
|
|
|
613
603
|
d["_local_transition_graph"] = None
|
|
614
604
|
d["_project"] = None
|
|
615
605
|
d["_function_manager"] = None
|
|
616
|
-
d["_block_cache"] = {}
|
|
617
606
|
return d
|
|
618
607
|
|
|
619
608
|
@property
|
|
@@ -642,7 +631,7 @@ class Function(Serializable):
|
|
|
642
631
|
|
|
643
632
|
@property
|
|
644
633
|
def size(self):
|
|
645
|
-
return sum(
|
|
634
|
+
return sum(b.size for b in self.blocks)
|
|
646
635
|
|
|
647
636
|
@property
|
|
648
637
|
def binary(self):
|
|
@@ -675,7 +664,7 @@ class Function(Serializable):
|
|
|
675
664
|
dec = self.project.analyses.Decompiler(self, cfg=self._function_manager._kb.cfgs.get_most_accurate())
|
|
676
665
|
return dec.codegen.text
|
|
677
666
|
|
|
678
|
-
def add_jumpout_site(self, node):
|
|
667
|
+
def add_jumpout_site(self, node: CodeNode):
|
|
679
668
|
"""
|
|
680
669
|
Add a custom jumpout site.
|
|
681
670
|
|
|
@@ -683,11 +672,11 @@ class Function(Serializable):
|
|
|
683
672
|
:return: None
|
|
684
673
|
"""
|
|
685
674
|
|
|
686
|
-
self.
|
|
675
|
+
node = self._register_node(True, node)
|
|
687
676
|
self._jumpout_sites.add(node)
|
|
688
677
|
self._add_endpoint(node, "transition")
|
|
689
678
|
|
|
690
|
-
def add_retout_site(self, node):
|
|
679
|
+
def add_retout_site(self, node: CodeNode):
|
|
691
680
|
"""
|
|
692
681
|
Add a custom retout site.
|
|
693
682
|
|
|
@@ -703,7 +692,7 @@ class Function(Serializable):
|
|
|
703
692
|
:return: None
|
|
704
693
|
"""
|
|
705
694
|
|
|
706
|
-
self.
|
|
695
|
+
node = self._register_node(True, node)
|
|
707
696
|
self._retout_sites.add(node)
|
|
708
697
|
self._add_endpoint(node, "return")
|
|
709
698
|
|
|
@@ -785,7 +774,6 @@ class Function(Serializable):
|
|
|
785
774
|
return None
|
|
786
775
|
|
|
787
776
|
def _clear_transition_graph(self):
|
|
788
|
-
self._block_cache = {}
|
|
789
777
|
self._block_sizes = {}
|
|
790
778
|
self._addr_to_block_node = {}
|
|
791
779
|
self._local_blocks = {}
|
|
@@ -812,11 +800,13 @@ class Function(Serializable):
|
|
|
812
800
|
|
|
813
801
|
# it's confirmed. register the node if needed
|
|
814
802
|
if "outside" not in data or data["outside"] is False:
|
|
815
|
-
self.
|
|
803
|
+
dst = self._register_node(True, dst)
|
|
816
804
|
|
|
817
805
|
self.transition_graph[src][dst]["confirmed"] = True
|
|
818
806
|
|
|
819
|
-
def _transit_to(
|
|
807
|
+
def _transit_to(
|
|
808
|
+
self, from_node: CodeNode, to_node, outside=False, ins_addr=None, stmt_idx=None, is_exception=False
|
|
809
|
+
):
|
|
820
810
|
"""
|
|
821
811
|
Registers an edge between basic blocks in this function's transition graph.
|
|
822
812
|
Arguments are CodeNode objects.
|
|
@@ -830,16 +820,15 @@ class Function(Serializable):
|
|
|
830
820
|
"""
|
|
831
821
|
|
|
832
822
|
if outside:
|
|
833
|
-
self.
|
|
823
|
+
from_node = self._register_node(True, from_node)
|
|
834
824
|
if to_node is not None:
|
|
835
|
-
self.
|
|
825
|
+
to_node = self._register_node(False, to_node)
|
|
836
826
|
|
|
837
827
|
self._jumpout_sites.add(from_node)
|
|
838
828
|
else:
|
|
829
|
+
from_node = self._register_node(True, from_node)
|
|
839
830
|
if to_node is not None:
|
|
840
|
-
self.
|
|
841
|
-
else:
|
|
842
|
-
self._register_nodes(True, from_node)
|
|
831
|
+
to_node = self._register_node(True, to_node)
|
|
843
832
|
|
|
844
833
|
type_ = "transition" if not is_exception else "exception"
|
|
845
834
|
if to_node is not None:
|
|
@@ -871,19 +860,22 @@ class Function(Serializable):
|
|
|
871
860
|
:type ins_addr: int or None
|
|
872
861
|
"""
|
|
873
862
|
|
|
874
|
-
self.
|
|
863
|
+
from_node = self._register_node(True, from_node)
|
|
875
864
|
|
|
876
865
|
if to_func.is_syscall:
|
|
877
866
|
self.transition_graph.add_edge(from_node, to_func, type="syscall", stmt_idx=stmt_idx, ins_addr=ins_addr)
|
|
878
867
|
else:
|
|
879
868
|
self.transition_graph.add_edge(from_node, to_func, type="call", stmt_idx=stmt_idx, ins_addr=ins_addr)
|
|
880
869
|
if ret_node is not None:
|
|
870
|
+
ret_node = self._register_node(return_to_outside is False, ret_node)
|
|
881
871
|
self._fakeret_to(from_node, ret_node, to_outside=return_to_outside)
|
|
882
872
|
|
|
883
873
|
self._local_transition_graph = None
|
|
884
874
|
|
|
885
875
|
def _fakeret_to(self, from_node, to_node, confirmed=None, to_outside=False):
|
|
886
|
-
self.
|
|
876
|
+
from_node = self._register_node(True, from_node)
|
|
877
|
+
if confirmed:
|
|
878
|
+
to_node = self._register_node(not to_outside, to_node)
|
|
887
879
|
|
|
888
880
|
if confirmed is None:
|
|
889
881
|
self.transition_graph.add_edge(from_node, to_node, type="fake_return", outside=to_outside)
|
|
@@ -891,8 +883,6 @@ class Function(Serializable):
|
|
|
891
883
|
self.transition_graph.add_edge(
|
|
892
884
|
from_node, to_node, type="fake_return", confirmed=confirmed, outside=to_outside
|
|
893
885
|
)
|
|
894
|
-
if confirmed:
|
|
895
|
-
self._register_nodes(not to_outside, to_node)
|
|
896
886
|
|
|
897
887
|
self._local_transition_graph = None
|
|
898
888
|
|
|
@@ -910,45 +900,56 @@ class Function(Serializable):
|
|
|
910
900
|
self._local_transition_graph = None
|
|
911
901
|
|
|
912
902
|
def _update_local_blocks(self, node: CodeNode):
|
|
913
|
-
self._local_blocks[node.addr]
|
|
914
|
-
|
|
903
|
+
if node.addr not in self._local_blocks or self._local_blocks[node.addr] != node:
|
|
904
|
+
self._local_blocks[node.addr] = node
|
|
905
|
+
self._local_block_addrs.add(node.addr)
|
|
915
906
|
|
|
916
907
|
def _update_addr_to_block_cache(self, node: BlockNode):
|
|
917
908
|
if node.addr not in self._addr_to_block_node:
|
|
918
909
|
self._addr_to_block_node[node.addr] = node
|
|
919
910
|
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
911
|
+
@overload
|
|
912
|
+
def _register_node(self, is_local: bool, node: CodeNode) -> CodeNode: ...
|
|
913
|
+
|
|
914
|
+
@overload
|
|
915
|
+
def _register_node(self, is_local: bool, node: Function) -> Function: ...
|
|
916
|
+
|
|
917
|
+
def _register_node(self, is_local: bool, node: CodeNode | Function) -> CodeNode | Function:
|
|
918
|
+
# if the node already exists and is the same, we reuse the existing node
|
|
919
|
+
if is_local and self._local_blocks.get(node.addr, None) == node:
|
|
920
|
+
return self._local_blocks[node.addr]
|
|
921
|
+
|
|
922
|
+
if node.addr not in self and node not in self.transition_graph:
|
|
923
|
+
# only add each node to the graph once
|
|
924
|
+
self.transition_graph.add_node(node)
|
|
925
|
+
|
|
926
|
+
if not isinstance(node, CodeNode):
|
|
927
|
+
# function and other things bail here
|
|
928
|
+
return node
|
|
929
|
+
|
|
930
|
+
# this is either a new node or a different node at the same address
|
|
931
|
+
node._graph = self.transition_graph
|
|
932
|
+
if self._block_sizes.get(node.addr, 0) == 0:
|
|
933
|
+
self._block_sizes[node.addr] = node.size
|
|
934
|
+
if node.addr == self.addr and (self.startpoint is None or not self.startpoint.is_hook):
|
|
935
|
+
self.startpoint = node
|
|
936
|
+
if is_local and node.addr not in self._local_blocks:
|
|
937
|
+
self._update_local_blocks(node)
|
|
938
|
+
# add BlockNodes to the addr_to_block_node cache if not already there
|
|
939
|
+
if isinstance(node, BlockNode):
|
|
940
|
+
self._update_addr_to_block_cache(node)
|
|
941
|
+
# else:
|
|
942
|
+
# # checks that we don't have multiple block nodes at a single address
|
|
943
|
+
# assert node == self._addr_to_block_node[node.addr]
|
|
944
|
+
return node
|
|
945
|
+
|
|
946
|
+
def _add_return_site(self, return_site: CodeNode):
|
|
946
947
|
"""
|
|
947
948
|
Registers a basic block as a site for control flow to return from this function.
|
|
948
949
|
|
|
949
|
-
:param
|
|
950
|
+
:param return_site: The block node that ends with a return.
|
|
950
951
|
"""
|
|
951
|
-
self.
|
|
952
|
+
return_site = self._register_node(True, return_site)
|
|
952
953
|
|
|
953
954
|
self._ret_sites.add(return_site)
|
|
954
955
|
# A return site must be an endpoint of the function - you cannot continue execution of the current function
|
|
@@ -1285,8 +1286,8 @@ class Function(Serializable):
|
|
|
1285
1286
|
"""
|
|
1286
1287
|
Draw the graph and save it to a PNG file.
|
|
1287
1288
|
"""
|
|
1288
|
-
import matplotlib.pyplot as pyplot # pylint: disable=import-error
|
|
1289
|
-
from networkx.drawing.nx_agraph import graphviz_layout # pylint: disable=import-error
|
|
1289
|
+
import matplotlib.pyplot as pyplot # pylint: disable=import-error,import-outside-toplevel
|
|
1290
|
+
from networkx.drawing.nx_agraph import graphviz_layout # pylint: disable=import-error,import-outside-toplevel
|
|
1290
1291
|
|
|
1291
1292
|
tmp_graph = networkx.classes.digraph.DiGraph()
|
|
1292
1293
|
for from_block, to_block in self.transition_graph.edges():
|
|
@@ -1416,11 +1417,8 @@ class Function(Serializable):
|
|
|
1416
1417
|
self._local_blocks[n.addr] = new_node
|
|
1417
1418
|
|
|
1418
1419
|
# update block_cache and block_sizes
|
|
1419
|
-
if
|
|
1420
|
-
n.addr in self._block_sizes and self._block_sizes[n.addr] != new_node.size
|
|
1421
|
-
):
|
|
1420
|
+
if n.addr in self._block_sizes and self._block_sizes[n.addr] != new_node.size:
|
|
1422
1421
|
# the cache needs updating
|
|
1423
|
-
self._block_cache.pop(n.addr, None)
|
|
1424
1422
|
self._block_sizes[n.addr] = new_node.size
|
|
1425
1423
|
|
|
1426
1424
|
for p, _, data in original_predecessors:
|
|
@@ -1680,7 +1678,6 @@ class Function(Serializable):
|
|
|
1680
1678
|
func.startpoint = self.startpoint
|
|
1681
1679
|
func._addr_to_block_node = self._addr_to_block_node.copy()
|
|
1682
1680
|
func._block_sizes = self._block_sizes.copy()
|
|
1683
|
-
func._block_cache = self._block_cache.copy()
|
|
1684
1681
|
func._local_blocks = self._local_blocks.copy()
|
|
1685
1682
|
func._local_block_addrs = self._local_block_addrs.copy()
|
|
1686
1683
|
func.info = self.info.copy()
|
|
@@ -6,6 +6,7 @@ from collections.abc import Generator
|
|
|
6
6
|
import logging
|
|
7
7
|
import collections.abc
|
|
8
8
|
import re
|
|
9
|
+
import weakref
|
|
9
10
|
from sortedcontainers import SortedDict
|
|
10
11
|
|
|
11
12
|
import networkx
|
|
@@ -31,7 +32,7 @@ class FunctionDict(SortedDict):
|
|
|
31
32
|
"""
|
|
32
33
|
|
|
33
34
|
def __init__(self, backref, *args, **kwargs):
|
|
34
|
-
self._backref = backref
|
|
35
|
+
self._backref = weakref.proxy(backref) if backref is not None else None
|
|
35
36
|
self._key_types = kwargs.pop("key_types", int)
|
|
36
37
|
super().__init__(*args, **kwargs)
|
|
37
38
|
|
|
@@ -39,7 +40,7 @@ class FunctionDict(SortedDict):
|
|
|
39
40
|
try:
|
|
40
41
|
return super().__getitem__(addr)
|
|
41
42
|
except KeyError as ex:
|
|
42
|
-
if not isinstance(addr, self._key_types):
|
|
43
|
+
if isinstance(addr, bool) or not isinstance(addr, self._key_types):
|
|
43
44
|
raise TypeError(f"FunctionDict only supports {self._key_types} as key type") from ex
|
|
44
45
|
|
|
45
46
|
if isinstance(addr, SootMethodDescriptor):
|
|
@@ -148,7 +149,7 @@ class FunctionManager(KnowledgeBasePlugin, collections.abc.Mapping):
|
|
|
148
149
|
dst_func = self._function_map[function_addr]
|
|
149
150
|
if syscall in (True, False):
|
|
150
151
|
dst_func.is_syscall = syscall
|
|
151
|
-
dst_func.
|
|
152
|
+
dst_func._register_node(True, node)
|
|
152
153
|
self.block_map[node.addr] = node
|
|
153
154
|
|
|
154
155
|
def _add_call_to(
|
|
@@ -160,7 +161,7 @@ class FunctionManager(KnowledgeBasePlugin, collections.abc.Mapping):
|
|
|
160
161
|
syscall=None,
|
|
161
162
|
stmt_idx=None,
|
|
162
163
|
ins_addr=None,
|
|
163
|
-
return_to_outside=False,
|
|
164
|
+
return_to_outside: bool = False,
|
|
164
165
|
):
|
|
165
166
|
"""
|
|
166
167
|
Add a call to a function.
|
|
@@ -172,7 +173,7 @@ class FunctionManager(KnowledgeBasePlugin, collections.abc.Mapping):
|
|
|
172
173
|
:param bool syscall: If this is a call to a syscall or not.
|
|
173
174
|
:param int stmt_idx: ID of the statement where this call happens.
|
|
174
175
|
:param int ins_addr: Address of the instruction where this call happens.
|
|
175
|
-
:param
|
|
176
|
+
:param return_to_outside: True if the return of the call is considered going to outside of the current
|
|
176
177
|
function.
|
|
177
178
|
:return: None
|
|
178
179
|
"""
|
|
@@ -306,7 +307,7 @@ class FunctionManager(KnowledgeBasePlugin, collections.abc.Mapping):
|
|
|
306
307
|
try:
|
|
307
308
|
_ = self[item]
|
|
308
309
|
return True
|
|
309
|
-
except KeyError:
|
|
310
|
+
except (KeyError, TypeError):
|
|
310
311
|
return False
|
|
311
312
|
|
|
312
313
|
def __getitem__(self, k) -> Function:
|
|
@@ -406,7 +407,7 @@ class FunctionManager(KnowledgeBasePlugin, collections.abc.Mapping):
|
|
|
406
407
|
|
|
407
408
|
try:
|
|
408
409
|
prev_addr = self._function_map.floor_addr(addr)
|
|
409
|
-
return self._function_map
|
|
410
|
+
return self._function_map.get(prev_addr)
|
|
410
411
|
|
|
411
412
|
except KeyError:
|
|
412
413
|
return None
|
|
@@ -108,24 +108,24 @@ class SootFunction(Function):
|
|
|
108
108
|
# The Shimple CFG is already normalized.
|
|
109
109
|
pass
|
|
110
110
|
|
|
111
|
-
def
|
|
112
|
-
if
|
|
113
|
-
|
|
111
|
+
def _register_node(self, is_local: bool, node):
|
|
112
|
+
if is_local and self._local_blocks.get(node.addr) == node:
|
|
113
|
+
return self._local_blocks[node.addr]
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
if node not in self.transition_graph:
|
|
116
116
|
self.transition_graph.add_node(node)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
117
|
+
node._graph = self.transition_graph
|
|
118
|
+
if node.addr not in self or self._block_sizes[node.addr] == 0:
|
|
119
|
+
self._block_sizes[node.addr] = node.size
|
|
120
|
+
if node.addr == self.addr.addr and (self.startpoint is None or not self.startpoint.is_hook):
|
|
121
|
+
self.startpoint = node
|
|
122
|
+
if is_local:
|
|
123
|
+
self._local_blocks[node.addr] = node
|
|
124
|
+
self._local_block_addrs.add(node.addr)
|
|
125
|
+
# add BlockNodes to the addr_to_block_node cache if not already there
|
|
126
|
+
if isinstance(node, BlockNode) and node.addr not in self._addr_to_block_node:
|
|
127
|
+
self._addr_to_block_node[node.addr] = node
|
|
128
|
+
return node
|
|
128
129
|
|
|
129
130
|
|
|
130
131
|
from angr.codenode import BlockNode
|
|
131
|
-
from angr.errors import AngrValueError
|
|
@@ -6,7 +6,7 @@ import claripy
|
|
|
6
6
|
import ailment
|
|
7
7
|
from angr.serializable import Serializable
|
|
8
8
|
from angr.knowledge_plugins.functions.function import Function
|
|
9
|
-
from .states import PropagatorVEXState,
|
|
9
|
+
from .states import PropagatorVEXState, PropagatorState
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class PropagationModel(Serializable):
|
|
@@ -65,10 +65,9 @@ class PropagationModel(Serializable):
|
|
|
65
65
|
preds = [self.states[pnode.addr] for pnode in self._function.graph.predecessors(node)]
|
|
66
66
|
if not preds:
|
|
67
67
|
if isinstance(node, ailment.Block):
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
state.store_register(state.arch.ip_offset, state.arch.bytes, claripy.BVV(block_addr, state.arch.bits))
|
|
68
|
+
raise NotImplementedError
|
|
69
|
+
state = PropagatorVEXState.initial_state(self._function.project, func_addr=self._function.addr)
|
|
70
|
+
state.store_register(state.arch.ip_offset, state.arch.bytes, claripy.BVV(block_addr, state.arch.bits))
|
|
72
71
|
else:
|
|
73
72
|
state, _ = preds[0].merge(*preds[1:])
|
|
74
73
|
return state
|