# -*- coding: utf-8 -*- from __future__ import print_function import threading import frida from frida_tools.application import Reactor class Application(object): def __init__(self): self._stop_requested = threading.Event() self._reactor = Reactor(run_until_return=lambda reactor: self._stop_requested.wait()) self._device = frida.get_local_device() self._sessions = set() self._device.on("child-added", lambda child: self._reactor.schedule(lambda: self._on_child_added(child))) self._device.on("child-removed", lambda child: self._reactor.schedule(lambda: self._on_child_removed(child))) self._device.on("output", lambda pid, fd, data: self._reactor.schedule(lambda: self._on_output(pid, fd, data))) def run(self): self._reactor.schedule(lambda: self._start()) self._reactor.run() def _start(self): argv = ["/bin/sh", "-c", "cat /etc/hosts"] env = { "BADGER": "badger-badger-badger", "SNAKE": "mushroom-mushroom", } print("✔ spawn(argv={})".format(argv)) pid = self._device.spawn(argv, env=env, stdio='pipe') self._instrument(pid) def _stop_if_idle(self): if len(self._sessions) == 0: self._stop_requested.set() def _instrument(self, pid): print("✔ attach(pid={})".format(pid)) session = self._device.attach(pid) session.on("detached", lambda reason: self._reactor.schedule(lambda: self._on_detached(pid, session, reason))) print("✔ enable_child_gating()") session.enable_child_gating() print("✔ create_script()") script = session.create_script("""\ Interceptor.attach(Module.getExportByName(null, 'open'), { onEnter: function (args) { send({ type: 'open', path: Memory.readUtf8String(args[0]) }); } }); """) script.on("message", lambda message, data: self._reactor.schedule(lambda: self._on_message(pid, message))) print("✔ load()") script.load() print("✔ resume(pid={})".format(pid)) self._device.resume(pid) self._sessions.add(session) def _on_child_added(self, child): print("⚡ child_added: {}".format(child)) self._instrument(child.pid) def _on_child_removed(self, child): print("⚡ child_removed: {}".format(child)) def _on_output(self, pid, fd, data): print("⚡ output: pid={}, fd={}, data={}".format(pid, fd, repr(data))) def _on_detached(self, pid, session, reason): print("⚡ detached: pid={}, reason='{}'".format(pid, reason)) self._sessions.remove(session) self._reactor.schedule(self._stop_if_idle, delay=0.5) def _on_message(self, pid, message): print("⚡ message: pid={}, payload={}".format(pid, message["payload"])) app = Application() app.run()