Skip to content

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$PrivateKeyEntry hook)
  • ❌ SSL Pinning 定位(File.$init hook)
  • ❌ 裸 TCP 抓取(SocketOutputStream/InputStream hook)
  • ❌ SSL 调用栈抓取(Conscrypt SSLOutputStream/InputStream hook)

仅 Native 层 SSL_read/SSL_write 仍可用(不依赖 Java)。

相关文档 ​

基于 VitePress 构建 · 教学用途