Skip to content

Commit 22ed1fa

Browse files
committed
examples: Add a spawn gating example
1 parent 9b15bde commit 22ed1fa

1 file changed

Lines changed: 80 additions & 0 deletions

File tree

examples/spawn_gating.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import threading
2+
3+
from frida_tools.application import Reactor
4+
5+
import frida
6+
7+
8+
class Application:
9+
def __init__(self):
10+
self._stop_requested = threading.Event()
11+
self._reactor = Reactor(run_until_return=lambda reactor: self._stop_requested.wait())
12+
13+
self._device = frida.get_usb_device()
14+
self._sessions = set()
15+
self._sessions_lock = threading.Lock()
16+
17+
self._device.on("spawn-added", lambda spawn: self._reactor.schedule(lambda: self._on_spawn_added(spawn)))
18+
self._device.on("spawn-removed", lambda spawn: self._reactor.schedule(lambda: self._on_spawn_removed(spawn)))
19+
20+
def run(self):
21+
self._reactor.schedule(lambda: self._start())
22+
self._reactor.run()
23+
24+
def _start(self):
25+
self._device.enable_spawn_gating()
26+
27+
def _instrument(self, pid):
28+
print(f"✔ attach(pid={pid})")
29+
session = self._device.attach(pid)
30+
session.on("detached", lambda reason: self._reactor.schedule(lambda: self._on_detached(pid, session, reason)))
31+
print("✔ create_script()")
32+
script = session.create_script(
33+
"""\
34+
const puts = new NativeFunction(Module.getGlobalExportByName('puts'), 'int', ['pointer']);
35+
puts(Memory.allocUtf8String('Hello from Frida agent'));
36+
Interceptor.attach(Module.getGlobalExportByName('open'), {
37+
onEnter(args) {
38+
send({
39+
type: 'open',
40+
path: args[0].readUtf8String()
41+
});
42+
}
43+
});
44+
"""
45+
)
46+
script.on("message", lambda message, data: self._reactor.schedule(lambda: self._on_message(pid, message)))
47+
print("✔ load()")
48+
script.load()
49+
print(f"✔ resume(pid={pid})")
50+
self._device.resume(pid)
51+
with self._sessions_lock:
52+
self._sessions.add(session)
53+
54+
def _on_spawn_added(self, spawn):
55+
print(f"⚡ spawn_added: {spawn}")
56+
t = threading.Thread(target=self._handle_spawn, args=(spawn,))
57+
t.start()
58+
59+
def _handle_spawn(self, spawn):
60+
if "/bin/ls" in spawn.identifier:
61+
self._instrument(spawn.pid)
62+
else:
63+
pid = spawn.pid
64+
print(f"✔ resume(pid={pid})")
65+
self._device.resume(pid)
66+
67+
def _on_spawn_removed(self, spawn):
68+
print(f"⚡ spawn_removed: {spawn}")
69+
70+
def _on_detached(self, pid, session, reason):
71+
print(f"⚡ detached: pid={pid}, reason='{reason}'")
72+
with self._sessions_lock:
73+
self._sessions.remove(session)
74+
75+
def _on_message(self, pid, message):
76+
print(f"⚡ message: pid={pid}, payload={message['payload']}")
77+
78+
79+
app = Application()
80+
app.run()

0 commit comments

Comments
 (0)