angr 9.2.87__py3-none-manylinux2014_x86_64.whl → 9.2.89__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 +4 -1
- angr/analyses/decompiler/clinic.py +16 -0
- angr/analyses/decompiler/decompiler.py +3 -0
- angr/analyses/decompiler/optimization_passes/__init__.py +5 -0
- angr/analyses/decompiler/optimization_passes/cross_jump_reverter.py +108 -0
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +17 -4
- angr/analyses/decompiler/optimization_passes/return_duplicator.py +4 -32
- angr/analyses/decompiler/structured_codegen/c.py +12 -2
- angr/analyses/decompiler/utils.py +13 -0
- angr/analyses/typehoon/dfa.py +108 -0
- angr/analyses/typehoon/lifter.py +34 -2
- angr/analyses/typehoon/simple_solver.py +1043 -503
- angr/analyses/typehoon/translator.py +13 -4
- angr/analyses/typehoon/typeconsts.py +117 -36
- angr/analyses/typehoon/typehoon.py +31 -11
- angr/analyses/typehoon/typevars.py +88 -21
- angr/analyses/typehoon/variance.py +10 -0
- angr/analyses/variable_recovery/engine_ail.py +28 -9
- angr/analyses/variable_recovery/engine_base.py +50 -43
- angr/analyses/variable_recovery/variable_recovery_base.py +16 -3
- angr/analyses/variable_recovery/variable_recovery_fast.py +14 -5
- angr/exploration_techniques/tracer.py +2 -0
- angr/misc/autoimport.py +26 -0
- angr/procedures/definitions/__init__.py +32 -3
- angr/utils/constants.py +1 -0
- angr/utils/graph.py +20 -1
- {angr-9.2.87.dist-info → angr-9.2.89.dist-info}/METADATA +7 -6
- {angr-9.2.87.dist-info → angr-9.2.89.dist-info}/RECORD +32 -244
- angr-9.2.89.dist-info/top_level.txt +1 -0
- angr/procedures/definitions/ntdll.py +0 -12
- angr-9.2.87.dist-info/top_level.txt +0 -2
- tests/__init__.py +0 -0
- tests/analyses/__init__.py +0 -0
- tests/analyses/cfg/__init__.py +0 -0
- tests/analyses/cfg/test_cfg_clflush.py +0 -43
- tests/analyses/cfg/test_cfg_get_any_node.py +0 -34
- tests/analyses/cfg/test_cfg_manager.py +0 -32
- tests/analyses/cfg/test_cfg_model.py +0 -55
- tests/analyses/cfg/test_cfg_patching.py +0 -378
- tests/analyses/cfg/test_cfg_rust_got_resolution.py +0 -36
- tests/analyses/cfg/test_cfg_thumb_firmware.py +0 -50
- tests/analyses/cfg/test_cfg_vex_postprocessor.py +0 -27
- tests/analyses/cfg/test_cfgemulated.py +0 -634
- tests/analyses/cfg/test_cfgfast.py +0 -1123
- tests/analyses/cfg/test_cfgfast_soot.py +0 -38
- tests/analyses/cfg/test_const_resolver.py +0 -38
- tests/analyses/cfg/test_iat_resolver.py +0 -37
- tests/analyses/cfg/test_jumptables.py +0 -3008
- tests/analyses/cfg/test_noop_blocks.py +0 -54
- tests/analyses/cfg_slice_to_sink/__init__.py +0 -0
- tests/analyses/cfg_slice_to_sink/test_cfg_slice_to_sink.py +0 -93
- tests/analyses/cfg_slice_to_sink/test_graph.py +0 -114
- tests/analyses/cfg_slice_to_sink/test_transitions.py +0 -28
- tests/analyses/decompiler/__init__.py +0 -0
- tests/analyses/decompiler/test_baseptr_save_simplifier.py +0 -80
- tests/analyses/decompiler/test_decompiler.py +0 -3336
- tests/analyses/decompiler/test_peephole_optimizations.py +0 -48
- tests/analyses/decompiler/test_propagator_loops.py +0 -101
- tests/analyses/decompiler/test_structurer.py +0 -275
- tests/analyses/reaching_definitions/__init__.py +0 -0
- tests/analyses/reaching_definitions/test_dep_graph.py +0 -432
- tests/analyses/reaching_definitions/test_function_handler.py +0 -131
- tests/analyses/reaching_definitions/test_heap_allocator.py +0 -46
- tests/analyses/reaching_definitions/test_rd_state.py +0 -78
- tests/analyses/reaching_definitions/test_reachingdefinitions.py +0 -463
- tests/analyses/reaching_definitions/test_subject.py +0 -76
- tests/analyses/test_bindiff.py +0 -52
- tests/analyses/test_block_simplifier.py +0 -112
- tests/analyses/test_boyscout.py +0 -104
- tests/analyses/test_calling_convention_analysis.py +0 -352
- tests/analyses/test_callsite_maker.py +0 -60
- tests/analyses/test_cdg.py +0 -165
- tests/analyses/test_cfb.py +0 -37
- tests/analyses/test_class_identifier.py +0 -46
- tests/analyses/test_clinic.py +0 -30
- tests/analyses/test_codetagging.py +0 -32
- tests/analyses/test_constantpropagation.py +0 -88
- tests/analyses/test_ddg.py +0 -95
- tests/analyses/test_ddg_global_var_dependencies.py +0 -83
- tests/analyses/test_ddg_memvar_addresses.py +0 -40
- tests/analyses/test_disassembly.py +0 -121
- tests/analyses/test_find_objects_static.py +0 -35
- tests/analyses/test_flirt.py +0 -49
- tests/analyses/test_identifier.py +0 -33
- tests/analyses/test_init_finder.py +0 -38
- tests/analyses/test_proximitygraph.py +0 -31
- tests/analyses/test_reassembler.py +0 -295
- tests/analyses/test_regionidentifier.py +0 -27
- tests/analyses/test_slicing.py +0 -164
- tests/analyses/test_stack_pointer_tracker.py +0 -74
- tests/analyses/test_static_hooker.py +0 -28
- tests/analyses/test_typehoon.py +0 -55
- tests/analyses/test_variablerecovery.py +0 -464
- tests/analyses/test_vfg.py +0 -221
- tests/analyses/test_vtable.py +0 -31
- tests/analyses/test_xrefs.py +0 -77
- tests/common.py +0 -128
- tests/engines/__init__.py +0 -0
- tests/engines/light/__init__.py +0 -0
- tests/engines/light/test_data.py +0 -17
- tests/engines/pcode/__init__.py +0 -0
- tests/engines/pcode/test_emulate.py +0 -607
- tests/engines/pcode/test_pcode.py +0 -84
- tests/engines/test_actions.py +0 -27
- tests/engines/test_hook.py +0 -112
- tests/engines/test_java.py +0 -697
- tests/engines/test_unicorn.py +0 -518
- tests/engines/vex/__init__.py +0 -0
- tests/engines/vex/test_lifter.py +0 -124
- tests/engines/vex/test_vex.py +0 -574
- tests/exploration_techniques/__init__.py +0 -0
- tests/exploration_techniques/test_cacher.py +0 -45
- tests/exploration_techniques/test_director.py +0 -67
- tests/exploration_techniques/test_driller_core.py +0 -48
- tests/exploration_techniques/test_loop_seer.py +0 -158
- tests/exploration_techniques/test_memory_watcher.py +0 -46
- tests/exploration_techniques/test_oppologist.py +0 -65
- tests/exploration_techniques/test_spiller.py +0 -82
- tests/exploration_techniques/test_stochastic.py +0 -40
- tests/exploration_techniques/test_tech_builder.py +0 -61
- tests/exploration_techniques/test_tracer.py +0 -856
- tests/exploration_techniques/test_unique.py +0 -40
- tests/exploration_techniques/test_veritesting.py +0 -120
- tests/factory/__init__.py +0 -0
- tests/factory/block/__init__.py +0 -0
- tests/factory/block/test_block_cache.py +0 -33
- tests/factory/block/test_keystone.py +0 -106
- tests/factory/test_argc.py +0 -101
- tests/factory/test_argc_sym.py +0 -110
- tests/factory/test_argv.py +0 -158
- tests/factory/test_callable.py +0 -266
- tests/factory/test_windows_args.py +0 -36
- tests/knowledge_plugins/__init__.py +0 -0
- tests/knowledge_plugins/cfg/__init__.py +0 -0
- tests/knowledge_plugins/cfg/test_cfg_manager.py +0 -36
- tests/knowledge_plugins/functions/__init__.py +0 -0
- tests/knowledge_plugins/functions/test_function.py +0 -91
- tests/knowledge_plugins/functions/test_function2.py +0 -79
- tests/knowledge_plugins/functions/test_function_manager.py +0 -139
- tests/knowledge_plugins/functions/test_prototypes.py +0 -53
- tests/knowledge_plugins/key_definitions/__init__.py +0 -0
- tests/knowledge_plugins/key_definitions/test_atoms.py +0 -24
- tests/knowledge_plugins/key_definitions/test_environment.py +0 -126
- tests/knowledge_plugins/key_definitions/test_heap_address.py +0 -27
- tests/knowledge_plugins/key_definitions/test_live_definitions.py +0 -72
- tests/knowledge_plugins/test_dwarf_variables.py +0 -240
- tests/knowledge_plugins/test_kb_plugins.py +0 -91
- tests/knowledge_plugins/test_kb_plugins_dwarf.py +0 -36
- tests/knowledge_plugins/test_patches.py +0 -48
- tests/misc/__init__.py +0 -0
- tests/misc/test_hookset.py +0 -57
- tests/perf/__init__.py +0 -0
- tests/perf/perf_cfgemulated.py +0 -19
- tests/perf/perf_cfgfast.py +0 -18
- tests/perf/perf_concrete_execution.py +0 -41
- tests/perf/perf_siminspect_nop.py +0 -36
- tests/perf/perf_state_copy.py +0 -33
- tests/perf/perf_unicorn_0.py +0 -27
- tests/perf/perf_unicorn_1.py +0 -23
- tests/procedures/__init__.py +0 -0
- tests/procedures/glibc/__init__.py +0 -0
- tests/procedures/glibc/test_ctype_locale.py +0 -164
- tests/procedures/libc/__init__.py +0 -0
- tests/procedures/libc/test_fgets.py +0 -53
- tests/procedures/libc/test_scanf.py +0 -205
- tests/procedures/libc/test_sprintf.py +0 -44
- tests/procedures/libc/test_sscanf.py +0 -63
- tests/procedures/libc/test_strcasecmp.py +0 -37
- tests/procedures/libc/test_string.py +0 -1102
- tests/procedures/libc/test_strtol.py +0 -78
- tests/procedures/linux_kernel/__init__.py +0 -0
- tests/procedures/linux_kernel/test_lseek.py +0 -174
- tests/procedures/posix/__init__.py +0 -0
- tests/procedures/posix/test_chroot.py +0 -33
- tests/procedures/posix/test_getenv.py +0 -78
- tests/procedures/posix/test_pwrite_pread.py +0 -57
- tests/procedures/posix/test_sim_time.py +0 -46
- tests/procedures/posix/test_unlink.py +0 -46
- tests/procedures/test_project_resolve_simproc.py +0 -43
- tests/procedures/test_sim_procedure.py +0 -117
- tests/procedures/test_stub_procedure_args.py +0 -53
- tests/serialization/__init__.py +0 -0
- tests/serialization/test_db.py +0 -197
- tests/serialization/test_pickle.py +0 -95
- tests/serialization/test_serialization.py +0 -132
- tests/serialization/test_vault.py +0 -169
- tests/sim/__init__.py +0 -3
- tests/sim/exec_func/__init__.py +0 -0
- tests/sim/exec_func/test_mem_funcs.py +0 -55
- tests/sim/exec_func/test_str_funcs.py +0 -93
- tests/sim/exec_func/test_syscall_result.py +0 -39
- tests/sim/exec_insn/__init__.py +0 -0
- tests/sim/exec_insn/test_adc.py +0 -44
- tests/sim/exec_insn/test_ops.py +0 -83
- tests/sim/exec_insn/test_rcr.py +0 -26
- tests/sim/exec_insn/test_rol.py +0 -51
- tests/sim/exec_insn/test_signed_div.py +0 -34
- tests/sim/exec_insn/test_sqrt.py +0 -56
- tests/sim/options/__init__.py +0 -0
- tests/sim/options/test_0div.py +0 -54
- tests/sim/options/test_symbolic_fd.py +0 -59
- tests/sim/options/test_unsupported.py +0 -34
- tests/sim/test_accuracy.py +0 -137
- tests/sim/test_checkbyte.py +0 -53
- tests/sim/test_echo.py +0 -36
- tests/sim/test_fauxware.py +0 -202
- tests/sim/test_self_modifying_code.py +0 -65
- tests/sim/test_simple_api.py +0 -36
- tests/sim/test_simulation_manager.py +0 -147
- tests/sim/test_stack_alignment.py +0 -65
- tests/sim/test_state.py +0 -303
- tests/sim/test_state_customization.py +0 -54
- tests/sim/test_symbol_hooked_by.py +0 -49
- tests/simos/__init__.py +0 -0
- tests/simos/windows/__init__.py +0 -0
- tests/simos/windows/test_windows_stack_cookie.py +0 -58
- tests/state_plugins/__init__.py +0 -0
- tests/state_plugins/inspect/__init__.py +0 -0
- tests/state_plugins/inspect/test_inspect.py +0 -310
- tests/state_plugins/inspect/test_syscall_override.py +0 -90
- tests/state_plugins/posix/__init__.py +0 -0
- tests/state_plugins/posix/test_file_struct_funcs.py +0 -56
- tests/state_plugins/posix/test_files.py +0 -69
- tests/state_plugins/posix/test_posix.py +0 -72
- tests/state_plugins/solver/__init__.py +0 -0
- tests/state_plugins/solver/test_simsolver.py +0 -58
- tests/state_plugins/solver/test_symbolic.py +0 -153
- tests/state_plugins/solver/test_variable_registration.py +0 -46
- tests/state_plugins/test_callstack.py +0 -54
- tests/state_plugins/test_gdb_plugin.py +0 -35
- tests/state_plugins/test_multi_open_file.py +0 -47
- tests/state_plugins/test_symbolization.py +0 -38
- tests/storage/__init__.py +0 -0
- tests/storage/test_memory.py +0 -960
- tests/storage/test_memory_merge.py +0 -114
- tests/storage/test_memview.py +0 -205
- tests/storage/test_mmap.py +0 -26
- tests/storage/test_multivalues.py +0 -44
- tests/storage/test_permissions.py +0 -32
- tests/storage/test_ptmalloc.py +0 -291
- tests/storage/test_relro_perm.py +0 -49
- tests/test_calling_conventions.py +0 -86
- tests/test_types.py +0 -329
- tests/utils/__init__.py +0 -0
- tests/utils/test_graph.py +0 -41
- {angr-9.2.87.dist-info → angr-9.2.89.dist-info}/LICENSE +0 -0
- {angr-9.2.87.dist-info → angr-9.2.89.dist-info}/WHEEL +0 -0
- {angr-9.2.87.dist-info → angr-9.2.89.dist-info}/entry_points.txt +0 -0
|
@@ -1,432 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# pylint: disable=no-self-use
|
|
3
|
-
from random import randrange
|
|
4
|
-
from unittest import main, mock, TestCase
|
|
5
|
-
import networkx
|
|
6
|
-
|
|
7
|
-
import claripy
|
|
8
|
-
|
|
9
|
-
from angr.code_location import CodeLocation, ExternalCodeLocation
|
|
10
|
-
from angr.knowledge_plugins.key_definitions.atoms import Atom, MemoryLocation, Register
|
|
11
|
-
from angr.knowledge_plugins.key_definitions.definition import Definition
|
|
12
|
-
from angr.analyses.reaching_definitions.dep_graph import DepGraph
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
_PAST_N = set()
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def unique_randrange(range_):
|
|
19
|
-
n = randrange(range_)
|
|
20
|
-
while n in _PAST_N:
|
|
21
|
-
n = randrange(range_)
|
|
22
|
-
_PAST_N.add(n)
|
|
23
|
-
return n
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def _a_mock_definition(atom: Atom = None):
|
|
27
|
-
# Randomise code locations to forcefully produce "different" <Definition>s.
|
|
28
|
-
statement_index = unique_randrange(1000)
|
|
29
|
-
code_location = CodeLocation(0x42, statement_index)
|
|
30
|
-
return Definition(atom, code_location)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class TestDepGraph(TestCase):
|
|
34
|
-
class ArchMock:
|
|
35
|
-
def __init__(self):
|
|
36
|
-
pass
|
|
37
|
-
|
|
38
|
-
@property
|
|
39
|
-
def bits(self):
|
|
40
|
-
return 32
|
|
41
|
-
|
|
42
|
-
class CFGMock:
|
|
43
|
-
def __init__(self, memory_data):
|
|
44
|
-
self._memory_data = memory_data
|
|
45
|
-
|
|
46
|
-
@property
|
|
47
|
-
def memory_data(self):
|
|
48
|
-
return self._memory_data
|
|
49
|
-
|
|
50
|
-
class MemoryDataMock:
|
|
51
|
-
def __init__(self, address, content, size, sort):
|
|
52
|
-
self._address = address
|
|
53
|
-
self._content = content
|
|
54
|
-
self._size = size
|
|
55
|
-
self._sort = sort
|
|
56
|
-
|
|
57
|
-
@property
|
|
58
|
-
def address(self):
|
|
59
|
-
return self._address
|
|
60
|
-
|
|
61
|
-
@property
|
|
62
|
-
def content(self):
|
|
63
|
-
return self._content
|
|
64
|
-
|
|
65
|
-
@property
|
|
66
|
-
def size(self):
|
|
67
|
-
return self._size
|
|
68
|
-
|
|
69
|
-
@property
|
|
70
|
-
def sort(self):
|
|
71
|
-
return self._sort
|
|
72
|
-
|
|
73
|
-
class SectionMock:
|
|
74
|
-
def __init__(self, is_writable):
|
|
75
|
-
self._is_writable = is_writable
|
|
76
|
-
|
|
77
|
-
@property
|
|
78
|
-
def is_writable(self):
|
|
79
|
-
return self._is_writable
|
|
80
|
-
|
|
81
|
-
class MainObjectMock:
|
|
82
|
-
def __init__(self, section):
|
|
83
|
-
self._section = section
|
|
84
|
-
|
|
85
|
-
def find_section_containing(self, _):
|
|
86
|
-
return self._section
|
|
87
|
-
|
|
88
|
-
class LoaderMock:
|
|
89
|
-
def __init__(self, main_object):
|
|
90
|
-
self._main_object = main_object
|
|
91
|
-
|
|
92
|
-
@property
|
|
93
|
-
def main_object(self):
|
|
94
|
-
return self._main_object
|
|
95
|
-
|
|
96
|
-
def setUp(self):
|
|
97
|
-
self.memory_address = 0x42424242
|
|
98
|
-
|
|
99
|
-
self.string_in_memory = "some string of data in memory"
|
|
100
|
-
self.string_in_memory_length = len(self.string_in_memory + "\x00")
|
|
101
|
-
|
|
102
|
-
def test_dep_graph_has_a_default_graph(self):
|
|
103
|
-
dep_graph = DepGraph()
|
|
104
|
-
self.assertEqual(isinstance(dep_graph.graph, networkx.DiGraph), True)
|
|
105
|
-
|
|
106
|
-
def test_dep_graph_refuses_to_instanciate_with_an_inadequate_graph(self):
|
|
107
|
-
a_graph = networkx.DiGraph([(1, 2)])
|
|
108
|
-
self.assertRaises(TypeError, DepGraph, a_graph)
|
|
109
|
-
|
|
110
|
-
def test_delegate_add_node_to_the_underlying_graph_object(self):
|
|
111
|
-
with mock.patch.object(networkx.DiGraph, "add_node") as digraph_add_node_mock:
|
|
112
|
-
definition = _a_mock_definition()
|
|
113
|
-
dep_graph = DepGraph()
|
|
114
|
-
dep_graph.add_node(definition)
|
|
115
|
-
|
|
116
|
-
digraph_add_node_mock.assert_called_once_with(definition)
|
|
117
|
-
|
|
118
|
-
def test_delegate_nodes_to_the_underlying_graph_object(self):
|
|
119
|
-
with mock.patch.object(networkx.DiGraph, "nodes") as digraph_nodes_mock:
|
|
120
|
-
dep_graph = DepGraph()
|
|
121
|
-
dep_graph.nodes()
|
|
122
|
-
|
|
123
|
-
digraph_nodes_mock.assert_called_once()
|
|
124
|
-
|
|
125
|
-
def test_delegate_predecessors_to_the_underlying_graph_object(self):
|
|
126
|
-
with mock.patch.object(networkx.DiGraph, "predecessors") as digraph_predecessors_mock:
|
|
127
|
-
definition = _a_mock_definition()
|
|
128
|
-
dep_graph = DepGraph()
|
|
129
|
-
dep_graph.predecessors(definition)
|
|
130
|
-
|
|
131
|
-
digraph_predecessors_mock.assert_called_once_with(definition)
|
|
132
|
-
|
|
133
|
-
def test_delegate_add_edge_to_the_underlying_graph_object(self):
|
|
134
|
-
with mock.patch.object(networkx.DiGraph, "add_edge") as digraph_add_edge_mock:
|
|
135
|
-
use = (_a_mock_definition(), _a_mock_definition())
|
|
136
|
-
labels = {"attribute1": "value1", "attribute2": "value2"}
|
|
137
|
-
|
|
138
|
-
dep_graph = DepGraph()
|
|
139
|
-
dep_graph.add_edge(*use, **labels)
|
|
140
|
-
|
|
141
|
-
digraph_add_edge_mock.assert_called_once_with(*use, **labels)
|
|
142
|
-
|
|
143
|
-
def test_transitive_closure_of_a_node(self):
|
|
144
|
-
dep_graph = DepGraph()
|
|
145
|
-
|
|
146
|
-
# A -> B, B -> D, C -> D
|
|
147
|
-
A = _a_mock_definition()
|
|
148
|
-
B = _a_mock_definition()
|
|
149
|
-
C = _a_mock_definition()
|
|
150
|
-
D = _a_mock_definition()
|
|
151
|
-
uses = [
|
|
152
|
-
(A, B),
|
|
153
|
-
(B, D),
|
|
154
|
-
(C, D),
|
|
155
|
-
]
|
|
156
|
-
|
|
157
|
-
for use in uses:
|
|
158
|
-
dep_graph.add_edge(*use)
|
|
159
|
-
|
|
160
|
-
result = dep_graph.transitive_closure(D)
|
|
161
|
-
result_nodes = set(result.nodes)
|
|
162
|
-
result_edges = set(result.edges)
|
|
163
|
-
|
|
164
|
-
self.assertSetEqual(result_nodes, {D, B, C, A})
|
|
165
|
-
self.assertSetEqual(result_edges, {(B, D), (C, D), (A, B)})
|
|
166
|
-
|
|
167
|
-
def test_transitive_closure_includes_beginning_node_with_memoized_content(self):
|
|
168
|
-
dep_graph = DepGraph()
|
|
169
|
-
# A -> B
|
|
170
|
-
# B -> C
|
|
171
|
-
# C -> D
|
|
172
|
-
A = _a_mock_definition()
|
|
173
|
-
B = _a_mock_definition()
|
|
174
|
-
C = _a_mock_definition()
|
|
175
|
-
D = _a_mock_definition()
|
|
176
|
-
uses = [(A, B), (B, C), (C, D)]
|
|
177
|
-
for use in uses:
|
|
178
|
-
dep_graph.add_edge(*use)
|
|
179
|
-
|
|
180
|
-
closure_0 = dep_graph.transitive_closure(C)
|
|
181
|
-
self.assertNotIn(D, closure_0)
|
|
182
|
-
|
|
183
|
-
closure_1 = dep_graph.transitive_closure(D)
|
|
184
|
-
self.assertIn(D, closure_1)
|
|
185
|
-
self.assertTrue(closure_1.has_edge(A, B))
|
|
186
|
-
self.assertTrue(closure_1.has_edge(B, C))
|
|
187
|
-
self.assertTrue(closure_1.has_edge(C, D))
|
|
188
|
-
|
|
189
|
-
def test_transitive_closure_of_a_node_should_copy_labels_from_original_graph(self):
|
|
190
|
-
dep_graph = DepGraph()
|
|
191
|
-
|
|
192
|
-
# A -> B
|
|
193
|
-
A = _a_mock_definition()
|
|
194
|
-
B = _a_mock_definition()
|
|
195
|
-
uses = [(A, B)]
|
|
196
|
-
|
|
197
|
-
for use in uses:
|
|
198
|
-
dep_graph.add_edge(*use, label="some data")
|
|
199
|
-
|
|
200
|
-
result = dep_graph.transitive_closure(B).get_edge_data(A, B)["label"]
|
|
201
|
-
|
|
202
|
-
self.assertEqual(result, "some data")
|
|
203
|
-
|
|
204
|
-
def test_transitive_closure_of_a_node_on_a_graph_with_loops_should_still_terminate(self):
|
|
205
|
-
dep_graph = DepGraph()
|
|
206
|
-
|
|
207
|
-
# A -> B, B -> C, C -> D, D -> A
|
|
208
|
-
A = _a_mock_definition()
|
|
209
|
-
B = _a_mock_definition()
|
|
210
|
-
C = _a_mock_definition()
|
|
211
|
-
D = _a_mock_definition()
|
|
212
|
-
uses = [
|
|
213
|
-
(A, B),
|
|
214
|
-
(B, C),
|
|
215
|
-
(C, D),
|
|
216
|
-
(D, A),
|
|
217
|
-
]
|
|
218
|
-
|
|
219
|
-
for use in uses:
|
|
220
|
-
dep_graph.add_edge(*use)
|
|
221
|
-
|
|
222
|
-
result = dep_graph.transitive_closure(C)
|
|
223
|
-
result_nodes = set(result.nodes)
|
|
224
|
-
result_edges = set(result.edges)
|
|
225
|
-
|
|
226
|
-
self.assertSetEqual(result_nodes, {A, B, C, D})
|
|
227
|
-
self.assertSetEqual(result_edges, {(A, B), (B, C), (C, D), (D, A)})
|
|
228
|
-
|
|
229
|
-
def test_contains_atom_returns_true_if_the_dependency_graph_contains_a_definition_of_the_given_atom(self):
|
|
230
|
-
dep_graph = DepGraph()
|
|
231
|
-
|
|
232
|
-
r0 = Register(8, 4)
|
|
233
|
-
|
|
234
|
-
# A -> B
|
|
235
|
-
A = _a_mock_definition(r0)
|
|
236
|
-
B = _a_mock_definition()
|
|
237
|
-
|
|
238
|
-
uses = [(A, B)]
|
|
239
|
-
|
|
240
|
-
for use in uses:
|
|
241
|
-
dep_graph.add_edge(*use)
|
|
242
|
-
|
|
243
|
-
result = dep_graph.contains_atom(r0)
|
|
244
|
-
self.assertTrue(result)
|
|
245
|
-
|
|
246
|
-
def test_contains_atom_returns_false_if_the_dependency_graph_does_not_contain_a_definition_of_the_given_atom(self):
|
|
247
|
-
dep_graph = DepGraph()
|
|
248
|
-
|
|
249
|
-
# A -> B
|
|
250
|
-
A = _a_mock_definition()
|
|
251
|
-
B = _a_mock_definition()
|
|
252
|
-
|
|
253
|
-
uses = [(A, B)]
|
|
254
|
-
|
|
255
|
-
for use in uses:
|
|
256
|
-
dep_graph.add_edge(*use)
|
|
257
|
-
|
|
258
|
-
result = dep_graph.contains_atom(Register(8, 4))
|
|
259
|
-
self.assertFalse(result)
|
|
260
|
-
|
|
261
|
-
def test_add_dependencies_for_concrete_pointers_of_fails_if_the_given_definition_is_not_in_the_graph(self):
|
|
262
|
-
dependency_graph = DepGraph()
|
|
263
|
-
|
|
264
|
-
definition = Definition(
|
|
265
|
-
Register(0, 4),
|
|
266
|
-
CodeLocation(0x42, 0),
|
|
267
|
-
)
|
|
268
|
-
|
|
269
|
-
with self.assertRaises(AssertionError) as cm:
|
|
270
|
-
dependency_graph.add_dependencies_for_concrete_pointers_of([claripy.BVS("TOP", 32)], definition, None, None)
|
|
271
|
-
|
|
272
|
-
ex = cm.exception
|
|
273
|
-
self.assertEqual(str(ex), "The given Definition must be present in the given graph.")
|
|
274
|
-
|
|
275
|
-
def test_add_dependencies_for_concrete_pointers_of_adds_a_definition_for_data_pointed_to_by_given_definition(self):
|
|
276
|
-
arch = self.ArchMock()
|
|
277
|
-
loader = self.LoaderMock(self.MainObjectMock(self.SectionMock(True)))
|
|
278
|
-
|
|
279
|
-
memory_datum = self.MemoryDataMock(
|
|
280
|
-
self.memory_address, str.encode(self.string_in_memory), len(self.string_in_memory), "string"
|
|
281
|
-
)
|
|
282
|
-
cfg = self.CFGMock({self.memory_address: memory_datum})
|
|
283
|
-
|
|
284
|
-
register_definition = Definition(
|
|
285
|
-
Register(0, 4),
|
|
286
|
-
None,
|
|
287
|
-
)
|
|
288
|
-
|
|
289
|
-
dependency_graph = DepGraph()
|
|
290
|
-
dependency_graph.add_node(register_definition)
|
|
291
|
-
|
|
292
|
-
dependency_graph.add_dependencies_for_concrete_pointers_of(
|
|
293
|
-
[claripy.BVV(self.memory_address, arch.bits)], register_definition, cfg, loader
|
|
294
|
-
)
|
|
295
|
-
|
|
296
|
-
memory_definition = Definition(
|
|
297
|
-
MemoryLocation(self.memory_address, self.string_in_memory_length),
|
|
298
|
-
ExternalCodeLocation(),
|
|
299
|
-
)
|
|
300
|
-
|
|
301
|
-
nodes = list(dependency_graph.nodes())
|
|
302
|
-
predecessors = list(dependency_graph.graph.predecessors(register_definition))
|
|
303
|
-
self.assertEqual(nodes, [register_definition, memory_definition])
|
|
304
|
-
self.assertListEqual(predecessors, [memory_definition])
|
|
305
|
-
|
|
306
|
-
def test_add_dependencies_for_concrete_pointers_of_does_nothing_if_data_pointed_to_by_definition_is_already_in_dependency_graph( # noqa: E501
|
|
307
|
-
self,
|
|
308
|
-
):
|
|
309
|
-
arch = self.ArchMock()
|
|
310
|
-
loader = self.LoaderMock(self.MainObjectMock(self.SectionMock(True)))
|
|
311
|
-
|
|
312
|
-
memory_datum = self.MemoryDataMock(
|
|
313
|
-
self.memory_address, str.encode(self.string_in_memory), len(self.string_in_memory), "string"
|
|
314
|
-
)
|
|
315
|
-
cfg = self.CFGMock({self.memory_address: memory_datum})
|
|
316
|
-
|
|
317
|
-
memory_location_definition = Definition(
|
|
318
|
-
MemoryLocation(self.memory_address, self.string_in_memory_length),
|
|
319
|
-
CodeLocation(0, 0),
|
|
320
|
-
)
|
|
321
|
-
|
|
322
|
-
register_definition = Definition(
|
|
323
|
-
Register(0, 4),
|
|
324
|
-
CodeLocation(0x42, 0),
|
|
325
|
-
)
|
|
326
|
-
|
|
327
|
-
dependency_graph = DepGraph(networkx.DiGraph([(memory_location_definition, register_definition)]))
|
|
328
|
-
|
|
329
|
-
nodes_before_call = dependency_graph.nodes()
|
|
330
|
-
|
|
331
|
-
dependency_graph.add_dependencies_for_concrete_pointers_of(
|
|
332
|
-
[claripy.BVV(self.memory_address, arch.bits)], register_definition, cfg, loader
|
|
333
|
-
)
|
|
334
|
-
|
|
335
|
-
self.assertEqual(nodes_before_call, dependency_graph.nodes())
|
|
336
|
-
|
|
337
|
-
def test_add_dependencies_for_concrete_pointers_of_does_nothing_if_pointer_is_not_concrete(self):
|
|
338
|
-
arch = self.ArchMock()
|
|
339
|
-
cfg = self.CFGMock({})
|
|
340
|
-
loader = self.LoaderMock(self.MainObjectMock(self.SectionMock(True)))
|
|
341
|
-
|
|
342
|
-
register_definition = Definition(
|
|
343
|
-
Register(0, 4),
|
|
344
|
-
CodeLocation(0x42, 0),
|
|
345
|
-
)
|
|
346
|
-
|
|
347
|
-
dependency_graph = DepGraph()
|
|
348
|
-
dependency_graph.add_node(register_definition)
|
|
349
|
-
|
|
350
|
-
nodes_before_call = dependency_graph.nodes()
|
|
351
|
-
|
|
352
|
-
dependency_graph.add_dependencies_for_concrete_pointers_of(
|
|
353
|
-
[claripy.BVS("TOP", arch.bits)],
|
|
354
|
-
register_definition,
|
|
355
|
-
cfg,
|
|
356
|
-
loader,
|
|
357
|
-
)
|
|
358
|
-
|
|
359
|
-
self.assertEqual(nodes_before_call, dependency_graph.nodes())
|
|
360
|
-
|
|
361
|
-
def test_add_dependencies_for_concrete_pointers_of_create_memory_location_with_undefined_data_if_data_pointed_to_by_definition_is_not_known( # noqa: E501
|
|
362
|
-
self,
|
|
363
|
-
):
|
|
364
|
-
arch = self.ArchMock()
|
|
365
|
-
loader = self.LoaderMock(self.MainObjectMock(self.SectionMock(True)))
|
|
366
|
-
|
|
367
|
-
datum_content = None
|
|
368
|
-
datum_size = 0x4242
|
|
369
|
-
memory_datum = self.MemoryDataMock(self.memory_address, datum_content, datum_size, "unknown")
|
|
370
|
-
cfg = self.CFGMock({self.memory_address: memory_datum})
|
|
371
|
-
|
|
372
|
-
memory_definition = Definition(
|
|
373
|
-
MemoryLocation(self.memory_address, datum_size),
|
|
374
|
-
ExternalCodeLocation(),
|
|
375
|
-
)
|
|
376
|
-
|
|
377
|
-
register_definition = Definition(
|
|
378
|
-
Register(0, 4),
|
|
379
|
-
CodeLocation(0x42, 0),
|
|
380
|
-
)
|
|
381
|
-
|
|
382
|
-
dependency_graph = DepGraph()
|
|
383
|
-
dependency_graph.add_node(register_definition)
|
|
384
|
-
|
|
385
|
-
dependency_graph.add_dependencies_for_concrete_pointers_of(
|
|
386
|
-
[claripy.BVV(self.memory_address, arch.bits)],
|
|
387
|
-
register_definition,
|
|
388
|
-
cfg,
|
|
389
|
-
loader,
|
|
390
|
-
)
|
|
391
|
-
|
|
392
|
-
nodes = list(dependency_graph.nodes())
|
|
393
|
-
predecessors = list(dependency_graph.graph.predecessors(register_definition))
|
|
394
|
-
self.assertEqual(nodes, [register_definition, memory_definition])
|
|
395
|
-
self.assertListEqual(predecessors, [memory_definition])
|
|
396
|
-
|
|
397
|
-
def test_add_dependencies_for_concrete_pointers_of_adds_a_definition_with_codelocation_in_binary_if_data_in_readonly_memory( # noqa: E501
|
|
398
|
-
self,
|
|
399
|
-
):
|
|
400
|
-
arch = self.ArchMock()
|
|
401
|
-
|
|
402
|
-
writable = False
|
|
403
|
-
loader = self.LoaderMock(self.MainObjectMock(self.SectionMock(writable)))
|
|
404
|
-
|
|
405
|
-
memory_datum = self.MemoryDataMock(
|
|
406
|
-
self.memory_address, str.encode(self.string_in_memory), len(self.string_in_memory), "string"
|
|
407
|
-
)
|
|
408
|
-
cfg = self.CFGMock({self.memory_address: memory_datum})
|
|
409
|
-
|
|
410
|
-
register_definition = Definition(
|
|
411
|
-
Register(0, 4),
|
|
412
|
-
CodeLocation(0x42, 0),
|
|
413
|
-
)
|
|
414
|
-
|
|
415
|
-
dependency_graph = DepGraph()
|
|
416
|
-
dependency_graph.add_node(register_definition)
|
|
417
|
-
|
|
418
|
-
dependency_graph.add_dependencies_for_concrete_pointers_of(
|
|
419
|
-
[claripy.BVV(self.memory_address, arch.bits)],
|
|
420
|
-
register_definition,
|
|
421
|
-
cfg,
|
|
422
|
-
loader,
|
|
423
|
-
)
|
|
424
|
-
|
|
425
|
-
origin_codelocation = CodeLocation(0, 0, info={"readonly": True})
|
|
426
|
-
|
|
427
|
-
predecessor = list(dependency_graph.graph.predecessors(register_definition))[0]
|
|
428
|
-
self.assertEqual(predecessor.codeloc, origin_codelocation)
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
if __name__ == "__main__":
|
|
432
|
-
main()
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# pylint:disable=missing-class-docstring,no-self-use
|
|
3
|
-
__package__ = __package__ or "tests.analyses.reaching_definitions" # pylint:disable=redefined-builtin
|
|
4
|
-
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
6
|
-
import os
|
|
7
|
-
from unittest import main, TestCase
|
|
8
|
-
|
|
9
|
-
import claripy
|
|
10
|
-
|
|
11
|
-
import angr
|
|
12
|
-
from angr.analyses.reaching_definitions import FunctionHandler
|
|
13
|
-
from angr.storage.memory_mixins.paged_memory.pages.multi_values import MultiValues
|
|
14
|
-
from angr.errors import SimMemoryMissingError
|
|
15
|
-
|
|
16
|
-
if TYPE_CHECKING:
|
|
17
|
-
from angr.analyses.reaching_definitions.rd_state import ReachingDefinitionsState
|
|
18
|
-
from angr.analyses.reaching_definitions import FunctionCallData
|
|
19
|
-
|
|
20
|
-
from ...common import bin_location
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
TESTS_LOCATION = os.path.join(bin_location, "tests")
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def load_cstring_from_loader_memory(project, addr: int, as_str: bool = False):
|
|
27
|
-
# This function loads a null-terminated string from the static memory region
|
|
28
|
-
s = b""
|
|
29
|
-
while True:
|
|
30
|
-
char_addr = addr + len(s)
|
|
31
|
-
try:
|
|
32
|
-
v = project.loader.memory.load(char_addr, 1)
|
|
33
|
-
except KeyError:
|
|
34
|
-
break
|
|
35
|
-
if v == b"\x00":
|
|
36
|
-
break
|
|
37
|
-
s += v
|
|
38
|
-
return s.decode("utf-8") if as_str else (s + b"\x00")
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def load_cstring_from_memory_definitions(ld, addr: int, as_str: bool = False):
|
|
42
|
-
# This function loads a null-terminated string from the memory definitions
|
|
43
|
-
s = b""
|
|
44
|
-
while True:
|
|
45
|
-
char_addr = addr + len(s)
|
|
46
|
-
try:
|
|
47
|
-
v = ld.memory.load(char_addr, 1).one_value().concrete_value
|
|
48
|
-
except SimMemoryMissingError:
|
|
49
|
-
break
|
|
50
|
-
if v == 0:
|
|
51
|
-
break
|
|
52
|
-
s += v.to_bytes(1, "little")
|
|
53
|
-
return s.decode("utf-8") if as_str else (s + b"\x00")
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
class CustomFunctionHandler(FunctionHandler):
|
|
57
|
-
def __init__(self, project):
|
|
58
|
-
self.project = project
|
|
59
|
-
self.system_cmd = ""
|
|
60
|
-
self.strcpy_addr = None
|
|
61
|
-
self.sscanf_str_addr = None
|
|
62
|
-
self.sscanf_str = None
|
|
63
|
-
self.sscanf_fmtstr_addr = None
|
|
64
|
-
self.sscanf_fmtstr = None
|
|
65
|
-
self.sscanf_out_value = None
|
|
66
|
-
self.malloc_sizes = []
|
|
67
|
-
|
|
68
|
-
def handle_impl_malloc(self, state: "ReachingDefinitionsState", data: "FunctionCallData"):
|
|
69
|
-
((src_atom,),) = data.args_atoms
|
|
70
|
-
|
|
71
|
-
src_value = state.get_values(src_atom).one_value().concrete_value
|
|
72
|
-
self.malloc_sizes.append(src_value)
|
|
73
|
-
data.depends(list(data.ret_atoms)[0], value=MultiValues(claripy.BVV(0x12345678, 64)))
|
|
74
|
-
|
|
75
|
-
def handle_impl___isoc99_sscanf(self, state: "ReachingDefinitionsState", data: "FunctionCallData"):
|
|
76
|
-
(str_atom,), (fmtstr_atom,), (out_atom,) = data.args_atoms[:3]
|
|
77
|
-
|
|
78
|
-
# string
|
|
79
|
-
str_addr = state.get_values(str_atom).one_value().concrete_value
|
|
80
|
-
self.sscanf_str_addr = str_addr
|
|
81
|
-
str_ = load_cstring_from_loader_memory(self.project, str_addr)
|
|
82
|
-
self.sscanf_str = str_
|
|
83
|
-
|
|
84
|
-
# format string: "%d"
|
|
85
|
-
fmtstr_addr = state.get_values(fmtstr_atom).one_value().concrete_value
|
|
86
|
-
self.sscanf_fmtstr_addr = fmtstr_addr
|
|
87
|
-
fmtstr = load_cstring_from_loader_memory(self.project, str_addr)
|
|
88
|
-
self.sscanf_fmtstr = fmtstr
|
|
89
|
-
|
|
90
|
-
# out pointer
|
|
91
|
-
(dst,) = state.pointer_to_atoms(state.get_values(out_atom), size=4, endness=state.arch.memory_endness)
|
|
92
|
-
(src,) = state.pointer_to_atoms(state.get_values(str_atom), size=len(str_), endness="Iend_BE")
|
|
93
|
-
self.sscanf_out_value = int(str_.strip(b"\x00"))
|
|
94
|
-
data.depends(dst, src, value=MultiValues(claripy.BVV(self.sscanf_out_value, 32)))
|
|
95
|
-
|
|
96
|
-
def handle_impl_strcpy(self, state: "ReachingDefinitionsState", data: "FunctionCallData"):
|
|
97
|
-
(dst_atom,), (src_atom,) = data.args_atoms
|
|
98
|
-
|
|
99
|
-
# Assume source is a constant string
|
|
100
|
-
src_addr = state.get_values(src_atom).one_value().concrete_value
|
|
101
|
-
self.strcpy_addr = src_addr
|
|
102
|
-
src_str = load_cstring_from_loader_memory(self.project, src_addr)
|
|
103
|
-
src_str_size = len(src_str)
|
|
104
|
-
|
|
105
|
-
(dst,) = state.pointer_to_atoms(state.get_values(dst_atom), size=src_str_size, endness="Iend_BE")
|
|
106
|
-
(src,) = state.pointer_to_atoms(state.get_values(src_atom), size=src_str_size, endness="Iend_BE")
|
|
107
|
-
|
|
108
|
-
data.depends(dst, src, value=MultiValues(claripy.BVV(src_str)))
|
|
109
|
-
|
|
110
|
-
def handle_impl_system(self, state: "ReachingDefinitionsState", data: "FunctionCallData"):
|
|
111
|
-
(cmd_atom,) = data.args_atoms[0]
|
|
112
|
-
cmd_addr = state.get_values(cmd_atom).one_value().concrete_value
|
|
113
|
-
self.system_cmd = load_cstring_from_memory_definitions(state.live_definitions, cmd_addr, as_str=True)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
class TestFunctionhandler(TestCase):
|
|
117
|
-
def test_function_handler_depends_has_endness(self):
|
|
118
|
-
filename = os.path.join(TESTS_LOCATION, "x86_64", "rda_function_handler")
|
|
119
|
-
project = angr.Project(filename, auto_load_libs=False)
|
|
120
|
-
_ = project.analyses.CFGFast()
|
|
121
|
-
handler = CustomFunctionHandler(project)
|
|
122
|
-
_ = project.analyses.ReachingDefinitions("main", function_handler=handler)
|
|
123
|
-
|
|
124
|
-
assert handler.system_cmd == "ABCDEFGH"
|
|
125
|
-
assert handler.sscanf_str == b"12345678\x00"
|
|
126
|
-
assert handler.sscanf_out_value == 12345678
|
|
127
|
-
assert handler.malloc_sizes == [20, 12345678]
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if __name__ == "__main__":
|
|
131
|
-
main()
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
from unittest import main, TestCase
|
|
3
|
-
|
|
4
|
-
from angr.analyses.reaching_definitions.heap_allocator import HeapAllocator
|
|
5
|
-
from angr.knowledge_plugins.key_definitions.heap_address import HeapAddress
|
|
6
|
-
from angr.knowledge_plugins.key_definitions.unknown_size import UNKNOWN_SIZE
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class TestHeapAllocator(TestCase):
|
|
10
|
-
UNKNOWN_SIZE_DEFAULT_CONCRETE_VALUE = 8
|
|
11
|
-
|
|
12
|
-
def setUp(self):
|
|
13
|
-
self.heap_allocator = HeapAllocator(self.UNKNOWN_SIZE_DEFAULT_CONCRETE_VALUE)
|
|
14
|
-
|
|
15
|
-
def test_allocate_returns_an_entry_address(self):
|
|
16
|
-
address = self.heap_allocator.allocate(0x10)
|
|
17
|
-
self.assertTrue(isinstance(address, HeapAddress))
|
|
18
|
-
|
|
19
|
-
def test_allocate_create_an_entry_after_the_previous_one(self):
|
|
20
|
-
size_of_first_chunck = 0x10
|
|
21
|
-
address = self.heap_allocator.allocate(size_of_first_chunck)
|
|
22
|
-
other_address = self.heap_allocator.allocate(0x10)
|
|
23
|
-
|
|
24
|
-
self.assertEqual(other_address.value - address.value, size_of_first_chunck)
|
|
25
|
-
|
|
26
|
-
def test_allocate_given_an_undefined_size_still_gives_a_concrete_address(self):
|
|
27
|
-
size_of_first_chunck = UNKNOWN_SIZE
|
|
28
|
-
address = self.heap_allocator.allocate(size_of_first_chunck)
|
|
29
|
-
other_address = self.heap_allocator.allocate(0x10)
|
|
30
|
-
|
|
31
|
-
self.assertEqual(other_address.value - address.value, self.UNKNOWN_SIZE_DEFAULT_CONCRETE_VALUE)
|
|
32
|
-
|
|
33
|
-
def test_allocated_addresses_keeps_track_of_memory_chuncks_in_use(self):
|
|
34
|
-
address = self.heap_allocator.allocate(0x10)
|
|
35
|
-
|
|
36
|
-
self.assertTrue(address in self.heap_allocator.allocated_addresses)
|
|
37
|
-
|
|
38
|
-
def test_free_removes_the_address_from_list_of_allocated_ones(self):
|
|
39
|
-
address = self.heap_allocator.allocate(0x10)
|
|
40
|
-
self.heap_allocator.free(address)
|
|
41
|
-
|
|
42
|
-
self.assertFalse(address in self.heap_allocator.allocated_addresses)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if __name__ == "__main__":
|
|
46
|
-
main()
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
__package__ = __package__ or "tests.analyses.reaching_definitions" # pylint:disable=redefined-builtin
|
|
3
|
-
|
|
4
|
-
import os
|
|
5
|
-
import random
|
|
6
|
-
|
|
7
|
-
from unittest import main, mock, TestCase
|
|
8
|
-
|
|
9
|
-
import archinfo
|
|
10
|
-
|
|
11
|
-
from angr.analyses.reaching_definitions.heap_allocator import HeapAllocator
|
|
12
|
-
from angr.analyses.reaching_definitions.rd_state import ReachingDefinitionsState
|
|
13
|
-
from angr.analyses.reaching_definitions.subject import SubjectType
|
|
14
|
-
from angr.knowledge_plugins.key_definitions.live_definitions import LiveDefinitions
|
|
15
|
-
from angr.code_location import CodeLocation
|
|
16
|
-
|
|
17
|
-
from ...common import bin_location
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
TESTS_LOCATION = os.path.join(bin_location, "tests")
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class _MockFunctionSubject: # pylint:disable=too-few-public-methods
|
|
24
|
-
class _MockFunction: # pylint:disable=too-few-public-methods
|
|
25
|
-
def __init__(self):
|
|
26
|
-
self.addr = 0x42
|
|
27
|
-
|
|
28
|
-
def __init__(self):
|
|
29
|
-
self.type = SubjectType.Function
|
|
30
|
-
self.cc = None # pylint:disable=invalid-name
|
|
31
|
-
self.content = self._MockFunction()
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class TestReachingDefinitionsState(TestCase):
|
|
35
|
-
def test_initializing_rd_state_for_ppc_without_rtoc_value_should_raise_an_error(self):
|
|
36
|
-
arch = archinfo.arch_ppc64.ArchPPC64()
|
|
37
|
-
self.assertRaises(
|
|
38
|
-
ValueError, ReachingDefinitionsState, CodeLocation(0x42, None), arch=arch, subject=_MockFunctionSubject()
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
def test_initializing_rd_state_for_ppc_with_rtoc_value(self):
|
|
42
|
-
arch = archinfo.arch_ppc64.ArchPPC64()
|
|
43
|
-
rtoc_value = random.randint(0, 0xFFFFFFFFFFFFFFFF)
|
|
44
|
-
|
|
45
|
-
state = ReachingDefinitionsState(
|
|
46
|
-
CodeLocation(0x42, None), arch=arch, subject=_MockFunctionSubject(), rtoc_value=rtoc_value
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
rtoc_offset = arch.registers["rtoc"][0]
|
|
50
|
-
rtoc_definition_value = state.registers.load(rtoc_offset, size=8)
|
|
51
|
-
|
|
52
|
-
self.assertIsNotNone(rtoc_definition_value.one_value())
|
|
53
|
-
v = rtoc_definition_value.one_value()
|
|
54
|
-
self.assertFalse(v.symbolic)
|
|
55
|
-
self.assertEqual(v.concrete_value, rtoc_value)
|
|
56
|
-
|
|
57
|
-
def test_rd_state_gets_a_default_heap_allocator(self):
|
|
58
|
-
arch = archinfo.arch_arm.ArchARM()
|
|
59
|
-
state = ReachingDefinitionsState(CodeLocation(0x42, None), arch, _MockFunctionSubject())
|
|
60
|
-
|
|
61
|
-
self.assertTrue(isinstance(state.heap_allocator, HeapAllocator))
|
|
62
|
-
|
|
63
|
-
def test_get_sp_delegates_to_the_underlying_live_definitions(self): # pylint:disable=no-self-use
|
|
64
|
-
arch = archinfo.arch_arm.ArchARM()
|
|
65
|
-
live_definitions = LiveDefinitions(arch)
|
|
66
|
-
|
|
67
|
-
state = ReachingDefinitionsState(
|
|
68
|
-
CodeLocation(0x42, None), arch=arch, subject=_MockFunctionSubject(), live_definitions=live_definitions
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
with mock.patch.object(LiveDefinitions, "get_sp") as live_definitions_get_sp_mock:
|
|
72
|
-
state.get_sp()
|
|
73
|
-
|
|
74
|
-
live_definitions_get_sp_mock.assert_called_once()
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if __name__ == "__main__":
|
|
78
|
-
main()
|