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,464 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
__package__ = __package__ or "tests.analyses" # pylint:disable=redefined-builtin
|
|
3
|
-
|
|
4
|
-
import os
|
|
5
|
-
import logging
|
|
6
|
-
import unittest
|
|
7
|
-
|
|
8
|
-
import angr
|
|
9
|
-
from angr.sim_variable import SimStackVariable, SimRegisterVariable
|
|
10
|
-
from angr.knowledge_plugins.variables import VariableType
|
|
11
|
-
|
|
12
|
-
from ..common import bin_location
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
test_location = os.path.join(bin_location, "tests")
|
|
16
|
-
|
|
17
|
-
l = logging.getLogger("test_variablerecovery")
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
#
|
|
21
|
-
# Utility methods
|
|
22
|
-
#
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class TestVariableRecovery(unittest.TestCase):
|
|
26
|
-
def _compare_memory_variable(self, variable, variable_info):
|
|
27
|
-
if variable_info["location"] == "stack":
|
|
28
|
-
if not isinstance(variable, SimStackVariable):
|
|
29
|
-
return False
|
|
30
|
-
|
|
31
|
-
# base
|
|
32
|
-
if "base" in variable_info:
|
|
33
|
-
base = variable_info["base"]
|
|
34
|
-
if variable.base != base:
|
|
35
|
-
return False
|
|
36
|
-
|
|
37
|
-
# offset
|
|
38
|
-
if "offset" in variable_info:
|
|
39
|
-
offset = variable_info["offset"]
|
|
40
|
-
if variable.offset != offset:
|
|
41
|
-
return False
|
|
42
|
-
|
|
43
|
-
# size
|
|
44
|
-
if "size" in variable_info:
|
|
45
|
-
size = variable_info["size"]
|
|
46
|
-
if variable.size != size:
|
|
47
|
-
return False
|
|
48
|
-
|
|
49
|
-
return True
|
|
50
|
-
|
|
51
|
-
else:
|
|
52
|
-
if isinstance(variable, SimStackVariable):
|
|
53
|
-
# it is not a variable on the stack
|
|
54
|
-
return False
|
|
55
|
-
|
|
56
|
-
raise NotImplementedError()
|
|
57
|
-
|
|
58
|
-
def _compare_register_variable(self, variable, variable_info): # pylint:disable=unused-argument
|
|
59
|
-
if not isinstance(variable, SimRegisterVariable):
|
|
60
|
-
return False
|
|
61
|
-
|
|
62
|
-
if "reg" in variable_info:
|
|
63
|
-
reg = variable_info["reg"]
|
|
64
|
-
if variable.reg != reg:
|
|
65
|
-
return False
|
|
66
|
-
|
|
67
|
-
if "size" in variable_info:
|
|
68
|
-
size = variable_info["size"]
|
|
69
|
-
if variable.size != size:
|
|
70
|
-
return False
|
|
71
|
-
|
|
72
|
-
return True
|
|
73
|
-
|
|
74
|
-
def _run_variable_recovery_analysis(self, func_name, groundtruth, is_fast):
|
|
75
|
-
binary_path = os.path.join(test_location, "x86_64", "fauxware")
|
|
76
|
-
project = angr.Project(binary_path, load_options={"auto_load_libs": False})
|
|
77
|
-
cfg = project.analyses.CFG(normalize=True)
|
|
78
|
-
func = cfg.kb.functions[func_name]
|
|
79
|
-
|
|
80
|
-
# Create a temporary KnowledgeBase instance
|
|
81
|
-
tmp_kb = angr.KnowledgeBase(project)
|
|
82
|
-
|
|
83
|
-
if is_fast:
|
|
84
|
-
l.debug("Running VariableRecoveryFast on function %r.", func)
|
|
85
|
-
vr = project.analyses.VariableRecoveryFast(func, kb=tmp_kb)
|
|
86
|
-
else:
|
|
87
|
-
l.debug("Running VariableRecovery on function %r.", func)
|
|
88
|
-
vr = project.analyses.VariableRecovery(func, kb=tmp_kb)
|
|
89
|
-
|
|
90
|
-
variable_manager = vr.variable_manager[func.addr]
|
|
91
|
-
|
|
92
|
-
for insn_addr, variables in groundtruth["variables_by_instruction"].items():
|
|
93
|
-
for var_info in variables:
|
|
94
|
-
var_sort = var_info["sort"]
|
|
95
|
-
vars_and_offset = variable_manager.find_variables_by_insn(insn_addr, var_sort)
|
|
96
|
-
|
|
97
|
-
# enumerate vars and find the variable that we want
|
|
98
|
-
if var_sort == VariableType.MEMORY:
|
|
99
|
-
the_var = next(
|
|
100
|
-
(var for var, _ in vars_and_offset if self._compare_memory_variable(var, var_info)),
|
|
101
|
-
None,
|
|
102
|
-
)
|
|
103
|
-
elif var_sort == VariableType.REGISTER:
|
|
104
|
-
the_var = next(
|
|
105
|
-
(var for var, _ in vars_and_offset if self._compare_register_variable(var, var_info)),
|
|
106
|
-
None,
|
|
107
|
-
)
|
|
108
|
-
else:
|
|
109
|
-
l.error("Unsupported variable sort %s.", var_sort)
|
|
110
|
-
assert False
|
|
111
|
-
|
|
112
|
-
assert (
|
|
113
|
-
the_var is not None
|
|
114
|
-
), "The variable {} in groundtruth at instruction {:#x} cannot be found in variable manager.".format(
|
|
115
|
-
var_info,
|
|
116
|
-
insn_addr,
|
|
117
|
-
)
|
|
118
|
-
l.debug("Found variable %s at %#x.", the_var, insn_addr)
|
|
119
|
-
|
|
120
|
-
for block_addr, variables in groundtruth["phi_variables_by_block"].items():
|
|
121
|
-
phi_variables = variable_manager.get_phi_variables(block_addr)
|
|
122
|
-
for var_info in variables:
|
|
123
|
-
var_sort = var_info["sort"]
|
|
124
|
-
|
|
125
|
-
# enumerate vars and find the variable that we want
|
|
126
|
-
if var_sort == VariableType.MEMORY:
|
|
127
|
-
the_var = next(
|
|
128
|
-
(var for var in phi_variables if self._compare_memory_variable(var, var_info)),
|
|
129
|
-
None,
|
|
130
|
-
)
|
|
131
|
-
elif var_sort == VariableType.REGISTER:
|
|
132
|
-
the_var = next(
|
|
133
|
-
(var for var in phi_variables if self._compare_register_variable(var, var_info)),
|
|
134
|
-
None,
|
|
135
|
-
)
|
|
136
|
-
else:
|
|
137
|
-
l.error("Unsupported variable sort %s.", var_sort)
|
|
138
|
-
assert False
|
|
139
|
-
|
|
140
|
-
assert (
|
|
141
|
-
the_var is not None
|
|
142
|
-
), "The phi variable {} in groundtruth at block {:#x} cannot be found in variable manager.".format(
|
|
143
|
-
var_info,
|
|
144
|
-
block_addr,
|
|
145
|
-
)
|
|
146
|
-
l.debug("Found phi variable %s at %#x.", the_var, block_addr)
|
|
147
|
-
|
|
148
|
-
def test_variable_recovery_fauxware_authenticate_true(self):
|
|
149
|
-
self._run_variable_recovery_analysis(
|
|
150
|
-
"authenticate",
|
|
151
|
-
{
|
|
152
|
-
"variables_by_instruction": {
|
|
153
|
-
0x40066C: [
|
|
154
|
-
{
|
|
155
|
-
"sort": VariableType.MEMORY,
|
|
156
|
-
"location": "stack",
|
|
157
|
-
"base": "bp",
|
|
158
|
-
"offset": -0x18,
|
|
159
|
-
"size": 8,
|
|
160
|
-
},
|
|
161
|
-
],
|
|
162
|
-
0x400670: [
|
|
163
|
-
{
|
|
164
|
-
"sort": VariableType.MEMORY,
|
|
165
|
-
"location": "stack",
|
|
166
|
-
"base": "bp",
|
|
167
|
-
"offset": -0x20,
|
|
168
|
-
"size": 8,
|
|
169
|
-
},
|
|
170
|
-
],
|
|
171
|
-
0x400674: [
|
|
172
|
-
{
|
|
173
|
-
"sort": VariableType.MEMORY,
|
|
174
|
-
"location": "stack",
|
|
175
|
-
"base": "bp",
|
|
176
|
-
"offset": -0x8,
|
|
177
|
-
"size": 1,
|
|
178
|
-
},
|
|
179
|
-
],
|
|
180
|
-
0x40067F: [
|
|
181
|
-
{
|
|
182
|
-
"sort": VariableType.MEMORY,
|
|
183
|
-
"location": "stack",
|
|
184
|
-
"base": "bp",
|
|
185
|
-
"offset": -0x20,
|
|
186
|
-
"size": 8,
|
|
187
|
-
},
|
|
188
|
-
],
|
|
189
|
-
0x400699: [
|
|
190
|
-
{
|
|
191
|
-
"sort": VariableType.MEMORY,
|
|
192
|
-
"location": "stack",
|
|
193
|
-
"base": "bp",
|
|
194
|
-
"offset": -0x18,
|
|
195
|
-
"size": 8,
|
|
196
|
-
},
|
|
197
|
-
],
|
|
198
|
-
0x4006AF: [
|
|
199
|
-
{
|
|
200
|
-
"sort": VariableType.MEMORY,
|
|
201
|
-
"location": "stack",
|
|
202
|
-
"base": "bp",
|
|
203
|
-
"offset": -0x4,
|
|
204
|
-
"size": 4,
|
|
205
|
-
},
|
|
206
|
-
],
|
|
207
|
-
0x4006B2: [
|
|
208
|
-
{
|
|
209
|
-
"sort": VariableType.MEMORY,
|
|
210
|
-
"location": "stack",
|
|
211
|
-
"base": "bp",
|
|
212
|
-
"offset": -0x10,
|
|
213
|
-
"size": 1,
|
|
214
|
-
},
|
|
215
|
-
],
|
|
216
|
-
},
|
|
217
|
-
"phi_variables_by_block": {
|
|
218
|
-
0x4006EB: [
|
|
219
|
-
{"sort": VariableType.REGISTER, "reg": 16, "size": 8},
|
|
220
|
-
{"sort": VariableType.REGISTER, "reg": 32, "size": 8},
|
|
221
|
-
{"sort": VariableType.REGISTER, "reg": 64, "size": 8},
|
|
222
|
-
{"sort": VariableType.REGISTER, "reg": 72, "size": 8},
|
|
223
|
-
]
|
|
224
|
-
},
|
|
225
|
-
},
|
|
226
|
-
True,
|
|
227
|
-
)
|
|
228
|
-
|
|
229
|
-
def test_variable_recovery_fauxware_authenticate_false(self):
|
|
230
|
-
self._run_variable_recovery_analysis(
|
|
231
|
-
"authenticate",
|
|
232
|
-
{
|
|
233
|
-
"variables_by_instruction": {
|
|
234
|
-
0x40066C: [
|
|
235
|
-
{
|
|
236
|
-
"sort": VariableType.MEMORY,
|
|
237
|
-
"location": "stack",
|
|
238
|
-
"base": "bp",
|
|
239
|
-
"offset": -0x18,
|
|
240
|
-
"size": 8,
|
|
241
|
-
},
|
|
242
|
-
],
|
|
243
|
-
0x400670: [
|
|
244
|
-
{
|
|
245
|
-
"sort": VariableType.MEMORY,
|
|
246
|
-
"location": "stack",
|
|
247
|
-
"base": "bp",
|
|
248
|
-
"offset": -0x20,
|
|
249
|
-
"size": 8,
|
|
250
|
-
},
|
|
251
|
-
],
|
|
252
|
-
0x400674: [
|
|
253
|
-
{
|
|
254
|
-
"sort": VariableType.MEMORY,
|
|
255
|
-
"location": "stack",
|
|
256
|
-
"base": "bp",
|
|
257
|
-
"offset": -0x8,
|
|
258
|
-
"size": 1,
|
|
259
|
-
},
|
|
260
|
-
],
|
|
261
|
-
0x40067F: [
|
|
262
|
-
{
|
|
263
|
-
"sort": VariableType.MEMORY,
|
|
264
|
-
"location": "stack",
|
|
265
|
-
"base": "bp",
|
|
266
|
-
"offset": -0x20,
|
|
267
|
-
"size": 8,
|
|
268
|
-
},
|
|
269
|
-
],
|
|
270
|
-
0x400699: [
|
|
271
|
-
{
|
|
272
|
-
"sort": VariableType.MEMORY,
|
|
273
|
-
"location": "stack",
|
|
274
|
-
"base": "bp",
|
|
275
|
-
"offset": -0x18,
|
|
276
|
-
"size": 8,
|
|
277
|
-
},
|
|
278
|
-
],
|
|
279
|
-
0x4006AF: [
|
|
280
|
-
{
|
|
281
|
-
"sort": VariableType.MEMORY,
|
|
282
|
-
"location": "stack",
|
|
283
|
-
"base": "bp",
|
|
284
|
-
"offset": -0x4,
|
|
285
|
-
"size": 4,
|
|
286
|
-
},
|
|
287
|
-
],
|
|
288
|
-
0x4006B2: [
|
|
289
|
-
{
|
|
290
|
-
"sort": VariableType.MEMORY,
|
|
291
|
-
"location": "stack",
|
|
292
|
-
"base": "bp",
|
|
293
|
-
"offset": -0x10,
|
|
294
|
-
"size": 1,
|
|
295
|
-
},
|
|
296
|
-
],
|
|
297
|
-
},
|
|
298
|
-
"phi_variables_by_block": {
|
|
299
|
-
0x4006EB: [
|
|
300
|
-
{"sort": VariableType.REGISTER, "reg": 16, "size": 8},
|
|
301
|
-
{"sort": VariableType.REGISTER, "reg": 32, "size": 8},
|
|
302
|
-
{"sort": VariableType.REGISTER, "reg": 64, "size": 8},
|
|
303
|
-
{"sort": VariableType.REGISTER, "reg": 72, "size": 8},
|
|
304
|
-
]
|
|
305
|
-
},
|
|
306
|
-
},
|
|
307
|
-
False,
|
|
308
|
-
)
|
|
309
|
-
|
|
310
|
-
def test_variable_recovery_fauxware_main_true(self):
|
|
311
|
-
self._run_variable_recovery_analysis(
|
|
312
|
-
"main",
|
|
313
|
-
{
|
|
314
|
-
"variables_by_instruction": {
|
|
315
|
-
0x400725: [
|
|
316
|
-
{
|
|
317
|
-
"sort": VariableType.MEMORY,
|
|
318
|
-
"location": "stack",
|
|
319
|
-
"base": "bp",
|
|
320
|
-
"offset": -0x34,
|
|
321
|
-
"size": 4,
|
|
322
|
-
},
|
|
323
|
-
],
|
|
324
|
-
0x400728: [
|
|
325
|
-
{
|
|
326
|
-
"sort": VariableType.MEMORY,
|
|
327
|
-
"location": "stack",
|
|
328
|
-
"base": "bp",
|
|
329
|
-
"offset": -0x40,
|
|
330
|
-
"size": 8,
|
|
331
|
-
},
|
|
332
|
-
],
|
|
333
|
-
0x40072C: [
|
|
334
|
-
{
|
|
335
|
-
"sort": VariableType.MEMORY,
|
|
336
|
-
"location": "stack",
|
|
337
|
-
"base": "bp",
|
|
338
|
-
"offset": -0x8,
|
|
339
|
-
"size": 1,
|
|
340
|
-
},
|
|
341
|
-
],
|
|
342
|
-
0x400730: [
|
|
343
|
-
{
|
|
344
|
-
"sort": VariableType.MEMORY,
|
|
345
|
-
"location": "stack",
|
|
346
|
-
"base": "bp",
|
|
347
|
-
"offset": -0x18,
|
|
348
|
-
"size": 1,
|
|
349
|
-
},
|
|
350
|
-
],
|
|
351
|
-
0x40073E: [
|
|
352
|
-
{
|
|
353
|
-
"sort": VariableType.MEMORY,
|
|
354
|
-
"location": "stack",
|
|
355
|
-
"base": "bp",
|
|
356
|
-
"offset": -0x10,
|
|
357
|
-
"size": 1,
|
|
358
|
-
},
|
|
359
|
-
],
|
|
360
|
-
0x400754: [
|
|
361
|
-
{
|
|
362
|
-
"sort": VariableType.MEMORY,
|
|
363
|
-
"location": "stack",
|
|
364
|
-
"base": "bp",
|
|
365
|
-
"offset": -0x24,
|
|
366
|
-
"size": 1,
|
|
367
|
-
},
|
|
368
|
-
],
|
|
369
|
-
0x400774: [
|
|
370
|
-
{
|
|
371
|
-
"sort": VariableType.MEMORY,
|
|
372
|
-
"location": "stack",
|
|
373
|
-
"base": "bp",
|
|
374
|
-
"offset": -0x20,
|
|
375
|
-
"size": 1,
|
|
376
|
-
},
|
|
377
|
-
],
|
|
378
|
-
},
|
|
379
|
-
"phi_variables_by_block": {},
|
|
380
|
-
},
|
|
381
|
-
True,
|
|
382
|
-
)
|
|
383
|
-
|
|
384
|
-
def test_variable_recovery_fauxware_main_false(self):
|
|
385
|
-
self._run_variable_recovery_analysis(
|
|
386
|
-
"main",
|
|
387
|
-
{
|
|
388
|
-
"variables_by_instruction": {
|
|
389
|
-
0x400725: [
|
|
390
|
-
{
|
|
391
|
-
"sort": VariableType.MEMORY,
|
|
392
|
-
"location": "stack",
|
|
393
|
-
"base": "bp",
|
|
394
|
-
"offset": -0x34,
|
|
395
|
-
"size": 4,
|
|
396
|
-
},
|
|
397
|
-
],
|
|
398
|
-
0x400728: [
|
|
399
|
-
{
|
|
400
|
-
"sort": VariableType.MEMORY,
|
|
401
|
-
"location": "stack",
|
|
402
|
-
"base": "bp",
|
|
403
|
-
"offset": -0x40,
|
|
404
|
-
"size": 8,
|
|
405
|
-
},
|
|
406
|
-
],
|
|
407
|
-
0x40072C: [
|
|
408
|
-
{
|
|
409
|
-
"sort": VariableType.MEMORY,
|
|
410
|
-
"location": "stack",
|
|
411
|
-
"base": "bp",
|
|
412
|
-
"offset": -0x8,
|
|
413
|
-
"size": 1,
|
|
414
|
-
},
|
|
415
|
-
],
|
|
416
|
-
0x400730: [
|
|
417
|
-
{
|
|
418
|
-
"sort": VariableType.MEMORY,
|
|
419
|
-
"location": "stack",
|
|
420
|
-
"base": "bp",
|
|
421
|
-
"offset": -0x18,
|
|
422
|
-
"size": 1,
|
|
423
|
-
},
|
|
424
|
-
],
|
|
425
|
-
0x40073E: [
|
|
426
|
-
{
|
|
427
|
-
"sort": VariableType.MEMORY,
|
|
428
|
-
"location": "stack",
|
|
429
|
-
"base": "bp",
|
|
430
|
-
"offset": -0x10,
|
|
431
|
-
"size": 1,
|
|
432
|
-
},
|
|
433
|
-
],
|
|
434
|
-
0x400754: [
|
|
435
|
-
{
|
|
436
|
-
"sort": VariableType.MEMORY,
|
|
437
|
-
"location": "stack",
|
|
438
|
-
"base": "bp",
|
|
439
|
-
"offset": -0x24,
|
|
440
|
-
"size": 1,
|
|
441
|
-
},
|
|
442
|
-
],
|
|
443
|
-
0x400774: [
|
|
444
|
-
{
|
|
445
|
-
"sort": VariableType.MEMORY,
|
|
446
|
-
"location": "stack",
|
|
447
|
-
"base": "bp",
|
|
448
|
-
"offset": -0x20,
|
|
449
|
-
"size": 1,
|
|
450
|
-
},
|
|
451
|
-
],
|
|
452
|
-
},
|
|
453
|
-
"phi_variables_by_block": {},
|
|
454
|
-
},
|
|
455
|
-
False,
|
|
456
|
-
)
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
if __name__ == "__main__":
|
|
460
|
-
l.setLevel(logging.DEBUG)
|
|
461
|
-
logging.getLogger("angr.analyses.variable_recovery_fast").setLevel(logging.DEBUG)
|
|
462
|
-
logging.getLogger("angr.analyses.variable_recovery").setLevel(logging.DEBUG)
|
|
463
|
-
|
|
464
|
-
unittest.main()
|
tests/analyses/test_vfg.py
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
__package__ = __package__ or "tests.analyses" # pylint:disable=redefined-builtin
|
|
3
|
-
|
|
4
|
-
import time
|
|
5
|
-
import os
|
|
6
|
-
import logging
|
|
7
|
-
import unittest
|
|
8
|
-
import claripy
|
|
9
|
-
|
|
10
|
-
import angr
|
|
11
|
-
|
|
12
|
-
from ..common import bin_location
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
test_location = os.path.join(bin_location, "tests")
|
|
16
|
-
l = logging.getLogger("angr_tests")
|
|
17
|
-
|
|
18
|
-
vfg_buffer_overflow_addresses = {"x86_64": 0x40055C}
|
|
19
|
-
|
|
20
|
-
vfg_1_addresses = {
|
|
21
|
-
"x86_64": {
|
|
22
|
-
0x40071D, # main
|
|
23
|
-
0x400510, # _puts
|
|
24
|
-
0x40073E, # main
|
|
25
|
-
0x400530, # _read
|
|
26
|
-
0x400754, # main
|
|
27
|
-
0x40076A, # main
|
|
28
|
-
0x400774, # main
|
|
29
|
-
0x40078A, # main
|
|
30
|
-
0x4007A0, # main
|
|
31
|
-
0x400664, # authenticate
|
|
32
|
-
0x400550, # _strcmp
|
|
33
|
-
0x40068E, # authenticate
|
|
34
|
-
0x400699, # authenticate
|
|
35
|
-
0x400560, # _open
|
|
36
|
-
0x4006AF, # authenticate
|
|
37
|
-
0x4006C8, # authenticate
|
|
38
|
-
0x4006DB, # authenticate
|
|
39
|
-
0x400692, # authenticate
|
|
40
|
-
0x4006DF, # authenticate
|
|
41
|
-
0x4006E6, # authenticate
|
|
42
|
-
0x4006EB, # authenticate
|
|
43
|
-
0x4007BD, # main
|
|
44
|
-
0x4006ED, # accepted
|
|
45
|
-
0x4006FB, # accepted
|
|
46
|
-
0x4007C7, # main
|
|
47
|
-
0x4007C9, # main
|
|
48
|
-
0x4006FD, # rejected
|
|
49
|
-
0x400520, # _printf
|
|
50
|
-
0x400713, # rejected
|
|
51
|
-
0x400570, # _exit
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
class TestVfg(unittest.TestCase):
|
|
57
|
-
def _run_vfg_buffer_overflow(self, arch):
|
|
58
|
-
# pylint: disable=no-member
|
|
59
|
-
proj = angr.Project(
|
|
60
|
-
os.path.join(test_location, arch, "basic_buffer_overflows"),
|
|
61
|
-
use_sim_procedures=True,
|
|
62
|
-
default_analysis_mode="symbolic",
|
|
63
|
-
auto_load_libs=False,
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
cfg = proj.analyses.CFGEmulated(context_sensitivity_level=1)
|
|
67
|
-
|
|
68
|
-
# For this test case, OPTIMIZE_IR does not work due to the way we are widening the states: an index variable
|
|
69
|
-
# directly goes to 0xffffffff, and when OPTIMIZE_IR is used, it does a signed comparison with 0x27, which
|
|
70
|
-
# eventually leads to the merged index variable covers all negative numbers and [0, 27]. This analysis result is
|
|
71
|
-
# correct but not accurate, and we suffer from it in this test case.
|
|
72
|
-
# The ultimate solution is to widen more carefully, or implement lookahead widening support.
|
|
73
|
-
# TODO: Solve this issue later
|
|
74
|
-
|
|
75
|
-
start = time.time()
|
|
76
|
-
function_start = vfg_buffer_overflow_addresses[arch]
|
|
77
|
-
vfg = proj.analyses.VFG(
|
|
78
|
-
cfg,
|
|
79
|
-
function_start=function_start,
|
|
80
|
-
context_sensitivity_level=2,
|
|
81
|
-
interfunction_level=4,
|
|
82
|
-
remove_options={angr.options.OPTIMIZE_IR},
|
|
83
|
-
)
|
|
84
|
-
end = time.time()
|
|
85
|
-
duration = end - start
|
|
86
|
-
|
|
87
|
-
l.info("VFG generation done in %f seconds.", duration)
|
|
88
|
-
|
|
89
|
-
# TODO: These are very weak conditions. Make them stronger!
|
|
90
|
-
assert len(vfg.final_states) > 0
|
|
91
|
-
states = vfg.final_states
|
|
92
|
-
assert len(states) == 2
|
|
93
|
-
stack_check_fail = proj._extern_obj.get_pseudo_addr("symbol hook: __stack_chk_fail")
|
|
94
|
-
assert {s.solver.eval_one(s.ip) for s in states} == {
|
|
95
|
-
stack_check_fail,
|
|
96
|
-
0x4005B4,
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
state = [s for s in states if s.solver.eval_one(s.ip) == 0x4005B4][0]
|
|
100
|
-
assert claripy.backends.vsa.is_true(state.stack_read(12, 4) >= 0x28)
|
|
101
|
-
|
|
102
|
-
def broken_vfg_buffer_overflow(self):
|
|
103
|
-
# Test for running VFG on a single function
|
|
104
|
-
self._run_vfg_buffer_overflow("x86_64")
|
|
105
|
-
|
|
106
|
-
#
|
|
107
|
-
# VFG test case 0
|
|
108
|
-
#
|
|
109
|
-
|
|
110
|
-
def test_vfg_0(self):
|
|
111
|
-
self._run_vfg_0("x86_64")
|
|
112
|
-
|
|
113
|
-
def _run_vfg_0(self, arch):
|
|
114
|
-
proj = angr.Project(
|
|
115
|
-
os.path.join(test_location, arch, "vfg_0"),
|
|
116
|
-
load_options={"auto_load_libs": False},
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
cfg = proj.analyses.CFG(normalize=True)
|
|
120
|
-
main = cfg.functions.function(name="main")
|
|
121
|
-
vfg = proj.analyses.VFG(
|
|
122
|
-
cfg,
|
|
123
|
-
start=main.addr,
|
|
124
|
-
context_sensitivity_level=1,
|
|
125
|
-
interfunction_level=3,
|
|
126
|
-
record_function_final_states=True,
|
|
127
|
-
max_iterations=80,
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
function_final_states = vfg._function_final_states
|
|
131
|
-
assert main.addr in function_final_states
|
|
132
|
-
|
|
133
|
-
final_state_main = next(iter(function_final_states[main.addr].values()))
|
|
134
|
-
stdout = final_state_main.posix.dumps(1)
|
|
135
|
-
|
|
136
|
-
assert stdout[:6] == b"i = 64"
|
|
137
|
-
# the following does not work without affine relation analysis
|
|
138
|
-
# assert stdout == "i = 64
|
|
139
|
-
|
|
140
|
-
#
|
|
141
|
-
# VFG test case 1
|
|
142
|
-
#
|
|
143
|
-
|
|
144
|
-
def _run_vfg_1(self, arch):
|
|
145
|
-
proj = angr.Project(
|
|
146
|
-
os.path.join(test_location, arch, "fauxware"), use_sim_procedures=True, auto_load_libs=False
|
|
147
|
-
)
|
|
148
|
-
|
|
149
|
-
cfg = proj.analyses.CFGEmulated()
|
|
150
|
-
vfg = proj.analyses.VFG(
|
|
151
|
-
cfg,
|
|
152
|
-
start=0x40071D,
|
|
153
|
-
context_sensitivity_level=10,
|
|
154
|
-
interfunction_level=10,
|
|
155
|
-
record_function_final_states=True,
|
|
156
|
-
)
|
|
157
|
-
|
|
158
|
-
all_block_addresses = {n.addr for n in vfg.graph.nodes()}
|
|
159
|
-
assert vfg_1_addresses[arch].issubset(all_block_addresses)
|
|
160
|
-
|
|
161
|
-
# return value for functions
|
|
162
|
-
|
|
163
|
-
# function authenticate has only two possible return values: 0 and 1
|
|
164
|
-
authenticate = cfg.functions.function(name="authenticate")
|
|
165
|
-
assert authenticate.addr in vfg.function_final_states
|
|
166
|
-
authenticate_final_states = vfg.function_final_states[authenticate.addr]
|
|
167
|
-
assert len(authenticate_final_states) == 1
|
|
168
|
-
authenticate_final_state = next(iter(authenticate_final_states.values()))
|
|
169
|
-
assert authenticate_final_state is not None
|
|
170
|
-
assert authenticate_final_state.solver.eval_upto(authenticate_final_state.regs.rax, 3) == [0, 1]
|
|
171
|
-
|
|
172
|
-
# optimal execution tests
|
|
173
|
-
# - the basic block after returning from `authenticate` should only be executed once
|
|
174
|
-
assert vfg._execution_counter[0x4007B3] == 1
|
|
175
|
-
# - the last basic block in `authenticate` should only be executed once (on a non-normalized CFG)
|
|
176
|
-
assert vfg._execution_counter[0x4006EB] == 1
|
|
177
|
-
|
|
178
|
-
def test_vfg_1(self):
|
|
179
|
-
# Test the code coverage of VFG
|
|
180
|
-
self._run_vfg_1("x86_64")
|
|
181
|
-
|
|
182
|
-
def test_vfg_resolving_indirect_calls(self):
|
|
183
|
-
# resolving indirect calls provided via a statically allocated list of function addresses
|
|
184
|
-
# the test binary is contributed by Luke Serné on angr Slack
|
|
185
|
-
proj = angr.Project(
|
|
186
|
-
os.path.join(test_location, "aarch64", "func-chain-aarch64"),
|
|
187
|
-
auto_load_libs=False,
|
|
188
|
-
)
|
|
189
|
-
cfg = proj.analyses.CFG(normalize=True)
|
|
190
|
-
vfg = proj.analyses.VFG(
|
|
191
|
-
cfg,
|
|
192
|
-
start=cfg.kb.functions["main"].addr,
|
|
193
|
-
context_sensitivity_level=1,
|
|
194
|
-
interfunction_level=1,
|
|
195
|
-
record_function_final_states=True,
|
|
196
|
-
)
|
|
197
|
-
|
|
198
|
-
# find the node with indirect call exits
|
|
199
|
-
expected_indirect_call_targets = {
|
|
200
|
-
(0x400808, 0x400754), # init_0
|
|
201
|
-
(0x400808, 0x400770), # init_1
|
|
202
|
-
(0x400808, 0x400790), # init_2
|
|
203
|
-
}
|
|
204
|
-
indirect_call_targets = set()
|
|
205
|
-
for block_addr in cfg.kb.functions["main"].block_addrs_set:
|
|
206
|
-
cfg_node = cfg.get_any_node(block_addr)
|
|
207
|
-
succs_and_jumpkinds = cfg_node.successors_and_jumpkinds()
|
|
208
|
-
if len(succs_and_jumpkinds) == 1 and succs_and_jumpkinds[0][1] == "Ijk_Call":
|
|
209
|
-
# does it lead to an UnresolvedCall?
|
|
210
|
-
if succs_and_jumpkinds[0][0].name == "UnresolvableCallTarget":
|
|
211
|
-
# found it!
|
|
212
|
-
for vfg_node in vfg.get_all_nodes(cfg_node.addr):
|
|
213
|
-
for successor_state in vfg_node.final_states:
|
|
214
|
-
if successor_state.history.jumpkind == "Ijk_Call":
|
|
215
|
-
indirect_call_targets.add((cfg_node.addr, successor_state.addr))
|
|
216
|
-
|
|
217
|
-
assert expected_indirect_call_targets == indirect_call_targets
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if __name__ == "__main__":
|
|
221
|
-
unittest.main()
|