Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def get_last_state_of_method(method_name):
# get SootAddressDescriptor of method entry
soot_method = next(project.loader.main_object.get_method(method_name))
method = SootMethodDescriptor.from_soot_method(soot_method)
addr = SootAddressDescriptor(method, 0, 0)
# create call state
state = project.factory.blank_state(addr=addr)
# run until no successors exists
# Note: this does not work if conditional branches are present
states = [state]
succ = states[-1].step()
while len(succ.successors) == 1:
states += succ
succ = states[-1].step()
# last state is the 'Terminator' state
# => return the state before
return states[-2]
def get_entry_state_of_method(project, method_fullname):
# get SootAddressDescriptor of method entry
soot_method = project.loader.main_object.get_soot_method(method_fullname)
method = SootMethodDescriptor.from_soot_method(soot_method)
addr = SootAddressDescriptor(method, 0, 0)
# create call state
return project.factory.blank_state(addr=addr, add_options={angr.options.ZERO_FILL_UNCONSTRAINED_MEMORY})
def _get_next_linear_instruction(state, stmt_idx):
addr = state.addr.copy()
addr.stmt_idx = stmt_idx
method = state.regs._ip_binary.get_soot_method(addr.method)
current_bb = method.blocks[addr.block_idx]
new_stmt_idx = addr.stmt_idx + 1
if new_stmt_idx < len(current_bb.statements):
return SootAddressDescriptor(addr.method, addr.block_idx, new_stmt_idx)
else:
new_bb_idx = addr.block_idx + 1
if new_bb_idx < len(method.blocks):
return SootAddressDescriptor(addr.method, new_bb_idx, 0)
else:
l.warning("falling into a non existing bb: %d in %s",
new_bb_idx, SootMethodDescriptor.from_soot_method(method))
raise IncorrectLocationException()
binary_path = os.path.join(self_dir, "bin/service.jar")
jni_options = {'jni_libs': ['libnotfun.so']}
project = angr.Project(binary_path, main_opts=jni_options)
# hooks
project.hook(SootMethodDescriptor(class_name="java.util.Random", name="nextInt", params=('int',)).address(), Random_nextInt())
project.hook(SootMethodDescriptor(class_name="java.lang.Integer", name="valueOf", params=('int',)).address(), Dummy_valueOf())
project.hook(SootMethodDescriptor(class_name="NotFun", name="print", params=('java.lang.Object',)).address(), Custom_Print())
project.hook(SootMethodDescriptor(class_name="NotFun", name="getInt", params=()).address(), Custom_getInt())
# set entry point to the 'game' method
game_method = [m for m in project.loader.main_object.classes['NotFun'].methods
if m.name == "game"][0]
game_entry = SootMethodDescriptor.from_soot_method(game_method).address()
entry = project.factory.blank_state(addr=game_entry)
simgr = project.factory.simgr(entry)
# Create a fake file with what it is going to be printed to the user (concrete)
fake_output_fd = entry.posix.open(b"/fake/output", Flags.O_RDWR)
ff = entry.posix.fd[fake_output_fd]
tstr = b"".join([bytes(str(n), 'utf-8') + b"\n" for n in numbers])
ff.write_data(tstr, len(tstr))
ff.seek(0)
# Create a fake file with what the user as to insert (symbolic)
fake_input_fd = entry.posix.open(b"/fake/input", Flags.O_RDWR)
ff = entry.posix.fd[fake_input_fd]
solutions = [claripy.BVS("solution%d" % (i), 32) for i in range(3)]
for s in solutions:
ff.write_data(s, 4)
def resolve_method(state, method_name, class_name, params=(), ret=None, attrs=[], exceptions=()):
java_binary = state.project.loader.main_object
class_hierarchy = state.javavm_classloader.get_class_hierarchy(class_name)
# walk up in class hierarchy
for class_ in class_hierarchy:
# try to fetch the method from the binary in every class
soot_method = java_binary.get_method(method_name, class_.name, attrs, params,
ret, exceptions, none_if_missing=True)
if soot_method:
# if method was found, load der class and return an opaque reference to it
state.javavm_classloader.load_class(class_)
return SootMethodDescriptor.from_soot_method(soot_method)
else:
# method could not be found in loaded classes
# => we are executing code that is not in CLE (typically library code)
# fallback: use only infos from the invocation, so we can still use SimProcedures
l.warning("Couldn't find method {class_name}.{method_name} in class(es) {class_hierarchy}."
"".format(class_name=class_name, method_name=method_name,
class_hierarchy=", ".join([str(c.name) for c in
state.javavm_classloader.get_class_hierarchy(class_name)])))
return SootMethodDescriptor(class_name, method_name, params)
l.debug("Lifting to Soot IR ...")
start_time = time.time()
pysoot_lifter = Lifter(self.binary,
input_format=input_format,
android_sdk=android_sdk,
additional_jars=additional_jars,
additional_jar_roots=additional_jar_roots)
end_time = time.time()
l.debug("Lifting completed in %ds", round(end_time - start_time, 2))
self._classes = pysoot_lifter.classes
# find entry method
if entry_point:
try:
ep_method = self.get_soot_method(entry_point, params=entry_point_params)
ep_method_descriptor = SootMethodDescriptor.from_soot_method(ep_method)
self._entry = SootAddressDescriptor(ep_method_descriptor, 0, 0)
l.debug("Entry point set to %s", self._entry)
except CLEError:
l.warning("Couldn't find entry point %s.", entry_point)
self._entry = None
self.os = 'javavm'
self.rebase_addr = None
self.set_arch(ArchSoot())
if jni_libs:
# native libraries are getting loaded by adding them as a dependency of this object
self.deps += [jni_libs] if type(jni_libs) in (str, bytes) else jni_libs
# if available, add additional load path(s)
if jni_libs_ld_path:
path_list = [jni_libs_ld_path] if type(jni_libs_ld_path) in (str, bytes) else jni_libs_ld_path