def run(self): mgr = frida.get_device_manager() on_devices_changed = lambda: self._reactor.schedule(self._try_start) mgr.on('changed', on_devices_changed) self._reactor.schedule(self._try_start) self._reactor.schedule(self._show_message_if_no_device, delay=1) signal.signal(signal.SIGTERM, self._on_sigterm) self._reactor.run() if self._started: try: self._perform_on_background_thread(self._stop) except frida.OperationCancelledError: pass if self._session is not None: self._session.off('detached', self._schedule_on_session_detached) try: self._perform_on_background_thread(self._session.detach) except frida.OperationCancelledError: pass self._session = None if self._device is not None: self._device.off('output', self._schedule_on_output) self._device.off('lost', self._schedule_on_device_lost) mgr.off('changed', on_devices_changed) frida.shutdown() sys.exit(self._exit_status)
def run(self): mgr = frida.get_device_manager() on_devices_changed = lambda: self._reactor.schedule(self._try_start) mgr.on('changed', on_devices_changed) self._reactor.schedule(self._try_start) self._reactor.schedule(self._show_message_if_no_device, delay=1) old_sigterm_handler = signal.signal(signal.SIGTERM, lambda n, f: self._exit(0)) self._reactor.run() signal.signal(signal.SIGTERM, old_sigterm_handler) if self._started: self._stop() if self._session is not None: self._session.off('detached', self._schedule_on_session_detached) self._session.detach() self._session = None if self._device is not None: self._device.off('output', self._schedule_on_output) self._device.off('lost', self._schedule_on_device_lost) mgr.off('changed', on_devices_changed) frida.shutdown() sys.exit(self._exit_status)
def run(self): while len(self._procstack) > 0: name = self._procstack.pop() print("[*] Attaching to: " + name) pid = frida.spawn([name]) session = frida.attach(pid) session.on('detached', self.on_detached) script = session.create_script(code) script.on('message', lambda m, d: self.on_message(m, d)) script.load() frida.resume(pid) with self._lock: self._cond.wait() frida.shutdown()
def run(self): mgr = frida.get_device_manager() on_devices_changed = lambda: self._reactor.schedule(self._try_start) mgr.on('changed', on_devices_changed) self._reactor.schedule(self._try_start) self._reactor.schedule(self._show_message_if_no_device, delay=0.1) self._reactor.run() if self._started: self._stop() if self._process is not None: self._process.off('detached', self._schedule_on_process_detached) self._process.detach() self._process = None if self._device is not None: self._device.off('lost', self._schedule_on_device_lost) mgr.off('changed', on_devices_changed) frida.shutdown() sys.exit(self._exit_status)
def run(self): mgr = frida.get_device_manager() on_devices_changed = lambda: self._reactor.schedule(self._try_start) mgr.on('changed', on_devices_changed) self._reactor.schedule(self._try_start) self._reactor.schedule(self._show_message_if_no_device, delay=0.1) self._reactor.run() if self._started: self._stop() if self._session is not None: self._session.off('detached', self._schedule_on_session_detached) self._session.detach() self._session = None if self._spawned_pid is not None: try: self._device.kill(self._spawned_pid) except: pass if self._device is not None: self._device.off('lost', self._schedule_on_device_lost) mgr.off('changed', on_devices_changed) frida.shutdown() sys.exit(self._exit_status)
def run(self): mgr = frida.get_device_manager() on_devices_changed = lambda: self._reactor.schedule(self._try_start) mgr.on('changed', on_devices_changed) self._reactor.schedule(self._try_start) self._reactor.schedule(self._show_message_if_no_device, delay=0.1) self._reactor.run() if self._started: self._stop() if self._session is not None: self._session.off('detached', self._schedule_on_session_detached) self._session.detach() self._session = None if self._spawned_pid is not None: try: self._device.kill(self._spawned_pid) except: pass if self._device is not None: self._device.off('output', self._schedule_on_output) self._device.off('lost', self._schedule_on_device_lost) mgr.off('changed', on_devices_changed) frida.shutdown() sys.exit(self._exit_status)
def main(): import colorama from colorama import Fore, Back, Style import frida from frida.core import Reactor from optparse import OptionParser import sys colorama.init(autoreset=True) usage = "usage: %prog [options] process-name-or-id" parser = OptionParser(usage=usage) (options, args) = parser.parse_args() if len(args) != 1: parser.error("process name or id must be specified") try: target = int(args[0]) except: target = args[0] class Application(UI): def __init__(self, target): self._target = target self._process = None self._discoverer = None self._status_updated = False self._exit_status = 0 self._reactor = Reactor(await_enter) self._reactor.schedule(self._start) def run(self): self._reactor.run() self._stop() return self._exit_status def _start(self): try: self._update_status("Attaching...") self._process = frida.attach(self._target) except Exception as e: self._update_status("Failed to attach: %s" % e) self._exit_status = 1 self._reactor.schedule(self._stop) return self._update_status("Injecting script...") self._discoverer = Discoverer(self._reactor) self._discoverer.start(self._process, self) def _stop(self): if self._discoverer is not None: print("Stopping...") self._discoverer.stop() self._discoverer = None if self._process is not None: self._process.detach() self._process = None self._reactor.stop() def _update_status(self, message): if self._status_updated: cursor_position = "\033[A" else: cursor_position = "" print("%-80s" % (cursor_position + Style.BRIGHT + message,)) self._status_updated = True def on_sample_progress(self, begin, end, total): self._update_status("Sampling %d threads: %d through %d..." % (total, begin, end)) def on_sample_result(self, module_functions, dynamic_functions): for module, functions in module_functions.items(): print(module.name) print("\t%-10s\t%s" % ("Rate", "Function")) for function, rate in sorted(functions, key=lambda item: item[1], reverse=True): print("\t%-10d\t%s" % (rate, function)) print("") if len(dynamic_functions) > 0: print("Dynamic functions:") print("\t%-10s\t%s" % ("Rate", "Function")) for function, rate in sorted(dynamic_functions, key=lambda item: item[1], reverse=True): print("\t%-10d\t%s" % (rate, function)) self._reactor.schedule(self._stop) def await_enter(): if sys.version_info[0] >= 3: input() else: raw_input() app = Application(target) status = app.run() frida.shutdown() sys.exit(status)
def main(): import colorama from colorama import Fore, Back, Style import frida from frida.core import Reactor from optparse import OptionParser import sys colorama.init(autoreset=True) tp = TracerProfileBuilder() def process_builder_arg(option, opt_str, value, parser, method, **kwargs): method(value) usage = "usage: %prog [options] process-name-or-id" parser = OptionParser(usage=usage) parser.add_option("-I", "--include-module=MODULE", help="include MODULE", metavar="MODULE", type='string', action='callback', callback=process_builder_arg, callback_args=(tp.include_modules,)) parser.add_option("-X", "--exclude-module=MODULE", help="exclude MODULE", metavar="MODULE", type='string', action='callback', callback=process_builder_arg, callback_args=(tp.exclude_modules,)) parser.add_option("-i", "--include=FUNCTION", help="include FUNCTION", metavar="FUNCTION", type='string', action='callback', callback=process_builder_arg, callback_args=(tp.include,)) parser.add_option("-x", "--exclude=FUNCTION", help="exclude FUNCTION", metavar="FUNCTION", type='string', action='callback', callback=process_builder_arg, callback_args=(tp.exclude,)) (options, args) = parser.parse_args() if len(args) != 1: parser.error("process name or id must be specified") try: target = int(args[0]) except: target = args[0] profile = tp.build() class Application(UI): def __init__(self, target, profile): self._target = target self._process = None self._tracer = None self._profile = profile self._status_updated = False self._exit_status = 0 self._reactor = Reactor(await_enter) self._reactor.schedule(self._start) def run(self): self._reactor.run() self._stop() return self._exit_status def _start(self): try: self._update_status("Attaching...") self._process = frida.attach(self._target) except Exception as e: self._update_status("Failed to attach: %s" % e) self._exit_status = 1 self._reactor.schedule(self._stop) return self._tracer = Tracer(self._reactor, FileRepository(), self._profile) targets = self._tracer.start_trace(self._process, self) if len(targets) == 1: plural = "" else: plural = "s" self._update_status("Started tracing %d function%s. Press ENTER to stop." % (len(targets), plural)) def _stop(self): if self._tracer is not None: print("Stopping...") self._tracer.stop() self._tracer = None if self._process is not None: self._process.detach() self._process = None self._reactor.stop() def on_trace_progress(self, operation): if operation == 'resolve': self._update_status("Resolving functions...") elif operation == 'upload': self._update_status("Uploading data...") elif operation == 'ready': self._update_status("Ready!") def on_trace_events(self, events): self._status_updated = False for timestamp, target_address, message in events: print("%6d ms\t%s" % (timestamp, message)) def on_trace_handler_create(self, function, handler, source): print("%s: Auto-generated handler at \"%s\"" % (function, source)) def on_trace_handler_load(self, function, handler, source): print("%s: Loaded handler at \"%s\"" % (function, source)) def _update_status(self, message): if self._status_updated: cursor_position = "\033[A" else: cursor_position = "" print("%-80s" % (cursor_position + Style.BRIGHT + message,)) self._status_updated = True def await_enter(): if sys.version_info[0] >= 3: input() else: raw_input() app = Application(target, profile) status = app.run() frida.shutdown() sys.exit(status)
def run(self): main_dir = os.path.join(CUCKOO_ROOT, "storage", "analyses", str(self._id)) file_dir = os.path.join(main_dir, "file") log_dir = os.path.join(main_dir, "logs") pending = [] spawns = {} sessions = {} scripts = {} anti_emulator_events = {} self._event = Event() def on_child(child): log.debug("on_child: {}".format(child)) def on_spawned(spawn_in): log.debug('on_spawned: {}'.format(spawn_in)) if spawn_in.identifier in exception_list: self._device.resume(spawn_in.pid) else: pending.append(spawn_in) self._event.set() def on_removed(spawn_out): log.debug('on_removed: {}'.format(spawn_out)) s = sessions.get(spawn_out.pid) if s: scr = scripts[spawn_out.pid] scr.unload() log.debug('on_removed - unload: {}'.format(spawn_out)) s.detach() # respond to "send" in javascript # message {type:(send || error), payload: (str || list || dict)} def on_message(message, data): if message.get("type") == "send": payload = message.get("payload") # log.debug("on_message - payload: {}".format(payload)) pid = payload.get("Process") if pid: pid = spawns.get(pid, pid) t = payload.get("type") if t == "file": # payload {"Process" : Process.id, "file" : fs.readFileSync(path), "path" : path} # log.debug("on_message: {} - file - path {}".format(pid, payload.get("path"))) msg = payload.get("message") # log.debug('on_message: {} {} {}'.format(pid, msg, data)) data = payload.get("file") write_to_file(file_dir, payload.get("path"), data) # log.debug("on_message: {} - successfully write file {}".format(pid, payload.get("path"))) elif t == "msg": # payload {"Process" : Process.id, "message" : "{Content}"}; msg = payload.get("message") log.debug('on_message: {} {} {}'.format(pid, msg, data)) elif t == 'log': # send({"type":"log", "Process" : Process.id, "log": fs.readFileSync(path) ,"message":msg}); msg = payload.get("message") log.debug('on_message: {} {} {}'.format(pid, msg, data)) data = payload.get("log") title = payload.get("title", "temp_log") temp = self._log_count self._log_count += 1 write_to_file(log_dir, "{}_{}.log".format(title, temp), data) elif t == 'droidmon': msg = payload.get("message") data = payload.get("data") c = data.get('class') if c and anti_emulator_events.get(c): anti_emulator_events[c].append(data) elif not anti_emulator_events.get(c): anti_emulator_events[c] = [data] log.debug('on_message: {} {} {}'.format(pid, msg, data)) write_to_file(log_dir, "emulatorDetect.log", data, json_enabled=True) elif t == 'recv_wait': # TODO: server-side intercept msg = payload.get("message") data = payload.get("data") # TODO: Logic handling s = scripts.get(pid) if s: # s.post({JSON}) pass log.debug('on_message: {} {} {}'.format(pid, msg, data)) else: log.debug("{} {}".format(message, data)) try: log.debug("Run") log.debug("Device: {}".format(self._device)) self._device.on('spawn-added', on_spawned) # self._device.on('child-added', on_child) # self._device.on('spawn-removed', on_removed) self._device.enable_spawn_gating() log.debug("Enabled spawn gating") for spawn in self._device.enumerate_pending_spawn(): self._device.resume(spawn.pid) self._ready = True while True: while len(pending) == 0: self._event.wait() if self._stop_flag: raise ValueError("Task #{}: {} is terminated.".format( self._id, self._device)) self._event.clear() spawn = pending.pop() if spawn.identifier is not None and spawn.identifier not in exception_list: log.debug('Instrumenting: {}'.format(spawn)) session = self._device.attach(spawn.pid) # session.enable_jit() # TODO: Handle subprocess # session.enable_child_gating() # Early instrumentation by rpc exports feature script = session.create_script(get_script(self._platform)) script.on('message', on_message) script.load() script.exports.init() # script.exports.debug() log.debug('Instrumented: {}'.format(spawn)) sessions[spawn.pid] = session scripts[spawn.pid] = script spawns[spawn.pid] = spawn try: self._device.resume(spawn.pid) except Exception as e: if 'unable to find process with pid' in str(e): pass else: raise CuckooFridaError(e) time.sleep(1) # script.exports.modules() else: log.debug('Not instrumenting: {}'.format(spawn)) self._device.resume(spawn.pid) time.sleep(1) log.debug('Processed: {}'.format(spawn)) except ValueError as normal: self._device.off('spawn-added', on_spawned) self.unset_adb() log.debug(normal) except KeyboardInterrupt as k: self.unset_adb() frida.shutdown() log.debug(k) except Exception as e: self.unset_adb() self._stop_flag = True raise CuckooFridaError(e)