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)
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