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,54 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# pylint: disable=missing-class-docstring,no-self-use,line-too-long
|
|
3
|
-
|
|
4
|
-
import unittest
|
|
5
|
-
|
|
6
|
-
import archinfo
|
|
7
|
-
|
|
8
|
-
import angr
|
|
9
|
-
from angr.analyses.cfg import CFGBase
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class TestNoopBlocks(unittest.TestCase):
|
|
13
|
-
def test_x86_noop_blocks(self):
|
|
14
|
-
# nop
|
|
15
|
-
arch = archinfo.arch_from_id("x86")
|
|
16
|
-
b = b"\x90\x90\x90\x90\x90\x90\x90\x90"
|
|
17
|
-
p = angr.load_shellcode(b, arch, load_address=0x400000)
|
|
18
|
-
block = p.factory.block(0x400000, opt_level=1, cross_insn_opt=False)
|
|
19
|
-
assert CFGBase._is_noop_block(arch, block) is True
|
|
20
|
-
block = p.factory.block(0x400000, opt_level=1, cross_insn_opt=True)
|
|
21
|
-
assert CFGBase._is_noop_block(arch, block) is True
|
|
22
|
-
|
|
23
|
-
def test_amd64_noop_blocks(self):
|
|
24
|
-
# nop
|
|
25
|
-
arch = archinfo.arch_from_id("amd64")
|
|
26
|
-
b = b"\x90\x90\x90\x90\x90\x90\x90\x90"
|
|
27
|
-
p = angr.load_shellcode(b, arch, load_address=0x400000)
|
|
28
|
-
block = p.factory.block(0x400000, opt_level=1, cross_insn_opt=False)
|
|
29
|
-
assert CFGBase._is_noop_block(arch, block) is True
|
|
30
|
-
block = p.factory.block(0x400000, opt_level=1, cross_insn_opt=True)
|
|
31
|
-
assert CFGBase._is_noop_block(arch, block) is True
|
|
32
|
-
|
|
33
|
-
def test_arm_noop_blocks(self):
|
|
34
|
-
arch = archinfo.arch_from_id("ARMEL")
|
|
35
|
-
|
|
36
|
-
# andeq r0, r0, r0
|
|
37
|
-
b = b"\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
38
|
-
p = angr.load_shellcode(b, arch, load_address=0x400000)
|
|
39
|
-
block = p.factory.block(0x400000, opt_level=1, cross_insn_opt=False)
|
|
40
|
-
assert CFGBase._is_noop_block(arch, block) is True
|
|
41
|
-
block = p.factory.block(0x400000, opt_level=1, cross_insn_opt=True)
|
|
42
|
-
assert CFGBase._is_noop_block(arch, block) is True
|
|
43
|
-
|
|
44
|
-
# mov r0, r0
|
|
45
|
-
b = b"\x00\x00\xa0\xe1"
|
|
46
|
-
p = angr.load_shellcode(b, arch, load_address=0x400000)
|
|
47
|
-
block = p.factory.block(0x400000, opt_level=1, cross_insn_opt=False)
|
|
48
|
-
assert CFGBase._is_noop_block(arch, block) is True
|
|
49
|
-
block = p.factory.block(0x400000, opt_level=1, cross_insn_opt=True)
|
|
50
|
-
assert CFGBase._is_noop_block(arch, block) is True
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if __name__ == "__main__":
|
|
54
|
-
unittest.main()
|
|
File without changes
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
import os
|
|
3
|
-
import unittest
|
|
4
|
-
|
|
5
|
-
from angr.analyses.cfg_slice_to_sink import CFGSliceToSink
|
|
6
|
-
from angr.project import Project
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class TestCFGSliceToSink(unittest.TestCase):
|
|
10
|
-
def test_get_transitions_from_slice(self):
|
|
11
|
-
transitions = {1: [2, 3]}
|
|
12
|
-
my_slice = CFGSliceToSink(None, transitions)
|
|
13
|
-
|
|
14
|
-
self.assertDictEqual(my_slice.transitions, transitions)
|
|
15
|
-
|
|
16
|
-
def test_get_entrypoints_from_slice(self):
|
|
17
|
-
transitions = {0: [2], 1: [2, 3], 2: [4, 5]}
|
|
18
|
-
my_slice = CFGSliceToSink(None, transitions)
|
|
19
|
-
|
|
20
|
-
self.assertListEqual(my_slice.entrypoints, [0, 1])
|
|
21
|
-
|
|
22
|
-
def test_add_transitions_updates_the_slice(self):
|
|
23
|
-
my_slice = CFGSliceToSink(None, {1: [2, 3]})
|
|
24
|
-
transitions_to_add = {1: [4], 2: [4]}
|
|
25
|
-
|
|
26
|
-
result = my_slice.add_transitions(transitions_to_add)
|
|
27
|
-
|
|
28
|
-
expected_result = {
|
|
29
|
-
1: [2, 3, 4],
|
|
30
|
-
2: [4],
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
self.assertDictEqual(result, expected_result)
|
|
34
|
-
|
|
35
|
-
def test_nodes(self):
|
|
36
|
-
my_slice = CFGSliceToSink(
|
|
37
|
-
None,
|
|
38
|
-
{
|
|
39
|
-
1: [2, 3],
|
|
40
|
-
2: [3],
|
|
41
|
-
},
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
expected_result = [1, 2, 3]
|
|
45
|
-
result = my_slice.nodes
|
|
46
|
-
|
|
47
|
-
self.assertListEqual(result, expected_result)
|
|
48
|
-
|
|
49
|
-
def test_transitions_as_tuples(self):
|
|
50
|
-
my_slice = CFGSliceToSink(None, {1: [2, 3], 2: [3]})
|
|
51
|
-
|
|
52
|
-
expected_result = [(1, 2), (1, 3), (2, 3)]
|
|
53
|
-
result = my_slice.transitions_as_tuples
|
|
54
|
-
|
|
55
|
-
self.assertListEqual(result, expected_result)
|
|
56
|
-
|
|
57
|
-
def disable_emptyness(self):
|
|
58
|
-
# disabled since binaries-private is not checked out for angr CI
|
|
59
|
-
binaries_path = os.path.join(
|
|
60
|
-
os.path.dirname(__file__), "..", "..", "..", "..", "binaries-private", "operation-mango"
|
|
61
|
-
)
|
|
62
|
-
binary_path = os.path.join(binaries_path, "air-live-bu-2015", "cgi_test.cgi")
|
|
63
|
-
project = Project(binary_path, auto_load_libs=False)
|
|
64
|
-
cfg = project.analyses.CFGFast()
|
|
65
|
-
printf = cfg.kb.functions.function(name="printf", plt=False)
|
|
66
|
-
printf_node = cfg.model.get_all_nodes(printf.addr)[0]
|
|
67
|
-
|
|
68
|
-
printf_predecessor = printf_node.predecessors[0]
|
|
69
|
-
|
|
70
|
-
empty_slice = CFGSliceToSink(printf, {})
|
|
71
|
-
non_empty_slice = CFGSliceToSink(printf, {printf_predecessor.addr: [printf.addr]})
|
|
72
|
-
|
|
73
|
-
self.assertEqual(empty_slice.is_empty(), True)
|
|
74
|
-
self.assertEqual(non_empty_slice.is_empty(), False)
|
|
75
|
-
|
|
76
|
-
def test_path_between_returns_True_only_if_there_exists_at_least_a_path_between_two_nodes_in_the_slice(self):
|
|
77
|
-
my_slice = CFGSliceToSink(None, {1: [2, 3], 2: [4]})
|
|
78
|
-
|
|
79
|
-
self.assertTrue(my_slice.path_between(1, 2))
|
|
80
|
-
self.assertTrue(my_slice.path_between(1, 3))
|
|
81
|
-
self.assertTrue(my_slice.path_between(2, 4))
|
|
82
|
-
self.assertTrue(my_slice.path_between(1, 4))
|
|
83
|
-
|
|
84
|
-
self.assertFalse(my_slice.path_between(3, 4))
|
|
85
|
-
|
|
86
|
-
def test_path_between_deals_with_loops(self):
|
|
87
|
-
my_slice = CFGSliceToSink(None, {1: [2, 3], 2: [1]})
|
|
88
|
-
|
|
89
|
-
self.assertFalse(my_slice.path_between(1, 4))
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if __name__ == "__main__":
|
|
93
|
-
unittest.main()
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
import networkx
|
|
3
|
-
import unittest
|
|
4
|
-
|
|
5
|
-
from angr.analyses.cfg_slice_to_sink import CFGSliceToSink, slice_callgraph, slice_cfg_graph, slice_function_graph
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class _MockCFGNode:
|
|
9
|
-
def __init__(self, addr):
|
|
10
|
-
self.addr = addr
|
|
11
|
-
|
|
12
|
-
def __repr__(self):
|
|
13
|
-
return "%s" % self.addr
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def _a_graph_and_its_nodes():
|
|
17
|
-
# Build the following graph (addresses displayed):
|
|
18
|
-
# 0 -> 1, 1 -> 2, 0 -> 3
|
|
19
|
-
graph = networkx.DiGraph()
|
|
20
|
-
nodes = list(map(_MockCFGNode, range(4)))
|
|
21
|
-
graph.add_edge(nodes[0], nodes[1])
|
|
22
|
-
graph.add_edge(nodes[1], nodes[2])
|
|
23
|
-
graph.add_edge(nodes[0], nodes[3])
|
|
24
|
-
return (graph, nodes)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class TestGraph(unittest.TestCase):
|
|
28
|
-
def test_slice_callgraph_remove_content_not_in_a_cfg_slice_to_sink(self):
|
|
29
|
-
my_callgraph, nodes = _a_graph_and_its_nodes()
|
|
30
|
-
|
|
31
|
-
# Let's imagine a node (0x42), not a function entry point, not in my_callgraph, such as:
|
|
32
|
-
# 1 -> 0x42, 0x42 -> 2
|
|
33
|
-
transitions = {nodes[0]: [nodes[1]], nodes[1]: [0x42], 0x42: [nodes[2]]}
|
|
34
|
-
cfg_slice_to_sink = CFGSliceToSink(None, transitions)
|
|
35
|
-
|
|
36
|
-
sliced_callgraph = slice_callgraph(my_callgraph, cfg_slice_to_sink)
|
|
37
|
-
|
|
38
|
-
result_nodes = list(sliced_callgraph.nodes)
|
|
39
|
-
result_edges = list(sliced_callgraph.edges)
|
|
40
|
-
|
|
41
|
-
self.assertListEqual(result_nodes, [nodes[0], nodes[1], nodes[2]])
|
|
42
|
-
self.assertListEqual(result_edges, [(nodes[0], nodes[1]), (nodes[1], nodes[2])])
|
|
43
|
-
|
|
44
|
-
def test_slice_callgraph_mutates_the_original_graph(self):
|
|
45
|
-
my_callgraph, nodes = _a_graph_and_its_nodes()
|
|
46
|
-
|
|
47
|
-
# Let's imagine a node (0x42), not a function entry point, not in my_callgraph, such as:
|
|
48
|
-
# 1 -> 0x42, 0x42 -> 2
|
|
49
|
-
transitions = {nodes[0]: [nodes[1]], nodes[1]: [0x42], 0x42: [nodes[2]]}
|
|
50
|
-
cfg_slice_to_sink = CFGSliceToSink(None, transitions)
|
|
51
|
-
|
|
52
|
-
sliced_callgraph = slice_callgraph(my_callgraph, cfg_slice_to_sink)
|
|
53
|
-
|
|
54
|
-
self.assertEqual(len(my_callgraph.nodes), 3)
|
|
55
|
-
self.assertEqual(len(my_callgraph.edges), 2)
|
|
56
|
-
self.assertEqual(my_callgraph, sliced_callgraph)
|
|
57
|
-
|
|
58
|
-
def test_slice_cfg_graph_remove_content_not_in_a_cfg_slice_to_sink(self):
|
|
59
|
-
my_graph, nodes = _a_graph_and_its_nodes()
|
|
60
|
-
|
|
61
|
-
transitions = {nodes[0].addr: [nodes[1].addr], nodes[1].addr: [nodes[2].addr]}
|
|
62
|
-
my_slice = CFGSliceToSink(None, transitions)
|
|
63
|
-
|
|
64
|
-
sliced_graph = slice_cfg_graph(my_graph, my_slice)
|
|
65
|
-
result_nodes = list(sliced_graph.nodes)
|
|
66
|
-
result_edges = list(sliced_graph.edges)
|
|
67
|
-
|
|
68
|
-
self.assertListEqual(result_nodes, [nodes[0], nodes[1], nodes[2]])
|
|
69
|
-
self.assertListEqual(result_edges, [(nodes[0], nodes[1]), (nodes[1], nodes[2])])
|
|
70
|
-
|
|
71
|
-
def test_slice_cfg_graph_mutates_the_original_graph(self):
|
|
72
|
-
my_graph, nodes = _a_graph_and_its_nodes()
|
|
73
|
-
|
|
74
|
-
transitions = {nodes[0].addr: [nodes[1].addr]}
|
|
75
|
-
my_slice = CFGSliceToSink(None, transitions)
|
|
76
|
-
|
|
77
|
-
sliced_graph = slice_cfg_graph(my_graph, my_slice)
|
|
78
|
-
|
|
79
|
-
self.assertEqual(len(my_graph.nodes), 2)
|
|
80
|
-
self.assertEqual(len(my_graph.edges), 1)
|
|
81
|
-
self.assertEqual(my_graph, sliced_graph)
|
|
82
|
-
|
|
83
|
-
def test_slice_function_graph_remove_nodes_not_in_a_cfg_slice_to_sink(self):
|
|
84
|
-
# Imagine a CFG being: 0 -> 0x42, 0x42 -> 1, 1 -> 2, 0 -> 3
|
|
85
|
-
# And the function graph: 0 -> 1, 1 -> 2, 0 -> 3
|
|
86
|
-
my_function_graph, nodes = _a_graph_and_its_nodes()
|
|
87
|
-
|
|
88
|
-
transitions = {nodes[0].addr: [0x42], 0x42: [nodes[1].addr]}
|
|
89
|
-
my_slice = CFGSliceToSink(None, transitions)
|
|
90
|
-
|
|
91
|
-
sliced_function_graph = slice_function_graph(my_function_graph, my_slice)
|
|
92
|
-
result_nodes = list(sliced_function_graph.nodes)
|
|
93
|
-
result_edges = list(sliced_function_graph.edges)
|
|
94
|
-
|
|
95
|
-
self.assertListEqual(result_nodes, [nodes[0], nodes[1]])
|
|
96
|
-
self.assertListEqual(result_edges, [(nodes[0], nodes[1])])
|
|
97
|
-
|
|
98
|
-
def test_slice_function_graph_mutates_the_original_function_graph(self):
|
|
99
|
-
# Imagine a CFG being: 0 -> 0x42, 0x42 -> 1, 1 -> 2, 0 -> 3
|
|
100
|
-
# And the function graph: 0 -> 1, 1 -> 2, 0 -> 3
|
|
101
|
-
my_function_graph, nodes = _a_graph_and_its_nodes()
|
|
102
|
-
|
|
103
|
-
transitions = {nodes[0].addr: [0x42], 0x42: [nodes[1].addr]}
|
|
104
|
-
my_slice = CFGSliceToSink(None, transitions)
|
|
105
|
-
|
|
106
|
-
sliced_function_graph = slice_function_graph(my_function_graph, my_slice)
|
|
107
|
-
|
|
108
|
-
self.assertEqual(len(my_function_graph.nodes), 2)
|
|
109
|
-
self.assertEqual(len(my_function_graph.edges), 1)
|
|
110
|
-
self.assertEqual(my_function_graph, sliced_function_graph)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if __name__ == "__main__":
|
|
114
|
-
unittest.main()
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
import unittest
|
|
3
|
-
|
|
4
|
-
from angr.analyses.cfg_slice_to_sink.transitions import merge_transitions
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class TestTrasitions(unittest.TestCase):
|
|
8
|
-
def test_merge_transitions(self):
|
|
9
|
-
t1 = {1: [2, 3]}
|
|
10
|
-
t2 = {2: [4]}
|
|
11
|
-
|
|
12
|
-
result = merge_transitions(t1, t2)
|
|
13
|
-
expected_result = {1: [2, 3], 2: [4]}
|
|
14
|
-
|
|
15
|
-
self.assertEqual(result, expected_result)
|
|
16
|
-
|
|
17
|
-
def test_merging_transitions_with_a_from_node_present_in_both_operands(self):
|
|
18
|
-
t1 = {1: [2, 3]}
|
|
19
|
-
t2 = {1: [4]}
|
|
20
|
-
|
|
21
|
-
result = merge_transitions(t1, t2)
|
|
22
|
-
expected_result = {1: [2, 3, 4]}
|
|
23
|
-
|
|
24
|
-
self.assertEqual(result, expected_result)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if __name__ == "__main__":
|
|
28
|
-
unittest.main()
|
|
File without changes
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
__package__ = __package__ or "tests.analyses.decompiler" # pylint:disable=redefined-builtin
|
|
3
|
-
|
|
4
|
-
import os.path
|
|
5
|
-
import unittest
|
|
6
|
-
|
|
7
|
-
import angr
|
|
8
|
-
import ailment
|
|
9
|
-
from angr.analyses.decompiler.optimization_passes.base_ptr_save_simplifier import (
|
|
10
|
-
BasePointerSaveSimplifier,
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
from ...common import bin_location
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
test_location = os.path.join(bin_location, "tests")
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def _get_block(clinic, addr):
|
|
20
|
-
for block in clinic.graph.nodes():
|
|
21
|
-
if block.addr == addr:
|
|
22
|
-
return block
|
|
23
|
-
return None
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def check_bp_save_fauxware(arch):
|
|
27
|
-
p = angr.Project(os.path.join(test_location, arch, "fauxware"), auto_load_libs=False)
|
|
28
|
-
cfg = p.analyses.CFGFast(normalize=True)
|
|
29
|
-
main = p.kb.functions["main"]
|
|
30
|
-
optimization_passes = [BasePointerSaveSimplifier]
|
|
31
|
-
dra = p.analyses.Decompiler(main, cfg=cfg, optimization_passes=optimization_passes)
|
|
32
|
-
first_block_stmts = dra.codegen._sequence.nodes[0].nodes[0].statements
|
|
33
|
-
for stmt in first_block_stmts:
|
|
34
|
-
if isinstance(stmt, ailment.Stmt.Store):
|
|
35
|
-
assert not (isinstance(stmt.data, ailment.Expr.Register) and stmt.data.reg_offset == p.arch.bp_offset) or (
|
|
36
|
-
isinstance(stmt.data, ailment.Expr.StackBaseOffset) and stmt.data.offset == 0
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
# pylint: disable=missing-class-docstring
|
|
41
|
-
# pylint: disable=no-self-use
|
|
42
|
-
class TestBaseptrSaveSimplifier(unittest.TestCase):
|
|
43
|
-
def test_baseptr_save_simplifier_amd64(self):
|
|
44
|
-
# decompile all:main and make sure the first and the last blocks do not save or restore to rbp
|
|
45
|
-
bin_path = os.path.join(test_location, "x86_64", "all")
|
|
46
|
-
proj = angr.Project(bin_path, auto_load_libs=False, load_debug_info=True)
|
|
47
|
-
|
|
48
|
-
cfg = proj.analyses.CFG(data_references=True, normalize=True)
|
|
49
|
-
|
|
50
|
-
optimization_passes = [BasePointerSaveSimplifier]
|
|
51
|
-
main_func = cfg.functions["main"]
|
|
52
|
-
dec = proj.analyses.Decompiler(main_func, cfg=cfg, optimization_passes=optimization_passes)
|
|
53
|
-
|
|
54
|
-
entry_block = _get_block(dec.clinic, main_func.addr)
|
|
55
|
-
endpoint_block = _get_block(dec.clinic, next(iter(main_func.endpoints)).addr)
|
|
56
|
-
|
|
57
|
-
assert entry_block is not None
|
|
58
|
-
assert endpoint_block is not None
|
|
59
|
-
|
|
60
|
-
for stmt in entry_block.statements:
|
|
61
|
-
if isinstance(stmt, ailment.Stmt.Store) and isinstance(stmt.data, ailment.Expr.StackBaseOffset):
|
|
62
|
-
assert False, "Found a base-pointer saving statement in the first block."
|
|
63
|
-
|
|
64
|
-
for stmt in endpoint_block.statements:
|
|
65
|
-
if (
|
|
66
|
-
isinstance(stmt, ailment.Stmt.Assignment)
|
|
67
|
-
and isinstance(stmt.dst, ailment.Expr.Register)
|
|
68
|
-
and stmt.dst.reg_offset == proj.arch.bp_offset
|
|
69
|
-
):
|
|
70
|
-
assert False, "Found a base-pointer restoring statement in the last block."
|
|
71
|
-
|
|
72
|
-
def test_bp_save_amd64_fauxware(self):
|
|
73
|
-
check_bp_save_fauxware("x86_64")
|
|
74
|
-
|
|
75
|
-
def test_bp_save_armel_fauxware(self):
|
|
76
|
-
check_bp_save_fauxware("armel")
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if __name__ == "__main__":
|
|
80
|
-
unittest.main()
|