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,463 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# Disable some pylint warnings: no-self-use, missing-docstring
|
|
3
|
-
# pylint: disable=R0201,C0111,bad-builtin
|
|
4
|
-
|
|
5
|
-
import os
|
|
6
|
-
import pickle
|
|
7
|
-
from unittest import TestCase, main
|
|
8
|
-
|
|
9
|
-
import ailment
|
|
10
|
-
import claripy
|
|
11
|
-
|
|
12
|
-
import angr
|
|
13
|
-
from angr.analyses import ReachingDefinitionsAnalysis, CFGFast, CompleteCallingConventionsAnalysis
|
|
14
|
-
from angr.code_location import CodeLocation, ExternalCodeLocation
|
|
15
|
-
from angr.analyses.reaching_definitions.rd_state import ReachingDefinitionsState
|
|
16
|
-
from angr.analyses.reaching_definitions.subject import Subject
|
|
17
|
-
from angr.analyses.reaching_definitions.dep_graph import DepGraph
|
|
18
|
-
from angr.block import Block
|
|
19
|
-
from angr.knowledge_plugins.key_definitions.live_definitions import LiveDefinitions
|
|
20
|
-
from angr.knowledge_plugins.key_definitions.atoms import AtomKind, GuardUse, Tmp, Register, MemoryLocation
|
|
21
|
-
from angr.knowledge_plugins.key_definitions.constants import ObservationPointType, OP_BEFORE, OP_AFTER
|
|
22
|
-
from angr.knowledge_plugins.key_definitions.live_definitions import Definition, SpOffset
|
|
23
|
-
from angr.storage.memory_mixins import MultiValuedMemory
|
|
24
|
-
from angr.storage.memory_object import SimMemoryObject
|
|
25
|
-
from angr.utils.constants import DEFAULT_STATEMENT
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class InsnAndNodeObserveTestingUtils:
|
|
29
|
-
@staticmethod
|
|
30
|
-
def assert_for_live_definitions(assertion, live_definition_1, live_definition_2):
|
|
31
|
-
list(
|
|
32
|
-
map(
|
|
33
|
-
lambda attr: {
|
|
34
|
-
assertion(getattr(live_definition_1, attr)._pages, getattr(live_definition_2, attr)._pages)
|
|
35
|
-
},
|
|
36
|
-
["registers", "stack", "memory"],
|
|
37
|
-
)
|
|
38
|
-
)
|
|
39
|
-
assertion(getattr(live_definition_1, "tmps"), getattr(live_definition_2, "tmps"))
|
|
40
|
-
|
|
41
|
-
@staticmethod
|
|
42
|
-
def filter(observed_results, observation_points):
|
|
43
|
-
# Return only the observed results associated with the observation points,
|
|
44
|
-
# and do not fail if an observation point do not appear in the observed results.
|
|
45
|
-
return list(
|
|
46
|
-
map(lambda key: observed_results[key], filter(lambda key: key in observed_results, observation_points))
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
@staticmethod
|
|
50
|
-
def setup(observation_points):
|
|
51
|
-
binary_path = _binary_path("all")
|
|
52
|
-
project = angr.Project(binary_path, load_options={"auto_load_libs": False})
|
|
53
|
-
cfg = project.analyses[CFGFast].prep()()
|
|
54
|
-
|
|
55
|
-
main_function = cfg.kb.functions["main"]
|
|
56
|
-
reaching_definitions = project.analyses[ReachingDefinitionsAnalysis].prep()(
|
|
57
|
-
subject=main_function,
|
|
58
|
-
observation_points=observation_points,
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
state = ReachingDefinitionsState(
|
|
62
|
-
CodeLocation(main_function.addr, None), project.arch, reaching_definitions.subject
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
return (project, main_function, reaching_definitions, state)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def _binary_path(binary_name, arch: str = "x86_64"):
|
|
69
|
-
tests_location = os.path.join(
|
|
70
|
-
os.path.dirname(os.path.realpath(__file__)), "..", "..", "..", "..", "binaries", "tests"
|
|
71
|
-
)
|
|
72
|
-
return os.path.join(tests_location, arch, binary_name)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def _result_path(binary_results_name):
|
|
76
|
-
return os.path.join(
|
|
77
|
-
os.path.dirname(os.path.realpath(__file__)), "results", "x86_64", binary_results_name + ".pickle"
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
class TestReachingDefinitions(TestCase):
|
|
82
|
-
def _run_reaching_definition_analysis_test(self, project, function, result_path, _extract_result):
|
|
83
|
-
tmp_kb = angr.KnowledgeBase(project)
|
|
84
|
-
reaching_definition = project.analyses[ReachingDefinitionsAnalysis].prep(kb=tmp_kb)(
|
|
85
|
-
subject=function,
|
|
86
|
-
observe_all=True,
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
result = _extract_result(reaching_definition)
|
|
90
|
-
|
|
91
|
-
# Uncomment these to regenerate the reference results... if you dare
|
|
92
|
-
# with open(result_path, "wb") as result_file:
|
|
93
|
-
# pickle.dump(result, result_file)
|
|
94
|
-
with open(result_path, "rb") as result_file:
|
|
95
|
-
expected_result = pickle.load(result_file)
|
|
96
|
-
|
|
97
|
-
self.assertListEqual(result, expected_result)
|
|
98
|
-
|
|
99
|
-
@staticmethod
|
|
100
|
-
def _extract_all_definitions_from_storage(storage: MultiValuedMemory):
|
|
101
|
-
all_defs = []
|
|
102
|
-
for page_id, page in storage._pages.items():
|
|
103
|
-
last_mo = None
|
|
104
|
-
for pos, n in enumerate(page.content):
|
|
105
|
-
if n is not None:
|
|
106
|
-
if type(n) is not set or len(n) == 1:
|
|
107
|
-
addr = page_id * 4096 + pos
|
|
108
|
-
if type(n) is set:
|
|
109
|
-
mo: SimMemoryObject = next(iter(n))
|
|
110
|
-
else:
|
|
111
|
-
mo: SimMemoryObject = n
|
|
112
|
-
if mo is not last_mo:
|
|
113
|
-
last_mo = mo
|
|
114
|
-
all_defs.append((addr, list(LiveDefinitions.extract_defs(mo.object))))
|
|
115
|
-
|
|
116
|
-
return all_defs
|
|
117
|
-
|
|
118
|
-
def test_reaching_definition_analysis_definitions(self):
|
|
119
|
-
def _result_extractor(rda):
|
|
120
|
-
unsorted_result = map(
|
|
121
|
-
lambda x: {
|
|
122
|
-
"key": x[0],
|
|
123
|
-
"register_definitions": self._extract_all_definitions_from_storage(x[1].registers),
|
|
124
|
-
"stack_definitions": self._extract_all_definitions_from_storage(x[1].stack),
|
|
125
|
-
"memory_definitions": self._extract_all_definitions_from_storage(x[1].memory),
|
|
126
|
-
},
|
|
127
|
-
[(k, v) for k, v in rda.observed_results.items() if k[0] != "stmt"],
|
|
128
|
-
)
|
|
129
|
-
return list(sorted(unsorted_result, key=lambda x: x["key"]))
|
|
130
|
-
|
|
131
|
-
binaries_and_results = list(
|
|
132
|
-
map(
|
|
133
|
-
lambda binary: (_binary_path(binary), _result_path(binary + "_definitions")),
|
|
134
|
-
["all", "fauxware", "loop"],
|
|
135
|
-
)
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
for binary, result_path in binaries_and_results:
|
|
139
|
-
project = angr.Project(binary, load_options={"auto_load_libs": False})
|
|
140
|
-
cfg = project.analyses[CFGFast].prep()()
|
|
141
|
-
function = cfg.kb.functions["main"]
|
|
142
|
-
|
|
143
|
-
self._run_reaching_definition_analysis_test(project, function, result_path, _result_extractor)
|
|
144
|
-
|
|
145
|
-
def test_reaching_definition_analysis_visited_blocks(self):
|
|
146
|
-
def _result_extractor(rda):
|
|
147
|
-
return list(sorted(rda.visited_blocks, key=lambda b: b.addr))
|
|
148
|
-
|
|
149
|
-
binaries_and_results = list(
|
|
150
|
-
map(
|
|
151
|
-
lambda binary: (_binary_path(binary), _result_path(binary + "_visited_blocks")),
|
|
152
|
-
["all", "fauxware", "loop"],
|
|
153
|
-
)
|
|
154
|
-
)
|
|
155
|
-
|
|
156
|
-
for binary, result_path in binaries_and_results:
|
|
157
|
-
project = angr.Project(binary, load_options={"auto_load_libs": False})
|
|
158
|
-
cfg = project.analyses[CFGFast].prep()()
|
|
159
|
-
function = cfg.kb.functions["main"]
|
|
160
|
-
|
|
161
|
-
self._run_reaching_definition_analysis_test(project, function, result_path, _result_extractor)
|
|
162
|
-
|
|
163
|
-
def test_node_observe(self):
|
|
164
|
-
# Create several different observation points
|
|
165
|
-
observation_points = [("node", 0x42, OP_AFTER), ("insn", 0x43, OP_AFTER)]
|
|
166
|
-
|
|
167
|
-
_, _, reaching_definition, state = InsnAndNodeObserveTestingUtils.setup(observation_points)
|
|
168
|
-
|
|
169
|
-
reaching_definition.node_observe(0x42, state, OP_AFTER)
|
|
170
|
-
|
|
171
|
-
results = InsnAndNodeObserveTestingUtils.filter(reaching_definition.observed_results, observation_points)
|
|
172
|
-
expected_results = [state.live_definitions]
|
|
173
|
-
|
|
174
|
-
self.assertEqual(results, expected_results)
|
|
175
|
-
|
|
176
|
-
def test_insn_observe_an_ailment_statement(self):
|
|
177
|
-
# Create several different observation points
|
|
178
|
-
observation_points = [("node", 0x42, OP_AFTER), ("insn", 0x43, OP_AFTER)]
|
|
179
|
-
|
|
180
|
-
_, main_function, reaching_definition, state = InsnAndNodeObserveTestingUtils.setup(observation_points)
|
|
181
|
-
|
|
182
|
-
# Here, the statement content does not matter, neither if it is really in the block or else…
|
|
183
|
-
statement = ailment.statement.DirtyStatement(0, None)
|
|
184
|
-
block = main_function._addr_to_block_node[main_function.addr] # pylint: disable=W0212
|
|
185
|
-
|
|
186
|
-
reaching_definition.insn_observe(0x43, statement, block, state, OP_AFTER)
|
|
187
|
-
|
|
188
|
-
results = InsnAndNodeObserveTestingUtils.filter(reaching_definition.observed_results, observation_points)
|
|
189
|
-
expected_results = [state.live_definitions]
|
|
190
|
-
|
|
191
|
-
self.assertGreater(len(results), 0)
|
|
192
|
-
list(
|
|
193
|
-
map(
|
|
194
|
-
lambda x: InsnAndNodeObserveTestingUtils.assert_for_live_definitions(self.assertEqual, x[0], x[1]),
|
|
195
|
-
zip(results, expected_results),
|
|
196
|
-
)
|
|
197
|
-
)
|
|
198
|
-
|
|
199
|
-
def test_insn_observe_before_an_imark_pyvex_statement(self):
|
|
200
|
-
# Create several different observation points
|
|
201
|
-
observation_points = [("node", 0x42, OP_AFTER), ("insn", 0x43, OP_BEFORE)]
|
|
202
|
-
|
|
203
|
-
project, main_function, reaching_definition, state = InsnAndNodeObserveTestingUtils.setup(observation_points)
|
|
204
|
-
|
|
205
|
-
code_block = main_function._addr_to_block_node[main_function.addr] # pylint: disable=W0212
|
|
206
|
-
block = Block(addr=0x43, byte_string=code_block.bytestr, project=project)
|
|
207
|
-
statement = block.vex.statements[0]
|
|
208
|
-
|
|
209
|
-
reaching_definition.insn_observe(0x43, statement, block, state, OP_BEFORE)
|
|
210
|
-
|
|
211
|
-
results = InsnAndNodeObserveTestingUtils.filter(reaching_definition.observed_results, observation_points)
|
|
212
|
-
expected_results = [state.live_definitions]
|
|
213
|
-
|
|
214
|
-
self.assertGreater(len(results), 0)
|
|
215
|
-
list(
|
|
216
|
-
map(
|
|
217
|
-
lambda x: InsnAndNodeObserveTestingUtils.assert_for_live_definitions(self.assertEqual, x[0], x[1]),
|
|
218
|
-
zip(results, expected_results),
|
|
219
|
-
)
|
|
220
|
-
)
|
|
221
|
-
|
|
222
|
-
def test_insn_observe_after_a_pyvex_statement(self):
|
|
223
|
-
# Create several different observation points
|
|
224
|
-
observation_points = [("node", 0x42, OP_AFTER), ("insn", 0x43, OP_AFTER)]
|
|
225
|
-
|
|
226
|
-
project, main_function, reaching_definition, state = InsnAndNodeObserveTestingUtils.setup(observation_points)
|
|
227
|
-
|
|
228
|
-
code_block = main_function._addr_to_block_node[main_function.addr] # pylint: disable=W0212
|
|
229
|
-
block = Block(addr=0x43, byte_string=code_block.bytestr, project=project)
|
|
230
|
-
# When observing OP_AFTER an instruction, the statement has to be the last of a block
|
|
231
|
-
# (or preceding an IMark)
|
|
232
|
-
statement = block.vex.statements[-1]
|
|
233
|
-
|
|
234
|
-
reaching_definition.insn_observe(0x43, statement, block, state, OP_AFTER)
|
|
235
|
-
|
|
236
|
-
results = InsnAndNodeObserveTestingUtils.filter(reaching_definition.observed_results, observation_points)
|
|
237
|
-
expected_results = [state.live_definitions]
|
|
238
|
-
|
|
239
|
-
self.assertGreater(len(results), 0)
|
|
240
|
-
list(
|
|
241
|
-
map(
|
|
242
|
-
lambda x: InsnAndNodeObserveTestingUtils.assert_for_live_definitions(self.assertEqual, x[0], x[1]),
|
|
243
|
-
zip(results, expected_results),
|
|
244
|
-
)
|
|
245
|
-
)
|
|
246
|
-
|
|
247
|
-
def test_reaching_definition_analysis_exposes_its_subject(self):
|
|
248
|
-
binary_path = _binary_path("all")
|
|
249
|
-
project = angr.Project(binary_path, load_options={"auto_load_libs": False})
|
|
250
|
-
cfg = project.analyses[CFGFast].prep()()
|
|
251
|
-
|
|
252
|
-
main_function = cfg.kb.functions["main"]
|
|
253
|
-
reaching_definitions = project.analyses[ReachingDefinitionsAnalysis].prep()(subject=main_function)
|
|
254
|
-
|
|
255
|
-
self.assertEqual(reaching_definitions.subject.__class__ is Subject, True)
|
|
256
|
-
|
|
257
|
-
def test_get_the_sp_from_a_reaching_definition(self):
|
|
258
|
-
binary = _binary_path("all")
|
|
259
|
-
project = angr.Project(binary, auto_load_libs=False)
|
|
260
|
-
cfg = project.analyses[CFGFast].prep()()
|
|
261
|
-
|
|
262
|
-
tmp_kb = angr.KnowledgeBase(project)
|
|
263
|
-
main_func = cfg.kb.functions["main"]
|
|
264
|
-
rda = project.analyses[ReachingDefinitionsAnalysis].prep(kb=tmp_kb)(subject=main_func, observe_all=True)
|
|
265
|
-
|
|
266
|
-
def _is_right_before_main_node(definition):
|
|
267
|
-
bloc, ins_addr, op_type = definition[0]
|
|
268
|
-
return bloc == "node" and ins_addr == main_func.addr and op_type == OP_BEFORE
|
|
269
|
-
|
|
270
|
-
reach_definition_at_main = next(filter(_is_right_before_main_node, rda.observed_results.items()))[1]
|
|
271
|
-
|
|
272
|
-
sp_value = reach_definition_at_main.get_sp()
|
|
273
|
-
|
|
274
|
-
self.assertEqual(sp_value, LiveDefinitions.INITIAL_SP_64BIT)
|
|
275
|
-
|
|
276
|
-
def test_dep_graph(self):
|
|
277
|
-
project = angr.Project(_binary_path("true"), auto_load_libs=False)
|
|
278
|
-
cfg = project.analyses[CFGFast].prep()()
|
|
279
|
-
main_func = cfg.functions["main"]
|
|
280
|
-
|
|
281
|
-
# build a def-use graph for main() of /bin/true without tmps.
|
|
282
|
-
# check that the only dependency of the first block's
|
|
283
|
-
# guard is the four cc registers
|
|
284
|
-
rda = project.analyses[ReachingDefinitionsAnalysis].prep()(
|
|
285
|
-
subject=main_func, track_tmps=False, track_consts=False, dep_graph=True
|
|
286
|
-
)
|
|
287
|
-
guard_use = list(
|
|
288
|
-
filter(
|
|
289
|
-
lambda def_: type(def_.atom) is GuardUse and def_.codeloc.block_addr == main_func.addr,
|
|
290
|
-
rda.dep_graph._graph.nodes(),
|
|
291
|
-
)
|
|
292
|
-
)[0]
|
|
293
|
-
preds = list(rda.dep_graph._graph.pred[guard_use])
|
|
294
|
-
self.assertEqual(len(preds), 1)
|
|
295
|
-
self.assertIsInstance(preds[0].atom, Register)
|
|
296
|
-
self.assertEqual(
|
|
297
|
-
preds[0].atom.reg_offset,
|
|
298
|
-
project.arch.registers["rdi"][0],
|
|
299
|
-
)
|
|
300
|
-
|
|
301
|
-
# build a def-use graph for main() of /bin/true. check that t7 in the first block is only used by the guard
|
|
302
|
-
rda = project.analyses[ReachingDefinitionsAnalysis].prep()(
|
|
303
|
-
subject=main_func, track_tmps=True, dep_graph=DepGraph()
|
|
304
|
-
)
|
|
305
|
-
tmp_7 = list(
|
|
306
|
-
filter(
|
|
307
|
-
lambda def_: type(def_.atom) is Tmp
|
|
308
|
-
and def_.atom.tmp_idx == 7
|
|
309
|
-
and def_.codeloc.block_addr == main_func.addr,
|
|
310
|
-
rda.dep_graph._graph.nodes(),
|
|
311
|
-
)
|
|
312
|
-
)[0]
|
|
313
|
-
self.assertEqual(len(rda.dep_graph._graph.succ[tmp_7]), 1)
|
|
314
|
-
self.assertEqual(type(list(rda.dep_graph._graph.succ[tmp_7])[0].atom), GuardUse)
|
|
315
|
-
|
|
316
|
-
def test_dep_graph_stack_variables(self):
|
|
317
|
-
bin_path = _binary_path("fauxware")
|
|
318
|
-
project = angr.Project(bin_path, auto_load_libs=False)
|
|
319
|
-
arch = project.arch
|
|
320
|
-
cfg = project.analyses[CFGFast].prep()()
|
|
321
|
-
main_func = cfg.functions["authenticate"]
|
|
322
|
-
|
|
323
|
-
rda: ReachingDefinitionsAnalysis = project.analyses[ReachingDefinitionsAnalysis].prep()(
|
|
324
|
-
subject=main_func, track_tmps=False, track_consts=False, dep_graph=True
|
|
325
|
-
)
|
|
326
|
-
dep_graph = rda.dep_graph
|
|
327
|
-
open_rdi = next(
|
|
328
|
-
iter(
|
|
329
|
-
filter(
|
|
330
|
-
lambda def_: isinstance(def_.atom, Register)
|
|
331
|
-
and def_.atom.reg_offset == arch.registers["rdi"][0]
|
|
332
|
-
and def_.codeloc.ins_addr == 0x4006A2,
|
|
333
|
-
dep_graph._graph.nodes(),
|
|
334
|
-
)
|
|
335
|
-
)
|
|
336
|
-
)
|
|
337
|
-
|
|
338
|
-
# 4006A2 mov rdi, rax
|
|
339
|
-
preds = list(dep_graph._graph.predecessors(open_rdi))
|
|
340
|
-
self.assertEqual(len(preds), 1)
|
|
341
|
-
rax: Definition = preds[0]
|
|
342
|
-
self.assertIsInstance(rax.atom, Register)
|
|
343
|
-
self.assertEqual(rax.atom.reg_offset, arch.registers["rax"][0])
|
|
344
|
-
self.assertEqual(rax.codeloc.ins_addr, 0x400699)
|
|
345
|
-
|
|
346
|
-
# 400699 mov rax, [rbp+file]
|
|
347
|
-
preds = list(dep_graph._graph.predecessors(rax))
|
|
348
|
-
self.assertEqual(len(preds), 1)
|
|
349
|
-
file_var: Definition = preds[0]
|
|
350
|
-
self.assertIsInstance(file_var.atom, MemoryLocation)
|
|
351
|
-
self.assertIsInstance(file_var.atom.addr, SpOffset)
|
|
352
|
-
self.assertEqual(file_var.atom.addr.offset, -32)
|
|
353
|
-
self.assertEqual(file_var.codeloc.ins_addr, 0x40066C)
|
|
354
|
-
|
|
355
|
-
# 40066C mov [rbp+file], rdi
|
|
356
|
-
preds = list(dep_graph._graph.predecessors(file_var))
|
|
357
|
-
self.assertEqual(len(preds), 1)
|
|
358
|
-
rdi: Definition = preds[0]
|
|
359
|
-
self.assertIsInstance(rdi.atom, Register)
|
|
360
|
-
self.assertEqual(rdi.atom.reg_offset, arch.registers["rdi"][0])
|
|
361
|
-
self.assertIsInstance(rdi.codeloc, ExternalCodeLocation)
|
|
362
|
-
|
|
363
|
-
def test_uses_function_call_arguments(self):
|
|
364
|
-
bin_path = _binary_path("fauxware")
|
|
365
|
-
project = angr.Project(bin_path, auto_load_libs=False)
|
|
366
|
-
arch = project.arch
|
|
367
|
-
cfg = project.analyses[CFGFast].prep()()
|
|
368
|
-
main_func = cfg.functions["main"]
|
|
369
|
-
|
|
370
|
-
project.analyses[CompleteCallingConventionsAnalysis].prep()(recover_variables=True)
|
|
371
|
-
rda = project.analyses[ReachingDefinitionsAnalysis].prep()(subject=main_func, track_tmps=False)
|
|
372
|
-
|
|
373
|
-
# 4007ae
|
|
374
|
-
# rsi and rdi are all used by authenticate()
|
|
375
|
-
code_location = CodeLocation(0x4007A0, DEFAULT_STATEMENT, ins_addr=0x4007AE)
|
|
376
|
-
uses = rda.all_uses.get_uses_by_location(code_location)
|
|
377
|
-
self.assertEqual(len(uses), 2)
|
|
378
|
-
auth_rdi = next(
|
|
379
|
-
iter(
|
|
380
|
-
filter(
|
|
381
|
-
lambda def_: isinstance(def_.atom, Register) and def_.atom.reg_offset == arch.registers["rdi"][0],
|
|
382
|
-
uses,
|
|
383
|
-
)
|
|
384
|
-
)
|
|
385
|
-
)
|
|
386
|
-
auth_rsi = next(
|
|
387
|
-
iter(
|
|
388
|
-
filter(
|
|
389
|
-
lambda def_: isinstance(def_.atom, Register) and def_.atom.reg_offset == arch.registers["rsi"][0],
|
|
390
|
-
uses,
|
|
391
|
-
)
|
|
392
|
-
)
|
|
393
|
-
)
|
|
394
|
-
|
|
395
|
-
# 4007AB mov rdi, rax
|
|
396
|
-
self.assertEqual(auth_rdi.codeloc.ins_addr, 0x4007AB)
|
|
397
|
-
|
|
398
|
-
# 4007A8 mov rsi, rdx
|
|
399
|
-
self.assertEqual(auth_rsi.codeloc.ins_addr, 0x4007A8)
|
|
400
|
-
|
|
401
|
-
def test_rda_on_a_block_without_cfg(self):
|
|
402
|
-
bin_path = _binary_path("fauxware")
|
|
403
|
-
project = angr.Project(bin_path, auto_load_libs=False)
|
|
404
|
-
|
|
405
|
-
block = project.factory.block(project.entry, cross_insn_opt=False)
|
|
406
|
-
_ = project.analyses[ReachingDefinitionsAnalysis].prep()(subject=block, track_tmps=False) # it should not crash
|
|
407
|
-
|
|
408
|
-
def test_partial_register_read(self):
|
|
409
|
-
bin_path = _binary_path("fauxware")
|
|
410
|
-
project = angr.Project(bin_path, auto_load_libs=False)
|
|
411
|
-
cfg = project.analyses[CFGFast].prep()()
|
|
412
|
-
rda = project.analyses[ReachingDefinitionsAnalysis].prep()(subject=cfg.kb.functions["main"], observe_all=True)
|
|
413
|
-
mv = rda.model.observed_results[("insn", 0x400765, OP_BEFORE)].registers.load(
|
|
414
|
-
project.arch.registers["edx"][0],
|
|
415
|
-
size=4,
|
|
416
|
-
endness=project.arch.register_endness,
|
|
417
|
-
)
|
|
418
|
-
assert claripy.is_true(mv.one_value() == claripy.BVV(1, 32))
|
|
419
|
-
|
|
420
|
-
def test_conditional_return(self):
|
|
421
|
-
bin_path = _binary_path("check_dap", arch="armel")
|
|
422
|
-
project = angr.Project(bin_path, auto_load_libs=False)
|
|
423
|
-
cfg = project.analyses[CFGFast].prep()(normalize=True)
|
|
424
|
-
rda = project.analyses[ReachingDefinitionsAnalysis].prep()(subject=cfg.kb.functions[0x93E0], observe_all=True)
|
|
425
|
-
sp_0 = rda.model.observed_results[("insn", 0x9410, OP_BEFORE)].registers.load(
|
|
426
|
-
project.arch.sp_offset,
|
|
427
|
-
size=4,
|
|
428
|
-
endness=project.arch.register_endness,
|
|
429
|
-
)
|
|
430
|
-
sp_1 = rda.model.observed_results[("insn", 0x9410, OP_AFTER)].registers.load(
|
|
431
|
-
project.arch.sp_offset,
|
|
432
|
-
size=4,
|
|
433
|
-
endness=project.arch.register_endness,
|
|
434
|
-
)
|
|
435
|
-
assert sp_0 == sp_1
|
|
436
|
-
|
|
437
|
-
def test_constants_not_stored_to_live_memory_defs(self):
|
|
438
|
-
# Ensure constants loaded from read-only sections are not stored back to memory definitions. If they are stored,
|
|
439
|
-
# we may accidentally pair them with TOP during state merging.
|
|
440
|
-
project = angr.Project(_binary_path("two_cond_func_call_with_const_arg", "armel"), auto_load_libs=False)
|
|
441
|
-
project.analyses.CFGFast()
|
|
442
|
-
project.analyses.CompleteCallingConventions(recover_variables=True)
|
|
443
|
-
rda = project.analyses.ReachingDefinitions("main", observe_all=True)
|
|
444
|
-
|
|
445
|
-
for info in rda.callsites_to("f"):
|
|
446
|
-
(defn,) = info.args_defns[0]
|
|
447
|
-
ld = rda.model.get_observation_by_insn(info.callsite, ObservationPointType.OP_BEFORE)
|
|
448
|
-
|
|
449
|
-
# Expect a singular mem predecessor
|
|
450
|
-
preds = rda.dep_graph.find_all_predecessors(defn, kind=AtomKind.MEMORY)
|
|
451
|
-
assert len(preds) == 1
|
|
452
|
-
|
|
453
|
-
# Verify not stored
|
|
454
|
-
with self.assertRaises(angr.errors.SimMemoryMissingError):
|
|
455
|
-
atom = preds[0].atom
|
|
456
|
-
ld.memory.load(atom.addr, atom.size)
|
|
457
|
-
|
|
458
|
-
# Verify expected constant value
|
|
459
|
-
assert ld.get_concrete_value_from_definition(defn) == 1337
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
if __name__ == "__main__":
|
|
463
|
-
main()
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
from unittest import mock
|
|
3
|
-
import unittest
|
|
4
|
-
|
|
5
|
-
import networkx
|
|
6
|
-
|
|
7
|
-
import ailment
|
|
8
|
-
|
|
9
|
-
from archinfo.arch_x86 import ArchX86
|
|
10
|
-
from angr.analyses.forward_analysis.visitors import FunctionGraphVisitor
|
|
11
|
-
from angr.analyses.reaching_definitions.subject import Subject, SubjectType
|
|
12
|
-
from angr.block import Block
|
|
13
|
-
from angr.knowledge_plugins import Function
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def _a_mock_function(address, name):
|
|
17
|
-
return Function(None, address, name=name, syscall=False, is_simprocedure=False, is_plt=False, returning=False)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class TestSubject(unittest.TestCase):
|
|
21
|
-
@mock.patch.object(Function, "_get_initial_binary_name", return_value="binary")
|
|
22
|
-
def test_can_be_instantiated_with_a_function(self, _):
|
|
23
|
-
function = _a_mock_function(0x42, "function_name")
|
|
24
|
-
subject = Subject(function)
|
|
25
|
-
|
|
26
|
-
assert subject.content == function
|
|
27
|
-
assert subject.type == SubjectType.Function
|
|
28
|
-
|
|
29
|
-
@mock.patch.object(Block, "_parse_vex_info", return_value=None)
|
|
30
|
-
def test_can_be_instantiated_with_a_block(self, _):
|
|
31
|
-
arch = ArchX86()
|
|
32
|
-
block = Block(0x42, byte_string=b"", arch=arch)
|
|
33
|
-
subject = Subject(block)
|
|
34
|
-
|
|
35
|
-
assert subject.content == block
|
|
36
|
-
assert subject.type == SubjectType.Block
|
|
37
|
-
|
|
38
|
-
def test_can_be_instantiated_with_an_ailment_block(self):
|
|
39
|
-
block = ailment.Block(0x42, original_size=4)
|
|
40
|
-
subject = Subject(block)
|
|
41
|
-
|
|
42
|
-
assert subject.content == block
|
|
43
|
-
assert subject.type == SubjectType.Block
|
|
44
|
-
|
|
45
|
-
def test_fails_when_instanciated_with_an_inadequate_object(self):
|
|
46
|
-
self.assertRaises(TypeError, Subject, "test-me", None)
|
|
47
|
-
|
|
48
|
-
@mock.patch.object(Function, "_get_initial_binary_name", return_value="binary")
|
|
49
|
-
@mock.patch.object(FunctionGraphVisitor, "sort_nodes")
|
|
50
|
-
def test_when_instanciated_with_a_function_need_other_attributes(self, _, __):
|
|
51
|
-
function = _a_mock_function(0x42, "function_name")
|
|
52
|
-
func_graph = networkx.DiGraph()
|
|
53
|
-
cc = "mock_cc"
|
|
54
|
-
|
|
55
|
-
subject = Subject(function, func_graph, cc)
|
|
56
|
-
|
|
57
|
-
assert subject.func_graph == func_graph
|
|
58
|
-
assert subject.cc == cc
|
|
59
|
-
|
|
60
|
-
def test_cc_attribute_should_raise_error_when_subject_is_a_block(self):
|
|
61
|
-
arch = ArchX86()
|
|
62
|
-
block = Block(0x42, byte_string=b"", arch=arch)
|
|
63
|
-
subject = Subject(block)
|
|
64
|
-
with self.assertRaises(TypeError):
|
|
65
|
-
_ = subject.cc
|
|
66
|
-
|
|
67
|
-
def test_func_graph_attribute_should_raise_error_when_subject_is_a_block(self):
|
|
68
|
-
arch = ArchX86()
|
|
69
|
-
block = Block(0x42, byte_string=b"", arch=arch)
|
|
70
|
-
subject = Subject(block)
|
|
71
|
-
with self.assertRaises(TypeError):
|
|
72
|
-
_ = subject.func_graph
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if __name__ == "__main__":
|
|
76
|
-
unittest.main()
|
tests/analyses/test_bindiff.py
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
__package__ = __package__ or "tests.analyses" # pylint:disable=redefined-builtin
|
|
3
|
-
|
|
4
|
-
import logging
|
|
5
|
-
import os
|
|
6
|
-
import unittest
|
|
7
|
-
|
|
8
|
-
import angr
|
|
9
|
-
|
|
10
|
-
from ..common import bin_location
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
l = logging.getLogger("angr.tests.test_bindiff")
|
|
14
|
-
|
|
15
|
-
test_location = os.path.join(bin_location, "tests")
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
# todo make a better test
|
|
19
|
-
# pylint: disable=missing-class-docstring
|
|
20
|
-
# pylint: disable=no-self-use
|
|
21
|
-
class TestBindiff(unittest.TestCase):
|
|
22
|
-
def test_bindiff_x86_64(self):
|
|
23
|
-
binary_path_1 = os.path.join(test_location, "x86_64", "bindiff_a")
|
|
24
|
-
binary_path_2 = os.path.join(test_location, "x86_64", "bindiff_b")
|
|
25
|
-
b = angr.Project(binary_path_1, load_options={"auto_load_libs": False})
|
|
26
|
-
b2 = angr.Project(binary_path_2, load_options={"auto_load_libs": False})
|
|
27
|
-
bindiff = b.analyses.BinDiff(b2)
|
|
28
|
-
|
|
29
|
-
identical_functions = bindiff.identical_functions
|
|
30
|
-
differing_functions = bindiff.differing_functions
|
|
31
|
-
unmatched_functions = bindiff.unmatched_functions
|
|
32
|
-
# check identical functions
|
|
33
|
-
assert (0x40064C, 0x40066A) in identical_functions
|
|
34
|
-
# check differing functions
|
|
35
|
-
assert (0x400616, 0x400616) in differing_functions
|
|
36
|
-
# check unmatched functions
|
|
37
|
-
assert len(unmatched_functions[0]) <= 1
|
|
38
|
-
assert len(unmatched_functions[1]) <= 2
|
|
39
|
-
# check for no major regressions
|
|
40
|
-
assert len(identical_functions) > len(differing_functions)
|
|
41
|
-
assert len(differing_functions) < 4
|
|
42
|
-
|
|
43
|
-
# check a function diff
|
|
44
|
-
fdiff = bindiff.get_function_diff(0x400616, 0x400616)
|
|
45
|
-
block_matches = {(a.addr, b.addr) for a, b in fdiff.block_matches}
|
|
46
|
-
assert (0x40064A, 0x400668) in block_matches
|
|
47
|
-
assert (0x400616, 0x400616) in block_matches
|
|
48
|
-
assert (0x40061E, 0x40061E) in block_matches
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if __name__ == "__main__":
|
|
52
|
-
unittest.main()
|