Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def state_call(self, addr, *args, **kwargs):
"""
Create a native or a Java call state.
:param addr: Soot or native addr of the invoke target.
:param args: List of SootArgument values.
"""
state = kwargs.pop('base_state', None)
# check if we need to setup a native or a java callsite
if isinstance(addr, SootAddressDescriptor):
# JAVA CALLSITE
# ret addr precedence: ret_addr kwarg > base_state.addr > terminator
ret_addr = kwargs.pop('ret_addr', state.addr if state else SootAddressTerminator())
cc = kwargs.pop('cc', SimCCSoot(self.arch))
if state is None:
state = self.state_blank(addr=addr, **kwargs)
else:
state = state.copy()
state.regs.ip = addr
cc.setup_callsite(state, ret_addr, args)
return state
else:
# NATIVE CALLSITE
# setup native argument values
native_arg_values = []
for arg in args:
if arg.type in ArchSoot.primitive_types or \
arg.type == "JNIEnv":
return
l.debug("Initialize class %r.", class_)
self.initialized_classes.add(class_)
if not class_.is_loaded:
l.warning("Class %r is not loaded in CLE. Skip initializiation.", class_)
return
clinit_method = resolve_method(self.state, '', class_.name,
include_superclasses=False, init_class=False)
if clinit_method.is_loaded:
javavm_simos = self.state.project.simos
clinit_state = javavm_simos.state_call(addr=SootAddressDescriptor(clinit_method, 0, 0),
base_state=self.state,
ret_addr=SootAddressTerminator())
simgr = self.state.project.factory.simgr(clinit_state)
l.info(">"*15 + " Run class initializer %r ... " + ">"*15, clinit_method)
simgr.run(step_func=step_func)
l.debug("<"*15 + " Run class initializer %r ... done " + "<"*15, clinit_method)
# The only thing that can be updated during initialization are
# static or rather global information, which are either stored on
# the heap or in the vm_static_table
self.state.memory.vm_static_table = simgr.deadended[-1].memory.vm_static_table.copy()
self.state.memory.heap = simgr.deadended[-1].memory.heap.copy()
else:
l.debug("Class initializer is not loaded in CLE. Skip initializiation.")
:return: Reference to the new object.
"""
# create reference
obj_ref = cls(heap_alloc_id=state.memory.get_new_uuid(), type_=type_, symbolic=symbolic)
# run initializer
if init_object:
l.info(">" * 15 + " Initialize object %r ... " + ">" * 15, obj_ref)
# find initializer method
# TODO: add support for non-default initializing methods
init_method = resolve_method(state, '', type_, init_class=False).address()
# setup init state
args = [SootArgument(obj_ref, obj_ref.type, is_this_ref=True)]
init_state = state.project.simos.state_call(init_method, *args,
base_state=state,
ret_addr=SootAddressTerminator())
# run init state
simgr = state.project.factory.simgr(init_state)
simgr.run()
# copy results from initialization to the state
state.memory.vm_static_table = simgr.deadended[0].memory.vm_static_table.copy()
state.memory.heap = simgr.deadended[0].memory.heap.copy()
l.debug("<" * 15 + " Initialize object %r ... done " + "<" * 15, obj_ref)
return obj_ref
def _process(self, state, successors, *args, **kwargs):
addr = state._ip
if isinstance(addr, SootAddressTerminator):
successors.processed = True
return
if self.project.use_sim_procedures:
procedure = self._get_sim_procedure(addr)
if procedure is not None:
self.project.factory.procedure_engine._process(state, successors, procedure)
return
binary = state.regs._ip_binary
method = binary.get_soot_method(addr.method, none_if_missing=True)
# TODO make the skipping of code in "android.*" classes optional
if addr.method.class_name.startswith('android.') or not method:
# This means we are executing code that is not in CLE, typically library code.
# We may want soot -> pysoot -> cle to export at least the method names of the libraries
if not self.project.entry and not addr:
raise ValueError("Failed to init blank state. Project entry is not set/invalid "
"and no address was provided.")
# init state register
state.regs._ip = addr if addr else self.project.entry
state.regs._ip_binary = self.project.loader.main_object
state.regs._invoke_return_target = None
state.regs._invoke_return_variable = None
# add empty stack frame
state.memory.push_stack_frame()
# create bottom of callstack
new_frame = state.callstack.copy()
new_frame.ret_addr = SootAddressTerminator()
state.callstack.push(new_frame)
# initialize class containing the current method
state.javavm_classloader.get_class(state.addr.method.class_name,
init_class=True, step_func=kwargs.get('step_function', None))
# initialize the Java environment
# TODO move this to `state_full_init?
self.init_static_field(state, "java.lang.System", "in", "java.io.InputStream")
self.init_static_field(state, "java.lang.System", "out", "java.io.PrintStream")
return state
def __init__(self):
dummy_method = SootMethodDescriptor("dummy", "dummy", tuple())
super(SootAddressTerminator, self).__init__(dummy_method, 0, 0)