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
tests/engines/test_java.py
DELETED
|
@@ -1,697 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
__package__ = __package__ or "tests.engines" # pylint:disable=redefined-builtin
|
|
3
|
-
|
|
4
|
-
import os
|
|
5
|
-
import unittest
|
|
6
|
-
|
|
7
|
-
from archinfo.arch_amd64 import ArchAMD64
|
|
8
|
-
from archinfo.arch_soot import (
|
|
9
|
-
ArchSoot,
|
|
10
|
-
SootAddressDescriptor,
|
|
11
|
-
SootMethodDescriptor,
|
|
12
|
-
SootArgument,
|
|
13
|
-
SootAddressTerminator,
|
|
14
|
-
)
|
|
15
|
-
from claripy.backends.backend_smtlib_solvers import z3str_popen # noqa: F401
|
|
16
|
-
|
|
17
|
-
import angr
|
|
18
|
-
from angr.storage.memory_mixins import JavaVmMemory, DefaultMemory, KeyValueMemory
|
|
19
|
-
from angr.engines.soot.values import SimSootValue_ArrayRef, SimSootValue_ThisRef
|
|
20
|
-
from angr.engines.soot.method_dispatcher import resolve_method
|
|
21
|
-
|
|
22
|
-
try:
|
|
23
|
-
import pysoot
|
|
24
|
-
except ModuleNotFoundError:
|
|
25
|
-
pysoot = None
|
|
26
|
-
|
|
27
|
-
from ..common import bin_location
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class TestJava(unittest.TestCase):
|
|
31
|
-
test_location = os.path.join(bin_location, "tests", "java")
|
|
32
|
-
sdk_path = os.path.join(os.path.expanduser("~"), "Android", "Sdk", "platforms")
|
|
33
|
-
|
|
34
|
-
@unittest.skipUnless(pysoot, "pysoot not available")
|
|
35
|
-
def test_fauxware(self):
|
|
36
|
-
# create project
|
|
37
|
-
binary_path = os.path.join(self.test_location, "fauxware_java_jni", "fauxware.jar")
|
|
38
|
-
jni_options = {"jni_libs": ["libfauxware.so"]}
|
|
39
|
-
project = angr.Project(binary_path, main_opts=jni_options)
|
|
40
|
-
entry = project.factory.entry_state()
|
|
41
|
-
simgr = project.factory.simgr(entry)
|
|
42
|
-
|
|
43
|
-
# find path to `accepted()` method
|
|
44
|
-
accepted_method = SootMethodDescriptor.from_string("Fauxware.accepted()").address()
|
|
45
|
-
simgr.explore(find=lambda s: s.addr == accepted_method)
|
|
46
|
-
|
|
47
|
-
assert len(simgr.found) == 1
|
|
48
|
-
state = simgr.found[0]
|
|
49
|
-
|
|
50
|
-
# eval password
|
|
51
|
-
cmd_line_args = project.simos.get_cmd_line_args(state)
|
|
52
|
-
password = state.solver.eval(cmd_line_args[0])
|
|
53
|
-
assert password == "SOSNEAKY"
|
|
54
|
-
|
|
55
|
-
@unittest.skipUnless(os.path.exists(sdk_path), "Android SDK found")
|
|
56
|
-
def test_apk_loading(self):
|
|
57
|
-
loading_opts = {
|
|
58
|
-
"android_sdk": self.sdk_path,
|
|
59
|
-
"entry_point": "com.example.antoniob.android1.MainActivity.onCreate",
|
|
60
|
-
"entry_point_params": ("android.os.Bundle",),
|
|
61
|
-
}
|
|
62
|
-
project = angr.Project(
|
|
63
|
-
os.path.join(self.test_location, "android1.apk"), main_opts=loading_opts, auto_load_libs=False
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
blank_state = project.factory.blank_state()
|
|
67
|
-
a1 = SimSootValue_ThisRef.new_object(blank_state, "com.example.antoniob.android1.MainActivity")
|
|
68
|
-
a2 = SimSootValue_ThisRef.new_object(blank_state, "android.os.Bundle", symbolic=True)
|
|
69
|
-
args = [SootArgument(arg, arg.type) for arg in [a1, a2]]
|
|
70
|
-
entry = project.factory.entry_state(args=args)
|
|
71
|
-
|
|
72
|
-
simgr = project.factory.simgr(entry)
|
|
73
|
-
simgr.step()
|
|
74
|
-
simgr.step()
|
|
75
|
-
assert simgr.active[0].addr.block_idx == 0
|
|
76
|
-
assert simgr.active[0].addr.stmt_idx == 3
|
|
77
|
-
simgr.run()
|
|
78
|
-
assert len(simgr.deadended) == 1
|
|
79
|
-
assert type(simgr.deadended[0].addr) is SootAddressTerminator
|
|
80
|
-
|
|
81
|
-
#
|
|
82
|
-
# Command line arguments
|
|
83
|
-
#
|
|
84
|
-
|
|
85
|
-
@unittest.skipUnless(pysoot, "pysoot not available")
|
|
86
|
-
def test_cmd_line_args(self):
|
|
87
|
-
project = self.create_project("cmd_line_args", load_native_libs=False)
|
|
88
|
-
entry = project.factory.entry_state()
|
|
89
|
-
simgr = project.factory.simgr(entry)
|
|
90
|
-
simgr.run()
|
|
91
|
-
assert len(simgr.deadended) == 2
|
|
92
|
-
state1, state2 = tuple(simgr.deadended)
|
|
93
|
-
|
|
94
|
-
# get symbol of args[0] from memory
|
|
95
|
-
args = state1.globals["cmd_line_args"]
|
|
96
|
-
args0_arrref = SimSootValue_ArrayRef(args, 0)
|
|
97
|
-
args0_strref = state1.memory.load(args0_arrref)
|
|
98
|
-
args0_strval = state1.memory.load(args0_strref)
|
|
99
|
-
|
|
100
|
-
# eval args[0] on both states
|
|
101
|
-
str1 = state1.solver.eval(args0_strval)
|
|
102
|
-
str2 = state2.solver.eval(args0_strval)
|
|
103
|
-
assert "secret_value" in [str1, str2]
|
|
104
|
-
|
|
105
|
-
#
|
|
106
|
-
# JNI Version Information
|
|
107
|
-
#
|
|
108
|
-
|
|
109
|
-
@unittest.skipUnless(pysoot, "pysoot not available")
|
|
110
|
-
def test_jni_version_information(self):
|
|
111
|
-
project = self.create_project("jni_version_information")
|
|
112
|
-
|
|
113
|
-
self.run_method(project=project, method="MixedJava.test_jni_get_version", assert_locals={"i0": 0x10008})
|
|
114
|
-
|
|
115
|
-
#
|
|
116
|
-
# JNI Global and Local References
|
|
117
|
-
#
|
|
118
|
-
|
|
119
|
-
@unittest.skipUnless(pysoot, "pysoot not available")
|
|
120
|
-
def test_jni_global_and_local_refs(self):
|
|
121
|
-
project = self.create_project("jni_global_and_local_refs")
|
|
122
|
-
|
|
123
|
-
assertions = {"global refs dict": lambda state: (state.jni_references.global_refs == {})}
|
|
124
|
-
self.run_method(
|
|
125
|
-
project=project, method="MixedJava.test_jni_global_refs", assert_locals={"i0": 0xA}, assertions=assertions
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
#
|
|
129
|
-
# JNI Object Operations
|
|
130
|
-
#
|
|
131
|
-
|
|
132
|
-
def test_jni_object_operations(self):
|
|
133
|
-
project = self.create_project("jni_object_operations")
|
|
134
|
-
|
|
135
|
-
self.run_method(project=project, method="MixedJava.test_jni_alloc_object", assert_locals={"i0": 0})
|
|
136
|
-
|
|
137
|
-
self.run_method(project=project, method="MixedJava.test_jni_new_object", assert_locals={"i0": 1})
|
|
138
|
-
|
|
139
|
-
self.run_method(project=project, method="MixedJava.test_jni_new_subclass_object", assert_locals={"i0": 2})
|
|
140
|
-
|
|
141
|
-
self.run_method(
|
|
142
|
-
project=project,
|
|
143
|
-
method="MixedJava.test_jni_isinstanceof",
|
|
144
|
-
assert_locals={"i0": 1, "i1": 1, "i2": 0, "i3": 1},
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
self.run_method(project=project, method="MixedJava.test_jni_issameobject", assert_locals={"i0": 0, "i1": 1})
|
|
148
|
-
|
|
149
|
-
#
|
|
150
|
-
# JNI String Operations
|
|
151
|
-
#
|
|
152
|
-
|
|
153
|
-
def test_jni_string_operations(self):
|
|
154
|
-
project = self.create_project("jni_string_operations")
|
|
155
|
-
|
|
156
|
-
assertions = {
|
|
157
|
-
"1st string": lambda state: (state.solver.eval_one(self.load_string(state, "r0")) == "mum"),
|
|
158
|
-
"2nd string": lambda state: (state.solver.eval_one(self.load_string(state, "r1")) == "himum!"),
|
|
159
|
-
}
|
|
160
|
-
self.run_method(
|
|
161
|
-
project=project,
|
|
162
|
-
method="MixedJava.test_jni_string_operations",
|
|
163
|
-
assert_locals={"i0": 0x3, "i1": 0x6},
|
|
164
|
-
assertions=assertions,
|
|
165
|
-
)
|
|
166
|
-
|
|
167
|
-
#
|
|
168
|
-
# JNI Field Access
|
|
169
|
-
#
|
|
170
|
-
|
|
171
|
-
def test_jni_field_access(self):
|
|
172
|
-
project = self.create_project("jni_field_access")
|
|
173
|
-
|
|
174
|
-
self.run_method(
|
|
175
|
-
project=project,
|
|
176
|
-
method="MixedJava.test_static_field_access_basic",
|
|
177
|
-
assert_locals={"i0": 0x0, "i1": 0x1, "i2": 0xA, "i3": 0xB, "i4": 0x7, "i5": 0xB, "i6": 0x0, "i7": 0x9},
|
|
178
|
-
)
|
|
179
|
-
|
|
180
|
-
self.run_method(
|
|
181
|
-
project=project, method="MixedJava.test_jni_static_field_access", assert_locals={"i0": 0, "i1": 5}
|
|
182
|
-
)
|
|
183
|
-
|
|
184
|
-
self.run_method(
|
|
185
|
-
project=project,
|
|
186
|
-
method="MixedJava.test_jni_static_field_access_subclass",
|
|
187
|
-
assert_locals={"i0": 1, "i1": 10, "i2": 30, "i3": 1},
|
|
188
|
-
)
|
|
189
|
-
|
|
190
|
-
self.run_method(
|
|
191
|
-
project=project,
|
|
192
|
-
method="MixedJava.test_instance_field_access_0",
|
|
193
|
-
assert_locals={"i0": 0, "i1": 10, "i2": 5, "i3": 5},
|
|
194
|
-
)
|
|
195
|
-
|
|
196
|
-
self.run_method(
|
|
197
|
-
project=project,
|
|
198
|
-
method="MixedJava.test_instance_field_access_1",
|
|
199
|
-
assert_locals={"i0": 0, "i1": 1, "i2": 10, "i3": 4, "i4": 4, "i5": 1},
|
|
200
|
-
)
|
|
201
|
-
|
|
202
|
-
#
|
|
203
|
-
# JNI Method Calls
|
|
204
|
-
#
|
|
205
|
-
|
|
206
|
-
@unittest.skipUnless(pysoot, "pysoot not available")
|
|
207
|
-
def test_jni_method_calls(self):
|
|
208
|
-
project = self.create_project("jni_method_calls")
|
|
209
|
-
|
|
210
|
-
self.run_method(
|
|
211
|
-
project=project, method="MixedJava.test_jni_non_virtual_instance_method_call", assert_locals={"i0": 5}
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
self.run_method(
|
|
215
|
-
project=project, method="MixedJava.test_jni_instance_method_calls_basic", assert_locals={"i0": 7, "i1": 7}
|
|
216
|
-
)
|
|
217
|
-
|
|
218
|
-
self.run_method(
|
|
219
|
-
project=project,
|
|
220
|
-
method="MixedJava.test_jni_instance_method_calls_subclass",
|
|
221
|
-
assert_locals={"i0": 2, "i1": 2},
|
|
222
|
-
)
|
|
223
|
-
|
|
224
|
-
self.run_method(
|
|
225
|
-
project=project,
|
|
226
|
-
method="MixedJava.test_jni_instance_method_calls_shared_method_id",
|
|
227
|
-
assert_locals={"i0": 8, "i1": 2},
|
|
228
|
-
)
|
|
229
|
-
|
|
230
|
-
self.run_method(
|
|
231
|
-
project=project, method="MixedJava.test_jni_instance_method_calls_args", assert_locals={"i0": 11}
|
|
232
|
-
)
|
|
233
|
-
|
|
234
|
-
self.run_method(project=project, method="MixedJava.test_jni_static_method_call", assert_locals={"i0": 10})
|
|
235
|
-
|
|
236
|
-
self.run_method(
|
|
237
|
-
project=project, method="MixedJava.test_jni_static_method_call_return_obj", assert_locals={"i0": 7}
|
|
238
|
-
)
|
|
239
|
-
|
|
240
|
-
#
|
|
241
|
-
# JNI Primitive Datatypes
|
|
242
|
-
#
|
|
243
|
-
|
|
244
|
-
@unittest.skipUnless(pysoot, "pysoot not available")
|
|
245
|
-
def test_jni_primitive_datatypes(self):
|
|
246
|
-
project = self.create_project("jni_primitive_datatypes")
|
|
247
|
-
|
|
248
|
-
self.run_method(
|
|
249
|
-
project=project,
|
|
250
|
-
method="MixedJava.test_boolean",
|
|
251
|
-
assert_locals={"z0": 1, "z1": 0, "z2": 1, "z3": 0, "z4": 1},
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
self.run_method(
|
|
255
|
-
project=project, method="MixedJava.test_byte", assert_locals={"b5": 30, "b8": 0xFFFFFF80, "b11": 0}
|
|
256
|
-
)
|
|
257
|
-
|
|
258
|
-
self.run_method(project=project, method="MixedJava.test_char", assert_locals={"c4": 21, "c6": 0, "c9": 1})
|
|
259
|
-
|
|
260
|
-
self.run_method(
|
|
261
|
-
project=project,
|
|
262
|
-
method="MixedJava.test_short",
|
|
263
|
-
assert_locals={"s3": 0x1000, "s5": 0xFFFFF000, "s0": 11, "s9": 0},
|
|
264
|
-
)
|
|
265
|
-
|
|
266
|
-
self.run_method(
|
|
267
|
-
project=project,
|
|
268
|
-
method="MixedJava.test_int",
|
|
269
|
-
assert_locals={"i1": 0xFFFFFFF6, "i3": 0, "i5": 0x80000001, "i7": 0x7FFFFFFF},
|
|
270
|
-
)
|
|
271
|
-
|
|
272
|
-
self.run_method(
|
|
273
|
-
project=project, method="MixedJava.test_long", assert_locals={"l1": 0xFFFFFFFFFFFFFFFF, "l3": 1}
|
|
274
|
-
)
|
|
275
|
-
|
|
276
|
-
@unittest.skipUnless(pysoot, "pysoot not available")
|
|
277
|
-
def test_jni_object_arrays(self):
|
|
278
|
-
project = self.create_project("jni_object_array_operations")
|
|
279
|
-
|
|
280
|
-
self.run_method(project=project, method="MixedJava.test_jni_access_object_array", assert_locals={"i0": 7})
|
|
281
|
-
|
|
282
|
-
self.run_method(project=project, method="MixedJava.test_jni_new_object_array", assert_locals={"i0": 10})
|
|
283
|
-
|
|
284
|
-
#
|
|
285
|
-
# JNI Array Operations
|
|
286
|
-
#
|
|
287
|
-
|
|
288
|
-
@unittest.skipUnless(pysoot, "pysoot not available")
|
|
289
|
-
def test_jni_array_operations(self):
|
|
290
|
-
project = self.create_project("jni_array_operations")
|
|
291
|
-
|
|
292
|
-
# test_jni_newarray
|
|
293
|
-
self.run_method(
|
|
294
|
-
project=project,
|
|
295
|
-
method="MixedJava.test_jni_newarray",
|
|
296
|
-
assert_locals={"i0": 0, "i1": 1, "i2": 2, "i3": 3, "i4": 4},
|
|
297
|
-
)
|
|
298
|
-
|
|
299
|
-
# test_jni_getarrayregion
|
|
300
|
-
state = self.run_method(project=project, method="MixedJava.test_jni_getarrayregion")
|
|
301
|
-
a = self.load_value_from_stack(state, "i1")
|
|
302
|
-
state.solver.add(a == 15)
|
|
303
|
-
idx = state.posix.stdin.content[0][0]
|
|
304
|
-
assert state.solver.eval_one(idx) == 7
|
|
305
|
-
|
|
306
|
-
# test_jni_setarrayregion1
|
|
307
|
-
self.run_method(
|
|
308
|
-
project=project,
|
|
309
|
-
method="MixedJava.test_jni_setarrayregion1",
|
|
310
|
-
assert_locals={"i0": 0, "i1": 3, "i2": 2, "i3": 1, "i4": 4},
|
|
311
|
-
)
|
|
312
|
-
|
|
313
|
-
# test_jni_setarrayregion2
|
|
314
|
-
state = self.run_method(project=project, method="MixedJava.test_jni_setarrayregion2")
|
|
315
|
-
a = self.load_value_from_stack(state, "i1")
|
|
316
|
-
state.solver.add(a == 2)
|
|
317
|
-
idx = state.posix.stdin.content[0][0]
|
|
318
|
-
idx_value = state.solver.eval_one(idx)
|
|
319
|
-
assert idx_value == 0
|
|
320
|
-
|
|
321
|
-
# test_jni_setarrayregion2
|
|
322
|
-
state = self.run_method(project=project, method="MixedJava.test_jni_setarrayregion2")
|
|
323
|
-
a = self.load_value_from_stack(state, "i1")
|
|
324
|
-
state.solver.add(a == 0)
|
|
325
|
-
idx = state.posix.stdin.content[0][0]
|
|
326
|
-
idx_value = state.solver.eval_exact(idx, 2)
|
|
327
|
-
assert 1 in idx_value
|
|
328
|
-
assert 2 in idx_value
|
|
329
|
-
assert 3 not in idx_value
|
|
330
|
-
|
|
331
|
-
# test_jni_getarrayelements_symbolic
|
|
332
|
-
winning_path = self.get_winning_path(
|
|
333
|
-
project=project, method_fullname="MixedJava.test_jni_getarrayelements_symbolic"
|
|
334
|
-
)
|
|
335
|
-
stdin_packets = winning_path.posix.stdin.content
|
|
336
|
-
idx = winning_path.solver.eval_one(stdin_packets[0][0])
|
|
337
|
-
min_length = winning_path.solver.min(stdin_packets[1][0])
|
|
338
|
-
assert idx == 223
|
|
339
|
-
assert min_length == 224
|
|
340
|
-
|
|
341
|
-
# test_jni_releasearrayelements
|
|
342
|
-
self.run_method(
|
|
343
|
-
project=project,
|
|
344
|
-
method="MixedJava.test_jni_releasearrayelments",
|
|
345
|
-
assert_locals={"i0": 4, "i1": 3, "i2": 2, "i3": 1, "i4": 0},
|
|
346
|
-
)
|
|
347
|
-
|
|
348
|
-
# test_jni_getarrayelements_and_releasearrayelements
|
|
349
|
-
self.run_method(
|
|
350
|
-
project=project,
|
|
351
|
-
method="MixedJava.test_jni_getarrayelements_and_releasearrayelements",
|
|
352
|
-
assert_locals={
|
|
353
|
-
"c9": 0xFFFF,
|
|
354
|
-
"c14": 0x0000,
|
|
355
|
-
"b5": 0x0000007F,
|
|
356
|
-
"b10": 0xFFFFFF80,
|
|
357
|
-
"s6": 0x00007FFF,
|
|
358
|
-
"s11": 0xFFFF8000,
|
|
359
|
-
"i7": 0x7FFFFFFF,
|
|
360
|
-
"i12": 0x80000000,
|
|
361
|
-
"l8": 0x7FFFFFFFFFFFFFFF,
|
|
362
|
-
"l13": 0x8000000000000000,
|
|
363
|
-
},
|
|
364
|
-
)
|
|
365
|
-
|
|
366
|
-
# test_jni_getarraylength
|
|
367
|
-
state = self.run_method(project=project, method="MixedJava.test_jni_getarraylength")
|
|
368
|
-
a = state.memory.stack.load("i3")
|
|
369
|
-
assert state.solver.eval(a) == 10
|
|
370
|
-
b = state.memory.stack.load("i4")
|
|
371
|
-
assert state.solver.min(b) == 0
|
|
372
|
-
assert state.solver.max(b) == 255
|
|
373
|
-
|
|
374
|
-
#
|
|
375
|
-
# Method Calls
|
|
376
|
-
#
|
|
377
|
-
|
|
378
|
-
@unittest.skipUnless(pysoot, "pysoot not available")
|
|
379
|
-
def test_method_calls(self):
|
|
380
|
-
project = self.create_project("method_calls", load_native_libs=False)
|
|
381
|
-
|
|
382
|
-
self.run_method(
|
|
383
|
-
project=project,
|
|
384
|
-
method="MixedJava.test_instance_method_calls",
|
|
385
|
-
assert_locals={"i0": 0, "i1": 1, "i2": 1, "i3": 2, "i4": 2, "i5": 2},
|
|
386
|
-
)
|
|
387
|
-
|
|
388
|
-
self.run_method(
|
|
389
|
-
project=project,
|
|
390
|
-
method="MixedJava.test_static_method_calls_0",
|
|
391
|
-
assert_locals={"i0": 0, "i1": 1, "i2": 2, "i3": 2},
|
|
392
|
-
)
|
|
393
|
-
|
|
394
|
-
self.run_method(
|
|
395
|
-
project=project,
|
|
396
|
-
method="MixedJava.test_static_method_calls_1",
|
|
397
|
-
assert_locals={"i0": 0, "i1": 0, "i2": 1, "i3": 2, "i4": 2, "i5": 2},
|
|
398
|
-
)
|
|
399
|
-
|
|
400
|
-
self.run_method(project=project, method="MixedJava.test_special_invoke_0", assert_locals={"i0": 3})
|
|
401
|
-
|
|
402
|
-
self.run_method(project=project, method="MixedJava.test_special_invoke_1", assert_locals={"i0": 4})
|
|
403
|
-
|
|
404
|
-
#
|
|
405
|
-
# Array Operations
|
|
406
|
-
#
|
|
407
|
-
|
|
408
|
-
@unittest.skipUnless(pysoot, "pysoot not available")
|
|
409
|
-
def test_array_operations(self):
|
|
410
|
-
project = self.create_project("array_operations", load_native_libs=False)
|
|
411
|
-
|
|
412
|
-
# test_basic_array_operations
|
|
413
|
-
self.run_method(
|
|
414
|
-
project=project,
|
|
415
|
-
method="MixedJava.test_basic_array_operations",
|
|
416
|
-
assert_locals={"i1": 0, "i2": 1, "i3": 2, "i4": 3, "i5": 4, "i6": 5, "i7": 2, "i8": 0},
|
|
417
|
-
)
|
|
418
|
-
|
|
419
|
-
# test_symbolic_array_read
|
|
420
|
-
winning_path = self.get_winning_path(project=project, method_fullname="MixedJava.test_symbolic_array_read")
|
|
421
|
-
stdin_packets = winning_path.posix.stdin.content
|
|
422
|
-
input_char, _ = stdin_packets[0]
|
|
423
|
-
solutions = winning_path.solver.eval_upto(input_char, 2)
|
|
424
|
-
assert ord("A") in solutions
|
|
425
|
-
assert ord("C") in solutions
|
|
426
|
-
|
|
427
|
-
# test_symbolic_array_write
|
|
428
|
-
winning_path = self.get_winning_path(project=project, method_fullname="MixedJava.test_symbolic_array_write")
|
|
429
|
-
stdin_packets = winning_path.posix.stdin.content
|
|
430
|
-
idx_symbol, _ = stdin_packets[0]
|
|
431
|
-
val_symbol, _ = stdin_packets[1]
|
|
432
|
-
winning_path.solver.add(val_symbol != 0) # exclude trivial solution
|
|
433
|
-
idx = winning_path.solver.eval(idx_symbol)
|
|
434
|
-
val = winning_path.solver.eval(val_symbol)
|
|
435
|
-
assert idx == 73
|
|
436
|
-
assert val == 53
|
|
437
|
-
|
|
438
|
-
# test_symbolic_array_length
|
|
439
|
-
winning_path = self.get_winning_path(project=project, method_fullname="MixedJava.test_symbolic_array_length")
|
|
440
|
-
stdin_packets = winning_path.posix.stdin.content
|
|
441
|
-
input_char, _ = stdin_packets[0]
|
|
442
|
-
solution = winning_path.solver.eval(input_char)
|
|
443
|
-
assert solution == ord("F")
|
|
444
|
-
|
|
445
|
-
# test_index_of_of_bound0
|
|
446
|
-
state = self.run_method(project=project, method="MixedJava.test_index_of_of_bound0")
|
|
447
|
-
array_len = self.load_value_from_stack(state, "i1")
|
|
448
|
-
assert state.solver.min(array_len) == 0
|
|
449
|
-
assert state.solver.max(array_len) == 255
|
|
450
|
-
|
|
451
|
-
# test_index_of_of_bound1
|
|
452
|
-
state = self.run_method(project=project, method="MixedJava.test_index_of_of_bound1")
|
|
453
|
-
array_len = self.load_value_from_stack(state, "i1")
|
|
454
|
-
assert state.solver.min(array_len) == 101
|
|
455
|
-
assert state.solver.max(array_len) == 255
|
|
456
|
-
|
|
457
|
-
# test_index_of_of_bound2
|
|
458
|
-
state = self.run_method(project=project, method="MixedJava.test_index_of_of_bound2")
|
|
459
|
-
assert self.load_value_from_stack(state, "i1") is not None
|
|
460
|
-
assert self.load_value_from_stack(state, "i2") is None
|
|
461
|
-
assert self.load_value_from_stack(state, "i3") is None
|
|
462
|
-
assert self.load_value_from_stack(state, "i4") is not None
|
|
463
|
-
assert self.load_value_from_stack(state, "i5") is None
|
|
464
|
-
|
|
465
|
-
# test_index_of_of_bound3
|
|
466
|
-
state = self.run_method(project=project, method="MixedJava.test_index_of_of_bound3")
|
|
467
|
-
assert self.load_value_from_stack(state, "i1") is not None
|
|
468
|
-
assert self.load_value_from_stack(state, "i2") is not None
|
|
469
|
-
assert self.load_value_from_stack(state, "i3") is None
|
|
470
|
-
assert self.load_value_from_stack(state, "i4") is not None
|
|
471
|
-
assert self.load_value_from_stack(state, "i5") is None
|
|
472
|
-
|
|
473
|
-
# test_index_of_of_bound4
|
|
474
|
-
state = self.run_method(project=project, method="MixedJava.test_index_of_of_bound4")
|
|
475
|
-
assert self.load_value_from_stack(state, "i1") is not None
|
|
476
|
-
assert self.load_value_from_stack(state, "i2") is not None
|
|
477
|
-
assert self.load_value_from_stack(state, "i3") is None
|
|
478
|
-
|
|
479
|
-
# test_index_of_of_bound5
|
|
480
|
-
state = self.run_method(project=project, method="MixedJava.test_index_of_of_bound5")
|
|
481
|
-
assert self.load_value_from_stack(state, "i1") is not None
|
|
482
|
-
assert self.load_value_from_stack(state, "i2") is not None
|
|
483
|
-
assert self.load_value_from_stack(state, "i3") is None
|
|
484
|
-
|
|
485
|
-
#
|
|
486
|
-
# MultiArray Operations
|
|
487
|
-
#
|
|
488
|
-
|
|
489
|
-
@unittest.skipUnless(pysoot, "pysoot not available")
|
|
490
|
-
def test_multiarray_operations(self):
|
|
491
|
-
project = self.create_project("multiarray_operations", load_native_libs=False)
|
|
492
|
-
|
|
493
|
-
self.run_method(project=project, method="MixedJava.basic_multiarray_ops", assert_locals={"d1": 4})
|
|
494
|
-
|
|
495
|
-
#
|
|
496
|
-
# Loading
|
|
497
|
-
#
|
|
498
|
-
|
|
499
|
-
@unittest.skipUnless(pysoot, "pysoot not available")
|
|
500
|
-
def test_loading(self):
|
|
501
|
-
# Test1: test loading with load path
|
|
502
|
-
native_libs_ld_path = os.path.join(self.test_location, "misc", "loading1", "libs")
|
|
503
|
-
jar_path = os.path.join(self.test_location, "misc", "loading1", "mixedjava.jar")
|
|
504
|
-
# define which libraries to load (+ the load path)
|
|
505
|
-
jni_options = {"jni_libs": ["libmixedjava.so"], "jni_libs_ld_path": native_libs_ld_path}
|
|
506
|
-
project = angr.Project(jar_path, main_opts=jni_options, auto_load_libs=True)
|
|
507
|
-
# check if libmixedjava.so was loaded
|
|
508
|
-
loaded_libs = [lib.provides for lib in project.loader.all_elf_objects]
|
|
509
|
-
assert "libmixedjava.so" in loaded_libs
|
|
510
|
-
|
|
511
|
-
# Test 2: test loading without load path
|
|
512
|
-
# => the folder of the JAR is implicitly used as an additional load path
|
|
513
|
-
binary_dir = os.path.join(self.test_location, "misc", "loading2")
|
|
514
|
-
project = self.create_project(binary_dir)
|
|
515
|
-
# check if libmixedjava.so was loaded
|
|
516
|
-
loaded_libs = [lib.provides for lib in project.loader.all_elf_objects]
|
|
517
|
-
assert "libmixedjava.so" in loaded_libs
|
|
518
|
-
|
|
519
|
-
#
|
|
520
|
-
# SimStates
|
|
521
|
-
#
|
|
522
|
-
|
|
523
|
-
@unittest.skipUnless(pysoot, "pysoot not available")
|
|
524
|
-
def test_toggling_of_simstate(self):
|
|
525
|
-
binary_dir = os.path.join(self.test_location, "misc", "simstates")
|
|
526
|
-
project = self.create_project(binary_dir)
|
|
527
|
-
|
|
528
|
-
state = project.factory.entry_state()
|
|
529
|
-
assert state.ip_is_soot_addr
|
|
530
|
-
assert isinstance(state.arch, ArchSoot)
|
|
531
|
-
assert isinstance(state.memory, JavaVmMemory)
|
|
532
|
-
assert isinstance(state.registers, KeyValueMemory)
|
|
533
|
-
|
|
534
|
-
state.regs.ip = 1
|
|
535
|
-
assert not state.ip_is_soot_addr
|
|
536
|
-
assert isinstance(state.arch, ArchAMD64)
|
|
537
|
-
assert isinstance(state.memory, DefaultMemory)
|
|
538
|
-
assert isinstance(state.registers, DefaultMemory)
|
|
539
|
-
|
|
540
|
-
state.regs._ip = project.entry
|
|
541
|
-
|
|
542
|
-
assert state.ip_is_soot_addr
|
|
543
|
-
assert isinstance(state.arch, ArchSoot)
|
|
544
|
-
assert isinstance(state.memory, JavaVmMemory)
|
|
545
|
-
assert isinstance(state.registers, KeyValueMemory)
|
|
546
|
-
|
|
547
|
-
state.ip = 1
|
|
548
|
-
assert not state.ip_is_soot_addr
|
|
549
|
-
assert isinstance(state.arch, ArchAMD64)
|
|
550
|
-
assert isinstance(state.memory, DefaultMemory)
|
|
551
|
-
assert isinstance(state.registers, DefaultMemory)
|
|
552
|
-
|
|
553
|
-
state_copy = state.copy()
|
|
554
|
-
assert not state_copy.ip_is_soot_addr
|
|
555
|
-
assert isinstance(state_copy.arch, ArchAMD64)
|
|
556
|
-
assert isinstance(state_copy.memory, DefaultMemory)
|
|
557
|
-
assert isinstance(state_copy.registers, DefaultMemory)
|
|
558
|
-
|
|
559
|
-
@unittest.skipUnless(pysoot, "pysoot not available")
|
|
560
|
-
def test_object_tracking(self):
|
|
561
|
-
binary_dir = os.path.join(self.test_location, "object_tracking")
|
|
562
|
-
project = self.create_project(binary_dir, load_native_libs=False)
|
|
563
|
-
bootstrap_state = project.factory.blank_state(addr=SootAddressTerminator())
|
|
564
|
-
mylib_object = SimSootValue_ThisRef.new_object(bootstrap_state, "MyLib", symbolic=True, init_object=False)
|
|
565
|
-
|
|
566
|
-
soot_method = resolve_method(
|
|
567
|
-
bootstrap_state, "testGetterAndSetterConcrete", "MixedJava", ("mylib.MyLib",), init_class=False
|
|
568
|
-
).address()
|
|
569
|
-
|
|
570
|
-
call_state = project.factory.call_state(
|
|
571
|
-
soot_method,
|
|
572
|
-
SootArgument(mylib_object, mylib_object.type, is_this_ref=False),
|
|
573
|
-
base_state=bootstrap_state,
|
|
574
|
-
ret_addr=SootAddressTerminator(),
|
|
575
|
-
)
|
|
576
|
-
|
|
577
|
-
call_state.options.add(angr.options.JAVA_IDENTIFY_GETTER_SETTER)
|
|
578
|
-
call_state.options.add(angr.options.JAVA_TRACK_ATTRIBUTES)
|
|
579
|
-
|
|
580
|
-
simgr = project.factory.simgr(call_state)
|
|
581
|
-
simgr.run()
|
|
582
|
-
|
|
583
|
-
assert len(simgr.deadended) == 1
|
|
584
|
-
|
|
585
|
-
final_state = simgr.deadended[0]
|
|
586
|
-
|
|
587
|
-
assert final_state.solver.eval(mylib_object.get_field(final_state, "myInt", "int")) == 1
|
|
588
|
-
assert final_state.solver.eval(mylib_object.get_field(final_state, "myShort", "short")) == 1
|
|
589
|
-
assert final_state.solver.eval(mylib_object.get_field(final_state, "myChar", "char")) == ord("c")
|
|
590
|
-
assert final_state.solver.eval(mylib_object.get_field(final_state, "myLong", "long")) == 2
|
|
591
|
-
assert final_state.solver.eval(mylib_object.get_field(final_state, "myFloat", "float")) == 1.5
|
|
592
|
-
assert final_state.solver.eval(mylib_object.get_field(final_state, "myDouble", "double")) == 1.5
|
|
593
|
-
string_ref = mylib_object.get_field(final_state, "myString", "java.lang.String")
|
|
594
|
-
assert final_state.solver.eval(final_state.memory.load(string_ref)) == "Hello!"
|
|
595
|
-
array_ref = mylib_object.get_field(final_state, "myArray", "int[]")
|
|
596
|
-
assert final_state.solver.eval(array_ref.size) == 3
|
|
597
|
-
object_ref = mylib_object.get_field(final_state, "myObject", "java.lang.Object")
|
|
598
|
-
assert final_state.solver.eval(object_ref.get_field(final_state, "a", "int")) == 1
|
|
599
|
-
|
|
600
|
-
assert ("myInt", "int") in mylib_object.attributes
|
|
601
|
-
assert ("myChar", "char") in mylib_object.attributes
|
|
602
|
-
assert ("myShort", "short") in mylib_object.attributes
|
|
603
|
-
assert ("myLong", "long") in mylib_object.attributes
|
|
604
|
-
assert ("myFloat", "float") in mylib_object.attributes
|
|
605
|
-
assert ("myDouble", "double") in mylib_object.attributes
|
|
606
|
-
assert ("myString", "java.lang.String") in mylib_object.attributes
|
|
607
|
-
assert ("myArray", "int[]") in mylib_object.attributes
|
|
608
|
-
assert ("myObject", "java.lang.Object") in mylib_object.attributes
|
|
609
|
-
|
|
610
|
-
#
|
|
611
|
-
# Helper
|
|
612
|
-
#
|
|
613
|
-
|
|
614
|
-
def run_method(self, project, method, assert_locals=None, assertions=None):
|
|
615
|
-
end_state = self.get_last_state_of_method(project, method)
|
|
616
|
-
# print_java_memory(end_state)
|
|
617
|
-
|
|
618
|
-
if assert_locals:
|
|
619
|
-
for symbol_name, assert_value in assert_locals.items():
|
|
620
|
-
symbol = self.load_value_from_stack(end_state, symbol_name)
|
|
621
|
-
val = end_state.solver.eval(symbol)
|
|
622
|
-
assert val == assert_value
|
|
623
|
-
|
|
624
|
-
if assertions:
|
|
625
|
-
for _, test in assertions.items():
|
|
626
|
-
assert test(end_state)
|
|
627
|
-
|
|
628
|
-
return end_state
|
|
629
|
-
|
|
630
|
-
@unittest.skipUnless(pysoot, "pysoot not available")
|
|
631
|
-
def create_project(self, binary_dir, load_native_libs=True):
|
|
632
|
-
jar_path = os.path.join(self.test_location, binary_dir, "mixedjava.jar")
|
|
633
|
-
if load_native_libs:
|
|
634
|
-
jni_options = {"jni_libs": ["libmixedjava.so"]}
|
|
635
|
-
project = angr.Project(jar_path, main_opts=jni_options)
|
|
636
|
-
else:
|
|
637
|
-
project = angr.Project(jar_path)
|
|
638
|
-
return project
|
|
639
|
-
|
|
640
|
-
def load_string(self, state, local_name):
|
|
641
|
-
str_ref = self.load_value_from_stack(state, local_name)
|
|
642
|
-
return state.memory.load(str_ref)
|
|
643
|
-
|
|
644
|
-
def load_value_from_stack(self, state, symbol_name):
|
|
645
|
-
try:
|
|
646
|
-
return state.memory.stack.load(symbol_name)
|
|
647
|
-
except KeyError:
|
|
648
|
-
return None
|
|
649
|
-
|
|
650
|
-
def get_entry_state_of_method(self, project, method_fullname):
|
|
651
|
-
# get SootAddressDescriptor of method entry
|
|
652
|
-
soot_method = project.loader.main_object.get_soot_method(method_fullname)
|
|
653
|
-
method = SootMethodDescriptor.from_soot_method(soot_method)
|
|
654
|
-
addr = SootAddressDescriptor(method, 0, 0)
|
|
655
|
-
# create call state
|
|
656
|
-
return project.factory.blank_state(addr=addr, add_options={angr.options.ZERO_FILL_UNCONSTRAINED_MEMORY})
|
|
657
|
-
|
|
658
|
-
def get_last_state_of_method(self, project, method_fullname):
|
|
659
|
-
state = self.get_entry_state_of_method(project, method_fullname)
|
|
660
|
-
# run until no successors exists
|
|
661
|
-
# Note: this does not work if conditional branches are present
|
|
662
|
-
states = [state]
|
|
663
|
-
succ = states[-1].step()
|
|
664
|
-
while len(succ.successors) == 1:
|
|
665
|
-
states += succ
|
|
666
|
-
succ = states[-1].step()
|
|
667
|
-
# last state is the 'Terminator' state
|
|
668
|
-
# => return the state before
|
|
669
|
-
return states[-2]
|
|
670
|
-
|
|
671
|
-
def get_winning_paths(self, project, method_fullname):
|
|
672
|
-
state = self.get_entry_state_of_method(project, method_fullname)
|
|
673
|
-
simgr = project.factory.simgr(state)
|
|
674
|
-
simgr.run()
|
|
675
|
-
paths = simgr.deadended
|
|
676
|
-
|
|
677
|
-
# winning paths output a single 'W' on stdout
|
|
678
|
-
winnning_paths = []
|
|
679
|
-
for pp in paths:
|
|
680
|
-
stdout_packets = pp.posix.stdout.content
|
|
681
|
-
read_byte, _ = stdout_packets[0]
|
|
682
|
-
# a winning path is printing 'W'
|
|
683
|
-
pp.solver.add(read_byte == pp.solver.BVV(ord("W"), 8))
|
|
684
|
-
if pp.satisfiable():
|
|
685
|
-
winnning_paths.append(pp)
|
|
686
|
-
|
|
687
|
-
return winnning_paths
|
|
688
|
-
|
|
689
|
-
def get_winning_path(self, project, method_fullname):
|
|
690
|
-
winning_paths = self.get_winning_paths(project, method_fullname)
|
|
691
|
-
assert len(winning_paths) != 0
|
|
692
|
-
assert len(winning_paths) == 1
|
|
693
|
-
return winning_paths[0]
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
if __name__ == "__main__":
|
|
697
|
-
unittest.main()
|