Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_toggling_of_simstate(binary_dir="2"):
project = create_project(binary_dir)
state = project.factory.entry_state()
assert state.ip_is_soot_addr
assert isinstance(state.arch, ArchSoot)
assert isinstance(state.memory, SimJavaVmMemory)
assert isinstance(state.registers, SimKeyValueMemory)
state.regs.ip = 1
assert not state.ip_is_soot_addr
assert isinstance(state.arch, ArchAMD64)
assert isinstance(state.memory, SimSymbolicMemory)
assert isinstance(state.registers, SimSymbolicMemory)
state.regs._ip = project.entry
assert state.ip_is_soot_addr
assert isinstance(state.arch, ArchSoot)
assert isinstance(state.memory, SimJavaVmMemory)
assert isinstance(state.registers, SimKeyValueMemory)
def decode_type_signature(type_sig):
if not type_sig:
return None
# try to translate signature as a primitive type
if type_sig in ArchSoot.sig_dict:
return ArchSoot.sig_dict[type_sig]
# java classes are encoded as 'Lclass_name;'
if type_sig.startswith('L') and type_sig.endswith(';'):
return type_sig[1:-1]
raise ValueError(type_sig)
# When executing a Java JNI application, we need to update the state's
# instruction pointer flag every time the ip gets written.
# This flag will then toggle between the native and the java view of the
# state.
if self.state.project and \
isinstance(self.state.project.arch, ArchSoot) and \
k == 'ip' and \
self.state.project.simos.is_javavm_with_jni_support:
self.state.ip_is_soot_addr = isinstance(v, SootAddressDescriptor)
try:
return self.state.registers.store(k, v, inspect=inspect, disable_actions=disable_actions)
except KeyError:
# What do we do in case we are dealing with soot? there are no register
if isinstance(self.state.arch, ArchSoot):
pass
else:
raise AttributeError(k)
invoke_target = resolve_method(self.state, method_id.name, class_name, method_id.params)
invoke_addr = SootAddressDescriptor(invoke_target, 0, 0)
# get args
no_of_args = len(invoke_target.params)
if args_in_array is not None:
arg_values = self._get_arg_values_from_array(args_in_array, no_of_args)
else:
arg_values = self._get_arg_values(no_of_args)
# setup java args
java_args = self._setup_java_args(arg_values, invoke_target, this_ref=obj)
# call java method
# => after returning, the execution will be continued in _return_result_of_computation
self.call(invoke_addr, java_args, "return_from_invocation", cc=SimCCSoot(ArchSoot()))
if o.SIMPLIFY_EXIT_TARGET in state.options:
state.scratch.target = state.solver.simplify(state.scratch.target)
# unwrap stuff from SimActionObjects
state.scratch.target = _raw_ast(state.scratch.target)
state.scratch.guard = _raw_ast(state.scratch.guard)
# apply the guard constraint and new program counter to the state
if add_guard:
state.add_constraints(state.scratch.guard)
# trigger inspect breakpoints here since this statement technically shows up in the IRSB as the "next"
state.regs.ip = state.scratch.target
# For architectures with no stack pointer, we can't manage a callstack. This has the side effect of breaking
# SimProcedures that call out to binary code self.call.
if self.initial_state.arch.sp_offset is not None and not isinstance(state.arch, ArchSoot):
self._manage_callstack(state)
if len(self.successors) != 0:
# This is a fork!
state._inspect('fork', BP_AFTER)
# clean up the state
state.options.discard(o.AST_DEPS)
state.options.discard(o.AUTO_REFS)
if self.processed:
successor_strings = [ ]
if len(self.flat_successors) != 0:
successor_strings.append("%d sat" % len(self.flat_successors))
if len(self.unsat_successors) != 0:
successor_strings.append("%d unsat" % len(self.unsat_successors))
if len(self.unconstrained_successors) != 0:
successor_strings.append("%d unconstrained" % len(self.unconstrained_successors))
if len(successor_strings) == 0:
result = 'empty'
else:
result = ' '.join(successor_strings)
else:
result = 'failure'
if isinstance(self.initial_state.arch, ArchSoot):
return '<%s from %s: %s>' % (self.description, self.addr, result)
return '<%s from %#x: %s>' % (self.description, self.addr, result)
def get_native_type(self, java_type):
"""
Maps the Java type to a SimTypeReg representation of its native
counterpart. This type can be used to indicate the (well-defined) size
of native JNI types.
:return: A SymTypeReg with the JNI size of the given type.
"""
if java_type in ArchSoot.sizeof.keys():
jni_type_size = ArchSoot.sizeof[java_type]
else:
# if it's not a primitive type, we treat it as a reference
jni_type_size = self.native_simos.arch.bits
return SimTypeReg(size=jni_type_size)
def run(self, ptr_env, class_, ptr_method_name, ptr_method_sig):
# class name
class_name = self.state.jni_references.lookup(class_).class_name
# method name
method_name = self._load_string_from_native_memory(ptr_method_name)
# param and return types
method_sig = self._load_string_from_native_memory(ptr_method_sig)
params, ret = ArchSoot.decode_method_signature(method_sig)
# create SootMethodDescriptor as id and return a opaque reference to it
# Note: we do not resolve the method at this point, because the method id can be
# used with different objects
# TODO test case
# used both for virtual invokes and special invokes (see invoke expr in Soot
# engine). The actual invoke type gets determined later, based on the type
# of jni function (CallMethod vs. CallNonVirtualMethod)
method_id = SootMethodDescriptor(class_name=class_name, name=method_name,
params=params, ret=ret)
return self.state.jni_references.create_new_reference(method_id)
# Step 5: determine the guest OS
if isinstance(simos, type) and issubclass(simos, SimOS):
self.simos = simos(self) #pylint:disable=invalid-name
elif isinstance(simos, str):
self.simos = os_mapping[simos](self)
elif simos is None:
self.simos = os_mapping[self.loader.main_object.os](self)
else:
raise ValueError("Invalid OS specification or non-matching architecture.")
self.is_java_project = isinstance(self.arch, ArchSoot)
self.is_java_jni_project = isinstance(self.arch, ArchSoot) and self.simos.is_javavm_with_jni_support
# Step 6: Register simprocedures as appropriate for library functions
if isinstance(self.arch, ArchSoot) and self.simos.is_javavm_with_jni_support:
# If we execute a Java archive that includes native JNI libraries,
# we need to use the arch of the native simos for all (native) sim
# procedures.
sim_proc_arch = self.simos.native_arch
else:
sim_proc_arch = self.arch
for obj in self.loader.initial_load_objects:
self._register_object(obj, sim_proc_arch)
# Step 7: Run OS-specific configuration
self.simos.configure_project()
self.analyses.use_plugin_preset(analyses_preset if analyses_preset is not None else 'default')
# Step 4.3: ...etc
self.kb = KnowledgeBase(self)
# Step 5: determine the guest OS
if isinstance(simos, type) and issubclass(simos, SimOS):
self.simos = simos(self) #pylint:disable=invalid-name
elif isinstance(simos, str):
self.simos = os_mapping[simos](self)
elif simos is None:
self.simos = os_mapping[self.loader.main_object.os](self)
else:
raise ValueError("Invalid OS specification or non-matching architecture.")
self.is_java_project = isinstance(self.arch, ArchSoot)
self.is_java_jni_project = isinstance(self.arch, ArchSoot) and self.simos.is_javavm_with_jni_support
# Step 6: Register simprocedures as appropriate for library functions
if isinstance(self.arch, ArchSoot) and self.simos.is_javavm_with_jni_support:
# If we execute a Java archive that includes native JNI libraries,
# we need to use the arch of the native simos for all (native) sim
# procedures.
sim_proc_arch = self.simos.native_arch
else:
sim_proc_arch = self.arch
for obj in self.loader.initial_load_objects:
self._register_object(obj, sim_proc_arch)
# Step 7: Run OS-specific configuration
self.simos.configure_project()