serve_bridge() 桥接服务
🔌 响应 frida 17 的
frida:load-bridge请求,把 Java/ObjC 桥接源码回传给脚本。
📎 源码在线查看:
r0capture.py#L256-L276(serve_bridge)
背景:frida 17 的破坏性变化
frida 17 起不再把 Java/ObjC 桥接内置进运行时。脚本里首次用到 Java 时,会发一条 {type:"frida:load-bridge", name:"Java"} 消息给 host(Python 端)。host 必须把 frida-java-bridge 的 JS 源码读出来,通过 script.post 回传,脚本再 Script.evaluate 注入,此后 Java 对象才可用。
- frida CLI 内置了这个 host 逻辑
- r0capture 作为独立 host 必须自己实现,否则 frida 17 下 script.js 里所有 Java 层 hook 全部失效
桥接源码来源
python
_bridges_dir = None
try:
import frida_tools
from pathlib import Path as _P
_bridges_dir = _P(frida_tools.__file__).parent / "bridges"
except Exception:
pass复用 frida_tools 包自带的 bridges/*.js,无需联网下载。
函数实现
python
def serve_bridge(name, script):
if _bridges_dir is None:
return
bridge_path = _bridges_dir / f"{name.lower()}.js"
if not bridge_path.exists():
return
with open(bridge_path, "r", encoding="utf-8") as f:
source = f.read()
script.post({
"type": "frida:bridge-loaded",
"filename": bridge_path.name,
"source": source,
})流程:name(如 "Java")→ 找 bridges/java.js → 读源码 → script.post 回传 {type:"frida:bridge-loaded", ...}。
与 on_message 的衔接
on_message 收到桥接请求时调 serve_bridge:
python
payload = message.get("payload")
if isinstance(payload, dict) and payload.get("type") == "frida:load-bridge":
serve_bridge(payload.get("name"), script)
return注意要传正确的 script 对象:主 script 的桥接请求 post 回主 script,selftest script 的请求 post 回 selftest script,否则会错位。详见 selftest 脚本。
失效后果
若不实现 serve_bridge,frida 17 下 script.js 里所有 Java 块都会失效:
- ❌ 客户端证书导出(
KeyStore$PrivateKeyEntryhook) - ❌ SSL Pinning 定位(
File.$inithook) - ❌ 裸 TCP 抓取(
SocketOutputStream/InputStreamhook) - ❌ SSL 调用栈抓取(Conscrypt
SSLOutputStream/InputStreamhook)
仅 Native 层 SSL_read/SSL_write 仍可用(不依赖 Java)。