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,1123 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# pylint:disable=missing-class-docstring,no-self-use,wrong-import-order
|
|
3
|
-
__package__ = __package__ or "tests.analyses.cfg" # pylint:disable=redefined-builtin
|
|
4
|
-
|
|
5
|
-
import os
|
|
6
|
-
import logging
|
|
7
|
-
import unittest
|
|
8
|
-
|
|
9
|
-
import archinfo
|
|
10
|
-
import angr
|
|
11
|
-
from angr.analyses.cfg.cfg_fast import SegmentList
|
|
12
|
-
from angr.knowledge_plugins.cfg import CFGNode, CFGModel, MemoryDataSort
|
|
13
|
-
from angr.analyses.cfg.indirect_jump_resolvers import mips_elf_fast
|
|
14
|
-
|
|
15
|
-
from ...common import bin_location, slow_test
|
|
16
|
-
|
|
17
|
-
l = logging.getLogger("angr.tests.test_cfgfast")
|
|
18
|
-
|
|
19
|
-
test_location = os.path.join(bin_location, "tests")
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def cstring_to_unicode_string(cstr: bytes) -> bytes:
|
|
23
|
-
return b"".join((bytes([ch]) + b"\x00") for ch in cstr)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class TestCfgfast(unittest.TestCase):
|
|
27
|
-
def cfg_fast_functions_check(self, arch, binary_path, func_addrs, func_features):
|
|
28
|
-
"""
|
|
29
|
-
Generate a fast CFG on the given binary, and test if all specified functions are found
|
|
30
|
-
|
|
31
|
-
:param str arch: the architecture, will be prepended to `binary_path`
|
|
32
|
-
:param str binary_path: path to the binary under the architecture directory
|
|
33
|
-
:param dict func_addrs: A collection of function addresses that should be recovered
|
|
34
|
-
:param dict func_features: A collection of features for some of the functions
|
|
35
|
-
:return: None
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
-
path = os.path.join(test_location, arch, binary_path)
|
|
39
|
-
proj = angr.Project(path, load_options={"auto_load_libs": False})
|
|
40
|
-
|
|
41
|
-
cfg = proj.analyses.CFGFast()
|
|
42
|
-
assert set(cfg.kb.functions.keys()).issuperset(func_addrs)
|
|
43
|
-
|
|
44
|
-
for func_addr, feature_dict in func_features.items():
|
|
45
|
-
returning = feature_dict.get("returning", "undefined")
|
|
46
|
-
if returning != "undefined":
|
|
47
|
-
assert cfg.kb.functions.function(addr=func_addr).returning is returning
|
|
48
|
-
|
|
49
|
-
# Segment only
|
|
50
|
-
cfg = proj.analyses.CFGFast(force_segment=True)
|
|
51
|
-
assert set(cfg.kb.functions.keys()).issuperset(func_addrs)
|
|
52
|
-
|
|
53
|
-
for func_addr, feature_dict in func_features.items():
|
|
54
|
-
returning = feature_dict.get("returning", "undefined")
|
|
55
|
-
if returning != "undefined":
|
|
56
|
-
assert cfg.kb.functions.function(addr=func_addr).returning is returning
|
|
57
|
-
|
|
58
|
-
# with normalization enabled
|
|
59
|
-
cfg = proj.analyses.CFGFast(force_segment=True, normalize=True)
|
|
60
|
-
assert set(cfg.kb.functions.keys()).issuperset(func_addrs)
|
|
61
|
-
|
|
62
|
-
for func_addr, feature_dict in func_features.items():
|
|
63
|
-
returning = feature_dict.get("returning", "undefined")
|
|
64
|
-
if returning != "undefined":
|
|
65
|
-
assert cfg.kb.functions.function(addr=func_addr).returning is returning
|
|
66
|
-
|
|
67
|
-
def cfg_fast_edges_check(self, arch, binary_path, edges):
|
|
68
|
-
"""
|
|
69
|
-
Generate a fast CFG on the given binary, and test if all edges are found.
|
|
70
|
-
|
|
71
|
-
:param str arch: the architecture, will be prepended to `binary_path`
|
|
72
|
-
:param str binary_path: path to the binary under the architecture directory
|
|
73
|
-
:param list edges: a list of edges
|
|
74
|
-
:return: None
|
|
75
|
-
"""
|
|
76
|
-
|
|
77
|
-
path = os.path.join(test_location, arch, binary_path)
|
|
78
|
-
proj = angr.Project(path, load_options={"auto_load_libs": False})
|
|
79
|
-
|
|
80
|
-
cfg = proj.analyses.CFGFast()
|
|
81
|
-
|
|
82
|
-
for src, dst in edges:
|
|
83
|
-
src_node = cfg.model.get_any_node(src)
|
|
84
|
-
dst_node = cfg.model.get_any_node(dst)
|
|
85
|
-
assert src_node is not None, "CFG node 0x%x is not found." % src
|
|
86
|
-
assert dst_node is not None, "CFG node 0x%x is not found." % dst
|
|
87
|
-
assert dst_node in src_node.successors, "CFG edge {}-{} is not found.".format(
|
|
88
|
-
src_node,
|
|
89
|
-
dst_node,
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
def test_cfg_0(self):
|
|
93
|
-
functions = {
|
|
94
|
-
0x400410,
|
|
95
|
-
0x400420,
|
|
96
|
-
0x400430,
|
|
97
|
-
0x400440,
|
|
98
|
-
0x400470,
|
|
99
|
-
0x40052C,
|
|
100
|
-
0x40053C,
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function_features = {}
|
|
104
|
-
|
|
105
|
-
self.cfg_fast_functions_check("x86_64", "cfg_0", functions, function_features)
|
|
106
|
-
|
|
107
|
-
def test_cfg_0_pe(self):
|
|
108
|
-
functions = {
|
|
109
|
-
# 0x40150a, # currently angr identifies 0x40150e due to the way _func_addrs_from_prologues() is
|
|
110
|
-
# implemented. this issue can be resolved with a properly implemented approach like Byte-Weight
|
|
111
|
-
0x4014F0,
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function_features = {}
|
|
115
|
-
|
|
116
|
-
self.cfg_fast_functions_check("x86_64", "cfg_0_pe", functions, function_features)
|
|
117
|
-
|
|
118
|
-
def test_arm_function_merge(self):
|
|
119
|
-
# function 0x7bb88 is created due to a data hint in another block. this function should be merged with the
|
|
120
|
-
# previous function 0x7ba84
|
|
121
|
-
|
|
122
|
-
path = os.path.join(test_location, "armel", "tenda-httpd")
|
|
123
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
124
|
-
|
|
125
|
-
cfg = proj.analyses.CFGFast()
|
|
126
|
-
|
|
127
|
-
node_7bb88 = cfg.model.get_any_node(0x7BB88)
|
|
128
|
-
assert node_7bb88 is not None
|
|
129
|
-
assert node_7bb88.function_address == 0x7BA84
|
|
130
|
-
|
|
131
|
-
@slow_test
|
|
132
|
-
def test_busybox(self):
|
|
133
|
-
edges = {
|
|
134
|
-
(0x4091EC, 0x408DE0),
|
|
135
|
-
# call to putenv. address of putenv may change in the future
|
|
136
|
-
(
|
|
137
|
-
0x449ACC,
|
|
138
|
-
0x5003B8,
|
|
139
|
-
),
|
|
140
|
-
# call to free. address of free may change in the future
|
|
141
|
-
(
|
|
142
|
-
0x467CFC,
|
|
143
|
-
0x500014,
|
|
144
|
-
),
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
self.cfg_fast_edges_check("mipsel", "busybox", edges)
|
|
148
|
-
|
|
149
|
-
@slow_test
|
|
150
|
-
@unittest.skipUnless(
|
|
151
|
-
os.path.isfile("C:\\Windows\\System32\\ntoskrnl.exe"),
|
|
152
|
-
"ntoskrnl.exe does not exist on this system.",
|
|
153
|
-
)
|
|
154
|
-
def test_ntoskrnl(self):
|
|
155
|
-
# we cannot distribute ntoskrnl.exe. as a result, this test case is manual
|
|
156
|
-
path = "C:\\Windows\\System32\\ntoskrnl.exe"
|
|
157
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
158
|
-
_ = proj.analyses.CFG(data_references=True, normalize=True, show_progressbar=True)
|
|
159
|
-
|
|
160
|
-
# nothing should prevent us from finish creating the CFG
|
|
161
|
-
|
|
162
|
-
def test_fauxware_function_feauters_x86_64(self):
|
|
163
|
-
functions = {
|
|
164
|
-
0x4004E0,
|
|
165
|
-
0x400510,
|
|
166
|
-
0x400520,
|
|
167
|
-
0x400530,
|
|
168
|
-
0x400540,
|
|
169
|
-
0x400550,
|
|
170
|
-
0x400560,
|
|
171
|
-
0x400570, # .plt._exit
|
|
172
|
-
0x400580, # _start
|
|
173
|
-
0x4005AC,
|
|
174
|
-
0x4005D0,
|
|
175
|
-
0x400640,
|
|
176
|
-
0x400664,
|
|
177
|
-
0x4006ED,
|
|
178
|
-
0x4006FD,
|
|
179
|
-
0x40071D, # main
|
|
180
|
-
0x4007E0,
|
|
181
|
-
0x400870,
|
|
182
|
-
0x400880,
|
|
183
|
-
0x4008B8,
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function_features = {
|
|
187
|
-
0x400570: {"returning": False}, # plt.exit
|
|
188
|
-
0x4006FD: {"returning": False}, # rejected
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return_edges = {
|
|
192
|
-
(0x4006FB, 0x4007C7),
|
|
193
|
-
} # return from accepted to main
|
|
194
|
-
|
|
195
|
-
self.cfg_fast_functions_check("x86_64", "fauxware", functions, function_features)
|
|
196
|
-
self.cfg_fast_edges_check("x86_64", "fauxware", return_edges)
|
|
197
|
-
|
|
198
|
-
def test_fauxware_function_features_mips(self):
|
|
199
|
-
functions = {
|
|
200
|
-
0x400534, # _init
|
|
201
|
-
0x400574,
|
|
202
|
-
0x400598,
|
|
203
|
-
0x4005D0, # _ftext
|
|
204
|
-
0x4005DC,
|
|
205
|
-
0x400630, # __do_global_dtors_aux
|
|
206
|
-
0x4006D4, # frame_dummy
|
|
207
|
-
0x400708,
|
|
208
|
-
0x400710, # authenticate
|
|
209
|
-
0x400814, # accepted
|
|
210
|
-
0x400868, # rejected
|
|
211
|
-
0x4008C0, # main
|
|
212
|
-
0x400A34,
|
|
213
|
-
0x400A48, # __libc_csu_init
|
|
214
|
-
0x400AF8,
|
|
215
|
-
0x400B00, # __do_global_ctors_aux
|
|
216
|
-
0x400B58,
|
|
217
|
-
### plt entries
|
|
218
|
-
0x400B60, # strcmp
|
|
219
|
-
0x400B70, # read
|
|
220
|
-
0x400B80, # printf
|
|
221
|
-
0x400B90, # puts
|
|
222
|
-
0x400BA0, # exit
|
|
223
|
-
0x400BB0, # open
|
|
224
|
-
0x400BC0, # __libc_start_main
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
function_features = {
|
|
228
|
-
0x400868: { # rejected
|
|
229
|
-
"returning": False,
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return_edges = {
|
|
234
|
-
(0x40084C, 0x400A04),
|
|
235
|
-
} # returning edge from accepted to main
|
|
236
|
-
|
|
237
|
-
self.cfg_fast_functions_check("mips", "fauxware", functions, function_features)
|
|
238
|
-
self.cfg_fast_edges_check("mips", "fauxware", return_edges)
|
|
239
|
-
|
|
240
|
-
def test_mips_elf_fast_indirect_jump_resolver(self):
|
|
241
|
-
bin_path = os.path.join(test_location, "mips", "fauxware")
|
|
242
|
-
proj = angr.Project(bin_path, auto_load_libs=False)
|
|
243
|
-
# enable profiling for MipsElfFast
|
|
244
|
-
# FIXME: The result might be different if other test cases that run in parallel mess with the profiling setting
|
|
245
|
-
mips_elf_fast.enable_profiling()
|
|
246
|
-
_ = proj.analyses.CFG()
|
|
247
|
-
mips_elf_fast.disable_profiling()
|
|
248
|
-
assert mips_elf_fast.HITS_CASE_0 >= 10
|
|
249
|
-
|
|
250
|
-
def test_cfg_loop_unrolling(self):
|
|
251
|
-
edges = {
|
|
252
|
-
(0x400658, 0x400636),
|
|
253
|
-
(0x400658, 0x400661),
|
|
254
|
-
(0x400651, 0x400636),
|
|
255
|
-
(0x400651, 0x400661),
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
self.cfg_fast_edges_check("x86_64", "cfg_loop_unrolling", edges)
|
|
259
|
-
|
|
260
|
-
def test_cfg_switches_x86_64(self):
|
|
261
|
-
edges = {
|
|
262
|
-
# jump table 0 in func_0
|
|
263
|
-
(0x40053A, 0x400547),
|
|
264
|
-
(0x40053A, 0x400552),
|
|
265
|
-
(0x40053A, 0x40055D),
|
|
266
|
-
(0x40053A, 0x400568),
|
|
267
|
-
(0x40053A, 0x400573),
|
|
268
|
-
(0x40053A, 0x400580),
|
|
269
|
-
(0x40053A, 0x40058D),
|
|
270
|
-
# jump table 0 in func_1
|
|
271
|
-
(0x4005BC, 0x4005C9),
|
|
272
|
-
(0x4005BC, 0x4005D8),
|
|
273
|
-
(0x4005BC, 0x4005E7),
|
|
274
|
-
(0x4005BC, 0x4005F6),
|
|
275
|
-
(0x4005BC, 0x400605),
|
|
276
|
-
(0x4005BC, 0x400614),
|
|
277
|
-
(0x4005BC, 0x400623),
|
|
278
|
-
(0x4005BC, 0x400632),
|
|
279
|
-
(0x4005BC, 0x40063E),
|
|
280
|
-
(0x4005BC, 0x40064A),
|
|
281
|
-
(0x4005BC, 0x4006B0),
|
|
282
|
-
# jump table 1 in func_1
|
|
283
|
-
(0x40065A, 0x400667),
|
|
284
|
-
(0x40065A, 0x400673),
|
|
285
|
-
(0x40065A, 0x40067F),
|
|
286
|
-
(0x40065A, 0x40068B),
|
|
287
|
-
(0x40065A, 0x400697),
|
|
288
|
-
(0x40065A, 0x4006A3),
|
|
289
|
-
# jump table 0 in main
|
|
290
|
-
(0x4006E1, 0x4006EE),
|
|
291
|
-
(0x4006E1, 0x4006FA),
|
|
292
|
-
(0x4006E1, 0x40070B),
|
|
293
|
-
(0x4006E1, 0x40071C),
|
|
294
|
-
(0x4006E1, 0x40072D),
|
|
295
|
-
(0x4006E1, 0x40073E),
|
|
296
|
-
(0x4006E1, 0x40074F),
|
|
297
|
-
(0x4006E1, 0x40075B),
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
self.cfg_fast_edges_check("x86_64", "cfg_switches", edges)
|
|
301
|
-
|
|
302
|
-
def test_cfg_switches_armel(self):
|
|
303
|
-
edges = {
|
|
304
|
-
# jump table 0 in func_0
|
|
305
|
-
(0x10434, 0x10488),
|
|
306
|
-
(0x10434, 0x104E8),
|
|
307
|
-
(0x10434, 0x10498),
|
|
308
|
-
(0x10434, 0x104A8),
|
|
309
|
-
(0x10434, 0x104B8),
|
|
310
|
-
(0x10434, 0x104C8),
|
|
311
|
-
(0x10434, 0x104D8),
|
|
312
|
-
(0x10454, 0x104E8), # default case
|
|
313
|
-
# jump table 0 in func_1
|
|
314
|
-
(0x10524, 0x105CC),
|
|
315
|
-
(0x10524, 0x106B4),
|
|
316
|
-
(0x10524, 0x105D8),
|
|
317
|
-
(0x10524, 0x105E4),
|
|
318
|
-
(0x10524, 0x105F0),
|
|
319
|
-
(0x10524, 0x105FC),
|
|
320
|
-
(0x10524, 0x10608),
|
|
321
|
-
(0x10524, 0x10614),
|
|
322
|
-
(0x10524, 0x10620),
|
|
323
|
-
(0x10524, 0x1062C),
|
|
324
|
-
(0x10524, 0x10638),
|
|
325
|
-
(0x10534, 0x106B4), # default case
|
|
326
|
-
# jump table 1 in func_1
|
|
327
|
-
(0x10650, 0x106A4), # default case
|
|
328
|
-
(0x10640, 0x10668),
|
|
329
|
-
(0x10640, 0x10674),
|
|
330
|
-
(0x10640, 0x10680),
|
|
331
|
-
(0x10640, 0x1068C),
|
|
332
|
-
(0x10640, 0x10698),
|
|
333
|
-
# jump table 0 in main
|
|
334
|
-
(0x10734, 0x107FC),
|
|
335
|
-
(0x10734, 0x10808),
|
|
336
|
-
(0x10734, 0x10818),
|
|
337
|
-
(0x10734, 0x10828),
|
|
338
|
-
(0x10734, 0x10838),
|
|
339
|
-
(0x10734, 0x10848),
|
|
340
|
-
(0x10734, 0x10858),
|
|
341
|
-
(0x10734, 0x10864),
|
|
342
|
-
(0x10744, 0x10864), # default case
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
self.cfg_fast_edges_check("armel", "cfg_switches", edges)
|
|
346
|
-
|
|
347
|
-
def test_cfg_switches_s390x(self):
|
|
348
|
-
edges = {
|
|
349
|
-
# jump table 0 in func_0
|
|
350
|
-
(0x4007D4, 0x4007EA), # case 1
|
|
351
|
-
(0x4007D4, 0x4007F4), # case 3
|
|
352
|
-
(0x4007D4, 0x4007FE), # case 5
|
|
353
|
-
(0x4007D4, 0x400808), # case 7
|
|
354
|
-
(0x4007D4, 0x400812), # case 9
|
|
355
|
-
(0x4007D4, 0x40081C), # case 12
|
|
356
|
-
(0x4007C0, 0x4007CA), # default case
|
|
357
|
-
# jump table 0 in func_1
|
|
358
|
-
(0x400872, 0x4008AE), # case 2
|
|
359
|
-
(0x400872, 0x4008BE), # case 10
|
|
360
|
-
(0x400872, 0x4008CE), # case 12
|
|
361
|
-
(0x400872, 0x4008DE), # case 14
|
|
362
|
-
(0x400872, 0x4008EE), # case 15
|
|
363
|
-
(0x400872, 0x4008FE), # case 16
|
|
364
|
-
(0x400872, 0x40090E), # case 22
|
|
365
|
-
(0x400872, 0x40091E), # case 24
|
|
366
|
-
(0x400872, 0x40092E), # case 28
|
|
367
|
-
(0x400872, 0x400888), # case 38
|
|
368
|
-
(0x400848, 0x400854), # default case (1)
|
|
369
|
-
(0x400872, 0x400854), # default case (2)
|
|
370
|
-
# jump table 1 in func_1
|
|
371
|
-
(0x40093E, 0x400984), # case 1
|
|
372
|
-
(0x40093E, 0x400974), # case 2
|
|
373
|
-
(0x40093E, 0x400964), # case 3
|
|
374
|
-
(0x40093E, 0x400954), # case 4
|
|
375
|
-
(0x40093E, 0x400994), # case 5
|
|
376
|
-
(0x400898, 0x40089E), # default case (1)
|
|
377
|
-
# jump table 0 in main
|
|
378
|
-
# case 1, 3, 5, 7, 9: optimized out
|
|
379
|
-
(0x400638, 0x40064E), # case 2
|
|
380
|
-
(0x400638, 0x400692), # case 4
|
|
381
|
-
(0x400638, 0x4006A4), # case 6
|
|
382
|
-
(0x400638, 0x40066E), # case 8
|
|
383
|
-
(0x400638, 0x400680), # case 10
|
|
384
|
-
# case 45: optimized out
|
|
385
|
-
(0x40062C, 0x40065C), # default case
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
self.cfg_fast_edges_check("s390x", "cfg_switches", edges)
|
|
389
|
-
|
|
390
|
-
def test_cfg_about_time(self):
|
|
391
|
-
# This is to test the correctness of the PLT stub removal in CFGBase
|
|
392
|
-
proj = angr.Project(os.path.join(test_location, "x86_64", "about_time"), auto_load_libs=False)
|
|
393
|
-
cfg = proj.analyses.CFG()
|
|
394
|
-
|
|
395
|
-
# a PLT stub that should be removed
|
|
396
|
-
assert 0x401026 not in cfg.kb.functions
|
|
397
|
-
# a PLT stub that should be removed
|
|
398
|
-
assert 0x4010A6 not in cfg.kb.functions
|
|
399
|
-
# a PLT stub that should be removed
|
|
400
|
-
assert 0x40115E not in cfg.kb.functions
|
|
401
|
-
# the start function that should not be removed
|
|
402
|
-
assert proj.entry in cfg.kb.functions
|
|
403
|
-
|
|
404
|
-
def test_segment_list_0(self):
|
|
405
|
-
seg_list = SegmentList()
|
|
406
|
-
seg_list.occupy(0, 1, "code")
|
|
407
|
-
seg_list.occupy(2, 3, "code")
|
|
408
|
-
|
|
409
|
-
assert len(seg_list) == 2
|
|
410
|
-
assert seg_list._list[0].end == 1
|
|
411
|
-
assert seg_list._list[1].end == 5
|
|
412
|
-
assert seg_list.is_occupied(4)
|
|
413
|
-
assert seg_list.is_occupied(5) is False
|
|
414
|
-
|
|
415
|
-
def test_segment_list_1(self):
|
|
416
|
-
seg_list = SegmentList()
|
|
417
|
-
|
|
418
|
-
# They should be merged
|
|
419
|
-
seg_list.occupy(0, 1, "code")
|
|
420
|
-
seg_list.occupy(1, 2, "code")
|
|
421
|
-
|
|
422
|
-
assert len(seg_list) == 1
|
|
423
|
-
assert seg_list._list[0].start == 0
|
|
424
|
-
assert seg_list._list[0].end == 3
|
|
425
|
-
|
|
426
|
-
def test_segment_list_2(self):
|
|
427
|
-
seg_list = SegmentList()
|
|
428
|
-
|
|
429
|
-
# They should not be merged
|
|
430
|
-
seg_list.occupy(0, 1, "code")
|
|
431
|
-
seg_list.occupy(1, 2, "data")
|
|
432
|
-
|
|
433
|
-
assert len(seg_list) == 2
|
|
434
|
-
assert seg_list._list[0].start == 0
|
|
435
|
-
assert seg_list._list[0].end == 1
|
|
436
|
-
assert seg_list._list[1].start == 1
|
|
437
|
-
assert seg_list._list[1].end == 3
|
|
438
|
-
|
|
439
|
-
def test_segment_list_3(self):
|
|
440
|
-
seg_list = SegmentList()
|
|
441
|
-
|
|
442
|
-
# They should be merged, and create three different segments
|
|
443
|
-
seg_list.occupy(0, 5, "code")
|
|
444
|
-
seg_list.occupy(5, 5, "code")
|
|
445
|
-
seg_list.occupy(1, 2, "data")
|
|
446
|
-
|
|
447
|
-
assert len(seg_list) == 3
|
|
448
|
-
|
|
449
|
-
assert seg_list._list[0].start == 0
|
|
450
|
-
assert seg_list._list[0].end == 1
|
|
451
|
-
assert seg_list._list[0].sort == "code"
|
|
452
|
-
|
|
453
|
-
assert seg_list._list[1].start == 1
|
|
454
|
-
assert seg_list._list[1].end == 3
|
|
455
|
-
assert seg_list._list[1].sort == "data"
|
|
456
|
-
|
|
457
|
-
assert seg_list._list[2].start == 3
|
|
458
|
-
assert seg_list._list[2].end == 10
|
|
459
|
-
assert seg_list._list[2].sort == "code"
|
|
460
|
-
|
|
461
|
-
def test_segment_list_4(self):
|
|
462
|
-
seg_list = SegmentList()
|
|
463
|
-
|
|
464
|
-
seg_list.occupy(5, 5, "code")
|
|
465
|
-
seg_list.occupy(4, 1, "code")
|
|
466
|
-
seg_list.occupy(2, 2, "code")
|
|
467
|
-
|
|
468
|
-
assert len(seg_list) == 1
|
|
469
|
-
assert seg_list._list[0].start == 2
|
|
470
|
-
assert seg_list._list[0].end == 10
|
|
471
|
-
|
|
472
|
-
def test_segment_list_5(self):
|
|
473
|
-
seg_list = SegmentList()
|
|
474
|
-
|
|
475
|
-
seg_list.occupy(5, 5, "data")
|
|
476
|
-
seg_list.occupy(4, 1, "code")
|
|
477
|
-
seg_list.occupy(2, 2, "data")
|
|
478
|
-
|
|
479
|
-
assert len(seg_list) == 3
|
|
480
|
-
assert seg_list._list[0].start == 2
|
|
481
|
-
assert seg_list._list[2].end == 10
|
|
482
|
-
|
|
483
|
-
seg_list.occupy(3, 2, "data")
|
|
484
|
-
|
|
485
|
-
assert len(seg_list) == 1
|
|
486
|
-
assert seg_list._list[0].start == 2
|
|
487
|
-
assert seg_list._list[0].end == 10
|
|
488
|
-
|
|
489
|
-
def test_segment_list_6(self):
|
|
490
|
-
seg_list = SegmentList()
|
|
491
|
-
|
|
492
|
-
seg_list.occupy(10, 20, "code")
|
|
493
|
-
seg_list.occupy(9, 2, "data")
|
|
494
|
-
|
|
495
|
-
assert len(seg_list) == 2
|
|
496
|
-
assert seg_list._list[0].start == 9
|
|
497
|
-
assert seg_list._list[0].end == 11
|
|
498
|
-
assert seg_list._list[0].sort == "data"
|
|
499
|
-
|
|
500
|
-
assert seg_list._list[1].start == 11
|
|
501
|
-
assert seg_list._list[1].end == 30
|
|
502
|
-
assert seg_list._list[1].sort == "code"
|
|
503
|
-
|
|
504
|
-
#
|
|
505
|
-
# Serialization
|
|
506
|
-
#
|
|
507
|
-
|
|
508
|
-
def test_serialization_cfgnode(self):
|
|
509
|
-
path = os.path.join(test_location, "x86_64", "fauxware")
|
|
510
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
511
|
-
|
|
512
|
-
cfg = proj.analyses.CFGFast()
|
|
513
|
-
# the first node
|
|
514
|
-
node = cfg.model.get_any_node(proj.entry)
|
|
515
|
-
assert node is not None
|
|
516
|
-
|
|
517
|
-
b = node.serialize()
|
|
518
|
-
assert len(b) > 0
|
|
519
|
-
new_node = CFGNode.parse(b)
|
|
520
|
-
assert new_node.addr == node.addr
|
|
521
|
-
assert new_node.size == node.size
|
|
522
|
-
assert new_node.block_id == node.block_id
|
|
523
|
-
|
|
524
|
-
def test_serialization_cfgfast(self):
|
|
525
|
-
path = os.path.join(test_location, "x86_64", "fauxware")
|
|
526
|
-
proj1 = angr.Project(path, auto_load_libs=False)
|
|
527
|
-
proj2 = angr.Project(path, auto_load_libs=False)
|
|
528
|
-
|
|
529
|
-
cfg = proj1.analyses.CFGFast()
|
|
530
|
-
# parse the entire graph
|
|
531
|
-
b = cfg.model.serialize()
|
|
532
|
-
assert len(b) > 0
|
|
533
|
-
|
|
534
|
-
# simulate importing a cfg from another tool
|
|
535
|
-
cfg_model = CFGModel.parse(b, cfg_manager=proj2.kb.cfgs)
|
|
536
|
-
|
|
537
|
-
assert len(cfg_model.graph.nodes) == len(cfg.graph.nodes)
|
|
538
|
-
assert len(cfg_model.graph.edges) == len(cfg.graph.edges)
|
|
539
|
-
|
|
540
|
-
n1 = cfg.model.get_any_node(proj1.entry)
|
|
541
|
-
n2 = cfg_model.get_any_node(proj1.entry)
|
|
542
|
-
assert n1 == n2
|
|
543
|
-
|
|
544
|
-
#
|
|
545
|
-
# CFG instance copy
|
|
546
|
-
#
|
|
547
|
-
|
|
548
|
-
def test_cfg_copy(self):
|
|
549
|
-
path = os.path.join(test_location, "cgc", "CADET_00002")
|
|
550
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
551
|
-
|
|
552
|
-
cfg = proj.analyses.CFGFast()
|
|
553
|
-
cfg_copy = cfg.copy()
|
|
554
|
-
for attribute in cfg_copy.__dict__:
|
|
555
|
-
if attribute in ["_graph", "_seg_list", "_model"]:
|
|
556
|
-
continue
|
|
557
|
-
assert getattr(cfg, attribute) == getattr(cfg_copy, attribute)
|
|
558
|
-
|
|
559
|
-
assert id(cfg.model) != id(cfg_copy.model)
|
|
560
|
-
assert id(cfg.model.graph) != id(cfg_copy.model.graph)
|
|
561
|
-
assert id(cfg._seg_list) != id(cfg_copy._seg_list)
|
|
562
|
-
|
|
563
|
-
#
|
|
564
|
-
# Alignment bytes
|
|
565
|
-
#
|
|
566
|
-
|
|
567
|
-
def test_cfg_0_pe_msvc_debug_nocc(self):
|
|
568
|
-
filename = os.path.join("windows", "msvc_cfg_0_debug.exe")
|
|
569
|
-
proj = angr.Project(os.path.join(test_location, "x86_64", filename), auto_load_libs=False)
|
|
570
|
-
cfg = proj.analyses.CFGFast()
|
|
571
|
-
|
|
572
|
-
# make sure 0x140015683 is marked as alignments
|
|
573
|
-
sort = cfg._seg_list.occupied_by_sort(0x140016583)
|
|
574
|
-
assert sort == "alignment"
|
|
575
|
-
|
|
576
|
-
assert 0x140015683 not in cfg.kb.functions
|
|
577
|
-
|
|
578
|
-
#
|
|
579
|
-
# Indirect jump resolvers
|
|
580
|
-
#
|
|
581
|
-
|
|
582
|
-
# For test cases for jump table resolver, please refer to test_jumptables.py
|
|
583
|
-
|
|
584
|
-
def test_resolve_x86_elf_pic_plt(self):
|
|
585
|
-
path = os.path.join(test_location, "i386", "fauxware_pie")
|
|
586
|
-
proj = angr.Project(path, load_options={"auto_load_libs": False})
|
|
587
|
-
|
|
588
|
-
cfg = proj.analyses.CFGFast()
|
|
589
|
-
|
|
590
|
-
# puts
|
|
591
|
-
puts_node = cfg.model.get_any_node(0x4005B0)
|
|
592
|
-
assert puts_node is not None
|
|
593
|
-
|
|
594
|
-
# there should be only one successor, which jumps to SimProcedure puts
|
|
595
|
-
assert len(puts_node.successors) == 1
|
|
596
|
-
puts_successor = puts_node.successors[0]
|
|
597
|
-
assert puts_successor.addr == proj.loader.find_symbol("puts").rebased_addr
|
|
598
|
-
|
|
599
|
-
# the SimProcedure puts should have more than one successors, which are all return targets
|
|
600
|
-
assert len(puts_successor.successors) == 3
|
|
601
|
-
simputs_successor = puts_successor.successors
|
|
602
|
-
return_targets = {a.addr for a in simputs_successor}
|
|
603
|
-
assert return_targets == {0x400800, 0x40087E, 0x4008B6}
|
|
604
|
-
|
|
605
|
-
#
|
|
606
|
-
# Function names
|
|
607
|
-
#
|
|
608
|
-
|
|
609
|
-
def test_function_names_for_unloaded_libraries(self):
|
|
610
|
-
path = os.path.join(test_location, "i386", "fauxware_pie")
|
|
611
|
-
proj = angr.Project(path, load_options={"auto_load_libs": False})
|
|
612
|
-
|
|
613
|
-
cfg = proj.analyses.CFGFast()
|
|
614
|
-
|
|
615
|
-
function_names = [f.name if not f.is_plt else "plt_" + f.name for f in cfg.functions.values()]
|
|
616
|
-
|
|
617
|
-
assert "plt_puts" in function_names
|
|
618
|
-
assert "plt_read" in function_names
|
|
619
|
-
assert "plt___stack_chk_fail" in function_names
|
|
620
|
-
assert "plt_exit" in function_names
|
|
621
|
-
assert "puts" in function_names
|
|
622
|
-
assert "read" in function_names
|
|
623
|
-
assert "__stack_chk_fail" in function_names
|
|
624
|
-
assert "exit" in function_names
|
|
625
|
-
|
|
626
|
-
#
|
|
627
|
-
# Basic blocks
|
|
628
|
-
#
|
|
629
|
-
|
|
630
|
-
def test_block_instruction_addresses_armhf(self):
|
|
631
|
-
path = os.path.join(test_location, "armhf", "fauxware")
|
|
632
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
633
|
-
|
|
634
|
-
cfg = proj.analyses.CFGFast()
|
|
635
|
-
|
|
636
|
-
main_func = cfg.kb.functions["main"]
|
|
637
|
-
|
|
638
|
-
# all instruction addresses of the block must be odd
|
|
639
|
-
block = next(b for b in main_func.blocks if b.addr == main_func.addr)
|
|
640
|
-
|
|
641
|
-
assert len(block.instruction_addrs) == 12
|
|
642
|
-
for instr_addr in block.instruction_addrs:
|
|
643
|
-
assert instr_addr % 2 == 1
|
|
644
|
-
|
|
645
|
-
main_node = cfg.model.get_any_node(main_func.addr)
|
|
646
|
-
assert main_node is not None
|
|
647
|
-
assert len(main_node.instruction_addrs) == 12
|
|
648
|
-
for instr_addr in main_node.instruction_addrs:
|
|
649
|
-
assert instr_addr % 2 == 1
|
|
650
|
-
|
|
651
|
-
#
|
|
652
|
-
# Tail-call optimization detection
|
|
653
|
-
#
|
|
654
|
-
|
|
655
|
-
def test_tail_call_optimization_detection_armel(self):
|
|
656
|
-
# GitHub issue #1286
|
|
657
|
-
|
|
658
|
-
path = os.path.join(test_location, "armel", "Nucleo_read_hyperterminal-stripped.elf")
|
|
659
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
660
|
-
|
|
661
|
-
cfg = proj.analyses.CFGFast(
|
|
662
|
-
resolve_indirect_jumps=True,
|
|
663
|
-
force_complete_scan=False,
|
|
664
|
-
normalize=True,
|
|
665
|
-
symbols=False,
|
|
666
|
-
detect_tail_calls=True,
|
|
667
|
-
data_references=True,
|
|
668
|
-
)
|
|
669
|
-
|
|
670
|
-
all_func_addrs = set(cfg.functions.keys())
|
|
671
|
-
assert 0x80010B5 not in all_func_addrs
|
|
672
|
-
assert 0x8003EF9 not in all_func_addrs
|
|
673
|
-
assert 0x8008419 not in all_func_addrs
|
|
674
|
-
|
|
675
|
-
# Functions that are jumped to from tail-calls
|
|
676
|
-
tail_call_funcs = [
|
|
677
|
-
0x8002BC1,
|
|
678
|
-
0x80046C1,
|
|
679
|
-
0x8000281,
|
|
680
|
-
0x8001BDB,
|
|
681
|
-
0x8002839,
|
|
682
|
-
0x80037AD,
|
|
683
|
-
0x8002C09,
|
|
684
|
-
0x8004165,
|
|
685
|
-
0x8004BE1,
|
|
686
|
-
0x8002EB1,
|
|
687
|
-
]
|
|
688
|
-
for member in tail_call_funcs:
|
|
689
|
-
assert member in all_func_addrs
|
|
690
|
-
|
|
691
|
-
# also test for tailcall return addresses
|
|
692
|
-
|
|
693
|
-
# mapping of return blocks to return addrs that are the actual callers of certain tail-calls endpoints
|
|
694
|
-
tail_call_return_addrs = {
|
|
695
|
-
0x8002BD9: [0x800275F], # 0x8002bc1
|
|
696
|
-
0x80046D7: [0x800275F], # 0x80046c1
|
|
697
|
-
0x80046ED: [0x800275F], # 0x80046c1
|
|
698
|
-
0x8001BE7: [0x800068D, 0x8000695], # 0x8001bdb ??
|
|
699
|
-
0x800284D: [0x800028B, 0x80006E1, 0x80006E7], # 0x8002839
|
|
700
|
-
0x80037F5: [0x800270B, 0x8002733, 0x8002759, 0x800098F, 0x8000997], # 0x80037ad
|
|
701
|
-
0x80037EF: [0x800270B, 0x8002733, 0x8002759, 0x800098F, 0x8000997], # 0x80037ad
|
|
702
|
-
0x8002CC9: [
|
|
703
|
-
0x8002D3B,
|
|
704
|
-
0x8002B99,
|
|
705
|
-
0x8002E9F,
|
|
706
|
-
0x80041AD,
|
|
707
|
-
0x8004C87,
|
|
708
|
-
0x8004D35,
|
|
709
|
-
0x8002EFB,
|
|
710
|
-
0x8002BE9,
|
|
711
|
-
0x80046EB,
|
|
712
|
-
0x800464F,
|
|
713
|
-
0x8002A09,
|
|
714
|
-
0x800325F,
|
|
715
|
-
0x80047C1,
|
|
716
|
-
], # 0x8002c09
|
|
717
|
-
0x8004183: [0x8002713], # 0x8004165
|
|
718
|
-
0x8004C31: [0x8002713], # 0x8004be1
|
|
719
|
-
0x8004C69: [0x8002713], # 0x8004be1
|
|
720
|
-
0x8002EF1: [0x800273B],
|
|
721
|
-
} # 0x8002eb1
|
|
722
|
-
|
|
723
|
-
# check all expected return addrs are present
|
|
724
|
-
for returning_block_addr, expected_return_addrs in tail_call_return_addrs.items():
|
|
725
|
-
returning_block = cfg.model.get_any_node(returning_block_addr)
|
|
726
|
-
return_block_addrs = [rb.addr for rb in cfg.model.get_successors(returning_block)]
|
|
727
|
-
msg = "%x: unequal sizes of expected_addrs [%d] and return_block_addrs [%d]" % (
|
|
728
|
-
returning_block_addr,
|
|
729
|
-
len(expected_return_addrs),
|
|
730
|
-
len(return_block_addrs),
|
|
731
|
-
)
|
|
732
|
-
assert len(return_block_addrs) == len(expected_return_addrs), msg
|
|
733
|
-
for expected_addr in expected_return_addrs:
|
|
734
|
-
msg = "expected retaddr {:x} not found for returning_block {:x}".format(
|
|
735
|
-
expected_addr,
|
|
736
|
-
returning_block_addr,
|
|
737
|
-
)
|
|
738
|
-
assert expected_addr in return_block_addrs, msg
|
|
739
|
-
|
|
740
|
-
#
|
|
741
|
-
# Incorrect function-leading blocks merging
|
|
742
|
-
#
|
|
743
|
-
|
|
744
|
-
def test_function_leading_blocks_merging(self):
|
|
745
|
-
# GitHub issue #1312
|
|
746
|
-
|
|
747
|
-
path = os.path.join(test_location, "armel", "Nucleo_read_hyperterminal-stripped.elf")
|
|
748
|
-
proj = angr.Project(path, arch=archinfo.ArchARMCortexM(), auto_load_libs=False)
|
|
749
|
-
|
|
750
|
-
cfg = proj.analyses.CFGFast(
|
|
751
|
-
resolve_indirect_jumps=True,
|
|
752
|
-
force_complete_scan=True,
|
|
753
|
-
normalize=True,
|
|
754
|
-
symbols=False,
|
|
755
|
-
detect_tail_calls=True,
|
|
756
|
-
)
|
|
757
|
-
|
|
758
|
-
assert 0x8000799 in cfg.kb.functions
|
|
759
|
-
assert 0x800079B not in cfg.kb.functions
|
|
760
|
-
assert 0x800079B not in cfg.kb.functions[0x8000799].block_addrs_set
|
|
761
|
-
assert 0x8000799 in cfg.kb.functions[0x8000799].block_addrs_set
|
|
762
|
-
assert next(iter(b for b in cfg.kb.functions[0x8000799].blocks if b.addr == 0x8000799)).size == 6
|
|
763
|
-
|
|
764
|
-
#
|
|
765
|
-
# Blanket
|
|
766
|
-
#
|
|
767
|
-
|
|
768
|
-
def test_blanket_fauxware(self):
|
|
769
|
-
path = os.path.join(test_location, "x86_64", "fauxware")
|
|
770
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
771
|
-
|
|
772
|
-
cfg = proj.analyses.CFGFast()
|
|
773
|
-
|
|
774
|
-
cfb = proj.analyses.CFBlanket(kb=cfg.kb)
|
|
775
|
-
|
|
776
|
-
# it should raise a key error when calling floor_addr on address 0 because nothing is mapped there
|
|
777
|
-
# an instruction (or a block) starts at 0x400580
|
|
778
|
-
assert cfb.floor_addr(0x400581) == 0x400580
|
|
779
|
-
# a block ends at 0x4005a9 (exclusive)
|
|
780
|
-
assert cfb.ceiling_addr(0x400581) == 0x4005A9
|
|
781
|
-
|
|
782
|
-
#
|
|
783
|
-
# CFG with patches
|
|
784
|
-
#
|
|
785
|
-
|
|
786
|
-
def test_unresolvable_targets(self):
|
|
787
|
-
path = os.path.join(test_location, "cgc", "CADET_00002")
|
|
788
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
789
|
-
|
|
790
|
-
proj.analyses.CFGFast(normalize=True)
|
|
791
|
-
func = proj.kb.functions[0x080489E0]
|
|
792
|
-
|
|
793
|
-
true_endpoint_addrs = {0x8048BBC, 0x8048AF5, 0x8048B5C, 0x8048A41, 0x8048AA8}
|
|
794
|
-
endpoint_addrs = {node.addr for node in func.endpoints}
|
|
795
|
-
assert len(endpoint_addrs.symmetric_difference(true_endpoint_addrs)) == 0
|
|
796
|
-
|
|
797
|
-
def test_indirect_jump_to_outside(self):
|
|
798
|
-
# an indirect jump might be jumping to outside as well
|
|
799
|
-
path = os.path.join(test_location, "mipsel", "libndpi.so.4.0.0")
|
|
800
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
801
|
-
|
|
802
|
-
cfg = proj.analyses.CFGFast()
|
|
803
|
-
|
|
804
|
-
assert len(list(cfg.functions[0x404EE4].blocks)) == 3
|
|
805
|
-
assert {ep.addr for ep in cfg.functions[0x404EE4].endpoints} == {
|
|
806
|
-
0x404F00,
|
|
807
|
-
0x404F08,
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
def test_plt_stub_has_one_jumpout_site(self):
|
|
811
|
-
# each PLT stub must have exactly one jumpout site
|
|
812
|
-
path = os.path.join(test_location, "x86_64", "1after909")
|
|
813
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
814
|
-
cfg = proj.analyses.CFGFast()
|
|
815
|
-
|
|
816
|
-
for func in cfg.kb.functions.values():
|
|
817
|
-
if func.is_plt:
|
|
818
|
-
assert len(func.jumpout_sites) == 1
|
|
819
|
-
|
|
820
|
-
def test_generate_special_info(self):
|
|
821
|
-
path = os.path.join(test_location, "mipsel", "fauxware")
|
|
822
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
823
|
-
|
|
824
|
-
cfg = proj.analyses.CFGFast()
|
|
825
|
-
|
|
826
|
-
assert any(func.info for func in cfg.functions.values())
|
|
827
|
-
assert cfg.functions["main"].info["gp"] == 0x418CA0
|
|
828
|
-
|
|
829
|
-
def test_load_from_shellcode(self):
|
|
830
|
-
proj = angr.load_shellcode("loop: dec ecx; jnz loop; ret", "x86")
|
|
831
|
-
cfg = proj.analyses.CFGFast()
|
|
832
|
-
|
|
833
|
-
assert len(cfg.model.nodes()) == 2
|
|
834
|
-
|
|
835
|
-
def test_starting_point_ordering(self):
|
|
836
|
-
# project entry should always be first
|
|
837
|
-
# so edge/path to unlabeled main function from _start
|
|
838
|
-
# is correctly generated
|
|
839
|
-
|
|
840
|
-
path = os.path.join(test_location, "armel", "start_ordering")
|
|
841
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
842
|
-
cfg = proj.analyses.CFGFast()
|
|
843
|
-
|
|
844
|
-
# if ordering is incorrect, edge to function 0x103D4 will not exist
|
|
845
|
-
n = cfg.model.get_any_node(proj.entry)
|
|
846
|
-
assert n is not None
|
|
847
|
-
assert len(n.successors) > 0
|
|
848
|
-
assert len(n.successors[0].successors) > 0
|
|
849
|
-
assert len(n.successors[0].successors[0].successors) == 3
|
|
850
|
-
|
|
851
|
-
# now checking if path to the "real main" exists
|
|
852
|
-
assert len(n.successors[0].successors[0].successors[1].successors) > 0
|
|
853
|
-
n = n.successors[0].successors[0].successors[1].successors[0]
|
|
854
|
-
|
|
855
|
-
assert len(n.successors) > 0
|
|
856
|
-
assert len(n.successors[0].successors) > 0
|
|
857
|
-
assert len(n.successors[0].successors[0].successors) > 0
|
|
858
|
-
assert n.successors[0].successors[0].successors[0].addr == 0x103D4
|
|
859
|
-
|
|
860
|
-
def test_error_returning(self):
|
|
861
|
-
# error() is a great function: its returning depends on the value of the first argument...
|
|
862
|
-
path = os.path.join(test_location, "x86_64", "mv_-O2")
|
|
863
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
864
|
-
cfg = proj.analyses.CFGFast()
|
|
865
|
-
|
|
866
|
-
error_not_returning = [
|
|
867
|
-
0x4030D4,
|
|
868
|
-
0x403100,
|
|
869
|
-
0x40313C,
|
|
870
|
-
0x4031F5,
|
|
871
|
-
0x40348A,
|
|
872
|
-
]
|
|
873
|
-
|
|
874
|
-
error_returning = [0x403179, 0x4031A2, 0x403981, 0x403E30, 0x40403B]
|
|
875
|
-
|
|
876
|
-
for error_site in error_not_returning:
|
|
877
|
-
node = cfg.model.get_any_node(error_site)
|
|
878
|
-
assert len(list(cfg.model.get_successors(node, excluding_fakeret=False))) == 1 # only the call successor
|
|
879
|
-
|
|
880
|
-
for error_site in error_returning:
|
|
881
|
-
node = cfg.model.get_any_node(error_site)
|
|
882
|
-
assert len(list(cfg.model.get_successors(node, excluding_fakeret=False))) == 2 # both a call and a fakeret
|
|
883
|
-
|
|
884
|
-
def test_kepler_server_armhf(self):
|
|
885
|
-
binary_path = os.path.join(test_location, "armhf", "kepler_server")
|
|
886
|
-
proj = angr.Project(binary_path, auto_load_libs=False)
|
|
887
|
-
cfg = proj.analyses.CFG(
|
|
888
|
-
normalize=True,
|
|
889
|
-
indirect_calls_always_return=False,
|
|
890
|
-
)
|
|
891
|
-
|
|
892
|
-
func_main = cfg.kb.functions[0x10329]
|
|
893
|
-
assert func_main.returning is False
|
|
894
|
-
|
|
895
|
-
func_0 = cfg.kb.functions[0x15EE9]
|
|
896
|
-
assert func_0.returning is False
|
|
897
|
-
assert len(func_0.block_addrs_set) == 1
|
|
898
|
-
|
|
899
|
-
func_1 = cfg.kb.functions[0x15D2D]
|
|
900
|
-
assert func_1.returning is False
|
|
901
|
-
|
|
902
|
-
func_2 = cfg.kb.functions[0x228C5]
|
|
903
|
-
assert func_2.returning is False
|
|
904
|
-
|
|
905
|
-
func_3 = cfg.kb.functions[0x12631]
|
|
906
|
-
assert func_3.returning is True
|
|
907
|
-
|
|
908
|
-
def test_func_in_added_segment_by_patcherex_arm(self):
|
|
909
|
-
path = os.path.join(test_location, "armel", "patcherex", "replace_function_patch_with_function_reference")
|
|
910
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
911
|
-
cfg = proj.analyses.CFGFast(
|
|
912
|
-
normalize=True,
|
|
913
|
-
function_starts={0xA00081},
|
|
914
|
-
regions=[
|
|
915
|
-
(4195232, 4195244),
|
|
916
|
-
(4195244, 4195324),
|
|
917
|
-
(4195324, 4196016),
|
|
918
|
-
(4196016, 4196024),
|
|
919
|
-
(10485888, 10485950),
|
|
920
|
-
],
|
|
921
|
-
)
|
|
922
|
-
|
|
923
|
-
# Check whether the target function is in the functions list
|
|
924
|
-
assert 0xA00081 in cfg.kb.functions
|
|
925
|
-
# Check the number of basic blocks
|
|
926
|
-
assert len(list(cfg.functions[0xA00081].blocks)) == 8
|
|
927
|
-
|
|
928
|
-
def test_func_in_added_segment_by_patcherex_x64(self):
|
|
929
|
-
path = os.path.join(test_location, "x86_64", "patchrex", "replace_function_patch_with_function_reference")
|
|
930
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
931
|
-
cfg = proj.analyses.CFGFast(
|
|
932
|
-
normalize=True,
|
|
933
|
-
function_starts={0xA0013D},
|
|
934
|
-
regions=[
|
|
935
|
-
(4195568, 4195591),
|
|
936
|
-
(4195600, 4195632),
|
|
937
|
-
(4195632, 4195640),
|
|
938
|
-
(4195648, 4196418),
|
|
939
|
-
(4196420, 4196429),
|
|
940
|
-
(10486064, 10486213),
|
|
941
|
-
],
|
|
942
|
-
)
|
|
943
|
-
|
|
944
|
-
# Check whether the target function is in the functions list
|
|
945
|
-
assert 0xA0013D in cfg.kb.functions
|
|
946
|
-
# Check the number of basic blocks
|
|
947
|
-
assert len(list(cfg.functions[0xA0013D].blocks)) == 7
|
|
948
|
-
|
|
949
|
-
def test_indirect_calls_always_return_overly_aggressive(self):
|
|
950
|
-
path = os.path.join(test_location, "x86_64", "ls_ubuntu_2004")
|
|
951
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
952
|
-
cfg = proj.analyses.CFGFast(normalize=True)
|
|
953
|
-
node = cfg.model.get_any_node(0x404DB4)
|
|
954
|
-
assert node is not None
|
|
955
|
-
assert node.function_address == 0x40F770
|
|
956
|
-
|
|
957
|
-
def test_removing_lock_edges(self):
|
|
958
|
-
path = os.path.join(
|
|
959
|
-
test_location, "x86_64", "windows", "6f289eb8c8cd826525d79b195b1cf187df509d56120427b10ea3fb1b4db1b7b5.sys"
|
|
960
|
-
)
|
|
961
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
962
|
-
cfg = proj.analyses.CFGFast(normalize=True)
|
|
963
|
-
node = cfg.model.get_any_node(0x1400061C2)
|
|
964
|
-
assert {n.addr for n in cfg.model.graph.successors(node)} == {0x1400060DC, 0x1400061D4}
|
|
965
|
-
|
|
966
|
-
def test_security_init_cookie_identification(self):
|
|
967
|
-
path = os.path.join(test_location, "x86_64", "windows", "3ware.sys")
|
|
968
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
969
|
-
cfg = proj.analyses.CFGFast()
|
|
970
|
-
assert cfg.kb.functions[0x1C001A018].name == "_security_init_cookie"
|
|
971
|
-
assert cfg.kb.functions[0x1C0010100].name == "_security_check_cookie"
|
|
972
|
-
|
|
973
|
-
def test_security_init_cookie_identification_a(self):
|
|
974
|
-
path = os.path.join(
|
|
975
|
-
test_location, "x86_64", "windows", "1817a5bf9c01035bcf8a975c9f1d94b0ce7f6a200339485d8f93859f8f6d730c.exe"
|
|
976
|
-
)
|
|
977
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
978
|
-
cfg = proj.analyses.CFGFast()
|
|
979
|
-
assert cfg.kb.functions[0x21514B5600].name == "_security_init_cookie"
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
class TestCfgfastDataReferences(unittest.TestCase):
|
|
983
|
-
def test_data_references_x86_64(self):
|
|
984
|
-
path = os.path.join(test_location, "x86_64", "fauxware")
|
|
985
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
986
|
-
|
|
987
|
-
cfg = proj.analyses.CFGFast(data_references=True)
|
|
988
|
-
|
|
989
|
-
memory_data = cfg.memory_data
|
|
990
|
-
# There is no code reference
|
|
991
|
-
code_ref_count = len([d for d in memory_data.values() if d.sort == MemoryDataSort.CodeReference])
|
|
992
|
-
assert code_ref_count >= 0, "There should be no code reference."
|
|
993
|
-
|
|
994
|
-
# There are at least 2 pointer arrays
|
|
995
|
-
ptr_array_count = len([d for d in memory_data.values() if d.sort == MemoryDataSort.PointerArray])
|
|
996
|
-
assert ptr_array_count > 2, "Missing some pointer arrays."
|
|
997
|
-
|
|
998
|
-
assert 0x4008D0 in memory_data
|
|
999
|
-
sneaky_str = memory_data[0x4008D0]
|
|
1000
|
-
assert sneaky_str.sort == "string"
|
|
1001
|
-
assert sneaky_str.content == b"SOSNEAKY"
|
|
1002
|
-
|
|
1003
|
-
def test_data_references_mipsel(self):
|
|
1004
|
-
path = os.path.join(test_location, "mipsel", "fauxware")
|
|
1005
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
1006
|
-
|
|
1007
|
-
cfg = proj.analyses.CFGFast(data_references=True)
|
|
1008
|
-
|
|
1009
|
-
memory_data = cfg.memory_data
|
|
1010
|
-
# There is no code reference
|
|
1011
|
-
code_ref_count = len([d for d in memory_data.values() if d.sort == MemoryDataSort.CodeReference])
|
|
1012
|
-
assert code_ref_count >= 0, "There should be no code reference."
|
|
1013
|
-
|
|
1014
|
-
# There are at least 2 pointer arrays
|
|
1015
|
-
ptr_array_count = len([d for d in memory_data.values() if d.sort == MemoryDataSort.PointerArray])
|
|
1016
|
-
assert ptr_array_count >= 1, "Missing some pointer arrays."
|
|
1017
|
-
|
|
1018
|
-
assert 0x400C00 in memory_data
|
|
1019
|
-
sneaky_str = memory_data[0x400C00]
|
|
1020
|
-
assert sneaky_str.sort == "string"
|
|
1021
|
-
assert sneaky_str.content == b"SOSNEAKY"
|
|
1022
|
-
|
|
1023
|
-
assert 0x400C0C in memory_data
|
|
1024
|
-
str_ = memory_data[0x400C0C]
|
|
1025
|
-
assert str_.sort == "string"
|
|
1026
|
-
assert str_.content == b"Welcome to the admin console, trusted user!"
|
|
1027
|
-
|
|
1028
|
-
assert 0x400C38 in memory_data
|
|
1029
|
-
str_ = memory_data[0x400C38]
|
|
1030
|
-
assert str_.sort == "string"
|
|
1031
|
-
assert str_.content == b"Go away!"
|
|
1032
|
-
|
|
1033
|
-
assert 0x400C44 in memory_data
|
|
1034
|
-
str_ = memory_data[0x400C44]
|
|
1035
|
-
assert str_.sort == "string"
|
|
1036
|
-
assert str_.content == b"Username: "
|
|
1037
|
-
|
|
1038
|
-
assert 0x400C50 in memory_data
|
|
1039
|
-
str_ = memory_data[0x400C50]
|
|
1040
|
-
assert str_.sort == "string"
|
|
1041
|
-
assert str_.content == b"Password: "
|
|
1042
|
-
|
|
1043
|
-
def test_data_references_mips64(self):
|
|
1044
|
-
path = os.path.join(test_location, "mips64", "true")
|
|
1045
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
1046
|
-
|
|
1047
|
-
cfg = proj.analyses.CFGFast(data_references=True, cross_references=True)
|
|
1048
|
-
memory_data = cfg.memory_data
|
|
1049
|
-
|
|
1050
|
-
assert 0x120007DD8 in memory_data
|
|
1051
|
-
assert memory_data[0x120007DD8].sort == "string"
|
|
1052
|
-
assert memory_data[0x120007DD8].content == b"coreutils"
|
|
1053
|
-
|
|
1054
|
-
xrefs = proj.kb.xrefs
|
|
1055
|
-
refs = list(xrefs.get_xrefs_by_dst(0x120007DD8))
|
|
1056
|
-
assert len(refs) == 2
|
|
1057
|
-
assert {x.ins_addr for x in refs} == {0x1200020E8, 0x120002108}
|
|
1058
|
-
|
|
1059
|
-
def test_data_references_i386_gcc_pie(self):
|
|
1060
|
-
path = os.path.join(test_location, "i386", "nl")
|
|
1061
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
1062
|
-
|
|
1063
|
-
cfg = proj.analyses.CFGFast(data_references=True, cross_references=True)
|
|
1064
|
-
memory_data = cfg.memory_data
|
|
1065
|
-
|
|
1066
|
-
assert 0x405BB0 in memory_data
|
|
1067
|
-
assert memory_data[0x405BB0].sort == "string"
|
|
1068
|
-
assert memory_data[0x405BB0].content == b"/usr/local/share/locale"
|
|
1069
|
-
|
|
1070
|
-
xrefs = proj.kb.xrefs
|
|
1071
|
-
refs = list(xrefs.get_xrefs_by_dst(0x405BB0))
|
|
1072
|
-
assert len(refs) == 1
|
|
1073
|
-
assert {x.ins_addr for x in refs} == {0x4011DD}
|
|
1074
|
-
|
|
1075
|
-
def test_data_references_wide_string(self):
|
|
1076
|
-
path = os.path.join(test_location, "x86_64", "windows", "fauxware-wide.exe")
|
|
1077
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
1078
|
-
|
|
1079
|
-
cfg = proj.analyses.CFGFast(data_references=True)
|
|
1080
|
-
recovered_strings = [d.content for d in cfg.memory_data.values() if d.sort == MemoryDataSort.UnicodeString]
|
|
1081
|
-
|
|
1082
|
-
for testme in ("SOSNEAKY", "Welcome to the admin console, trusted user!\n", "Go away!\n", "Username: \n"):
|
|
1083
|
-
assert testme.encode("utf-16-le") in recovered_strings
|
|
1084
|
-
|
|
1085
|
-
def test_data_references_lea_string_addr(self):
|
|
1086
|
-
path = os.path.join(test_location, "x86_64", "windows", "3ware.sys")
|
|
1087
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
1088
|
-
|
|
1089
|
-
cfg = proj.analyses.CFGFast(data_references=True)
|
|
1090
|
-
assert cfg.memory_data[0x1C0010A20].sort == MemoryDataSort.String
|
|
1091
|
-
assert cfg.memory_data[0x1C0010A20].content == b"Initialize> %s"
|
|
1092
|
-
|
|
1093
|
-
def test_arm_function_hints_from_data_references(self):
|
|
1094
|
-
path = os.path.join(test_location, "armel", "sha224sum")
|
|
1095
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
1096
|
-
|
|
1097
|
-
proj.analyses.CFGFast(data_references=True)
|
|
1098
|
-
funcs = proj.kb.functions
|
|
1099
|
-
assert funcs.contains_addr(0x129C4)
|
|
1100
|
-
func = funcs[0x129C4]
|
|
1101
|
-
assert len(list(func.blocks)) == 1
|
|
1102
|
-
assert list(func.blocks)[0].size == 16
|
|
1103
|
-
|
|
1104
|
-
def test_data_references_windows_driver_utf16_strings(self):
|
|
1105
|
-
path = os.path.join(
|
|
1106
|
-
test_location, "x86_64", "windows", "aaba7db353eb9400e3471eaaa1cf0105f6d1fab0ce63f1a2665c8ba0e8963a05.bin"
|
|
1107
|
-
)
|
|
1108
|
-
proj = angr.Project(path, auto_load_libs=False)
|
|
1109
|
-
|
|
1110
|
-
cfg = proj.analyses.CFGFast()
|
|
1111
|
-
|
|
1112
|
-
assert cfg.model.memory_data[0x1DCE0].sort == MemoryDataSort.UnicodeString
|
|
1113
|
-
assert cfg.model.memory_data[0x1DCE0].content == cstring_to_unicode_string(
|
|
1114
|
-
b"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\WinApi"
|
|
1115
|
-
)
|
|
1116
|
-
assert cfg.model.memory_data[0x1DCE0].size == 116
|
|
1117
|
-
assert cfg.model.memory_data[0x1DD90].sort == MemoryDataSort.UnicodeString
|
|
1118
|
-
assert cfg.model.memory_data[0x1DD90].content == cstring_to_unicode_string(b"ntdll.dll")
|
|
1119
|
-
assert cfg.model.memory_data[0x1DD90].size == 20
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
if __name__ == "__main__":
|
|
1123
|
-
unittest.main()
|