Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
this_ref = self.state.memory.load(this_ref_base, none_if_missing=True)
this_ref_type = this_ref.type if this_ref is not None else None
args += [SootArgument(this_ref, this_ref_type, is_this_ref=True)]
# translate function arguments
for arg in self.expr.args:
if "Constant" in arg.__class__.__name__:
# argument is a constant
# => translate the expr to get the value
arg_value = self._translate_expr(arg).expr
else:
# argument is a variable
# => load value from memory
arg_value = self.state.memory.load(self._translate_value(arg),
none_if_missing=True)
args += [SootArgument(arg_value, arg.type)]
return args
def _setup_native_callsite(cls, state, native_addr, java_method, args, ret_addr, ret_var):
# Step 1: setup java callsite, but w/o storing arguments in memory
cls.setup_callsite(state, None, ret_addr, ret_var)
# Step 2: add JNI specific arguments to *args list
# get JNI environment pointer
jni_env = SootArgument(state.project.simos.jni_env, "JNIEnv")
# get reference to the current object or class
if args and args[0].is_this_ref:
# instance method call
# => pass 'this' reference to native code
ref = args.pop(0)
else:
# static method call
# => pass 'class' reference to native code
class_ = state.javavm_classloader.get_class(java_method.class_name, init_class=True)
ref = SootArgument(class_, "Class")
# add to args
final_args = [jni_env, ref] + args
# Step 3: create native invoke state
# Step 2: add JNI specific arguments to *args list
# get JNI environment pointer
jni_env = SootArgument(state.project.simos.jni_env, "JNIEnv")
# get reference to the current object or class
if args and args[0].is_this_ref:
# instance method call
# => pass 'this' reference to native code
ref = args.pop(0)
else:
# static method call
# => pass 'class' reference to native code
class_ = state.javavm_classloader.get_class(java_method.class_name, init_class=True)
ref = SootArgument(class_, "Class")
# add to args
final_args = [jni_env, ref] + args
# Step 3: create native invoke state
return state.project.simos.state_call(native_addr, *final_args,
base_state=state,
ret_type=java_method.ret)
def _setup_java_args(self, arg_values, method_id, this_ref=None):
args = []
# if available, add 'this' reference
if this_ref:
args += [ SootArgument(this_ref, this_ref.type, is_this_ref=True) ]
# function arguments
for arg_value_, arg_type in zip(arg_values, method_id.params):
if arg_type in ArchSoot.primitive_types:
# argument has a primitive integral type
# => cast native value to java type
arg_value = self.project.simos.cast_primitive(self.state,
value=arg_value_,
to_type=arg_type)
else:
# argument has a relative type
# => lookup java object
arg_value = self.state.jni_references.lookup(arg_value_)
def state_entry(self, args=None, **kwargs): # pylint: disable=arguments-differ
"""
Create an entry state.
:param args: List of SootArgument values (optional).
"""
state = self.state_blank(**kwargs)
# for the Java main method `public static main(String[] args)`,
# we add symbolic cmdline arguments
if not args and state.addr.method.name == 'main' and \
state.addr.method.params[0] == 'java.lang.String[]':
cmd_line_args = SimSootExpr_NewArray.new_array(state, "java.lang.String", BVS('argc', 32))
cmd_line_args.add_default_value_generator(self.generate_symbolic_cmd_line_arg)
args = [SootArgument(cmd_line_args, "java.lang.String[]")]
# for referencing the Java array, we need to know the array reference
# => saves it in the globals dict
state.globals['cmd_line_args'] = cmd_line_args
# setup arguments
SimEngineSoot.setup_arguments(state, args)
return state
native_arg_values = []
for arg in args:
if arg.type in ArchSoot.primitive_types or \
arg.type == "JNIEnv":
# the value of primitive types and the JNIEnv pointer
# are just getting copied into the native memory
native_arg_value = arg.value
if self.arch.bits == 32 and arg.type == "long":
# On 32 bit architecture, long values (w/ 64 bit) are copied
# as two 32 bit integer
# TODO is this correct?
upper = native_arg_value.get_bytes(0, 4)
lower = native_arg_value.get_bytes(4, 4)
idx = args.index(arg)
args = args[:idx] \
+ (SootArgument(upper, 'int'), SootArgument(lower, 'int')) \
+ args[idx+1:]
native_arg_values += [upper, lower]
continue
else:
# argument has a relative type
# => map Java reference to an opaque reference, which the native code
# can use to access the Java object through the JNI interface
native_arg_value = state.jni_references.create_new_reference(obj=arg.value)
native_arg_values += [native_arg_value]
# setup native return type
ret_type = kwargs.pop('ret_type')
native_ret_type = self.get_native_type(ret_type)
# setup function prototype, so the SimCC know how to init the callsite
arg_types = [self.get_native_type(arg.type) for arg in args]
if not os.path.exists(sdk_path):
print("cannot run test_apk_loading since there is no Android SDK folder")
return
apk_location = os.path.join(file_dir, "androidnative1.apk")
loading_opts = {'android_sdk': sdk_path,
'entry_point': 'com.angr.nativetest1.MainActivity.onCreate',
'entry_point_params': ('android.os.Bundle', ),
'supported_jni_archs': ['x86']}
project = angr.Project(apk_location, main_opts=loading_opts)
project.hook(SootMethodDescriptor(class_name="java.lang.String", name="valueOf", params=('int',)).address(), Dummy_String_valueOf())
blank_state = project.factory.blank_state()
a1 = SimSootValue_ThisRef.new_object(blank_state, 'com.angr.androidnative1.MainActivity')
a2 = SimSootValue_ThisRef.new_object(blank_state, 'android.os.Bundle', symbolic = True)
args = [SootArgument(arg, arg.type) for arg in [a1, a2]]
entry = project.factory.entry_state(args = args)
simgr = project.factory.simgr(entry)
simgr.run()
int_result = simgr.deadended[0].solver.eval(result)
assert int_result == 221