Skip to content

Frida 17 兼容性 ​

Frida 17 是个破坏性大版本:Java 桥接不再内置,导致 r0capture 的所有 Java 层 hook 失效。本篇讲清楚问题与修复。

问题:Java 桥接消失了 ​

Frida 16 及之前,脚本里直接用 Java.use(...) 是理所当然的——Java 对象由 frida-java-bridge 提供,内置在运行时。Frida 17 改了:

Frida 17 把 frida-java-bridge 从运行时里拿掉了,改为按需加载:脚本第一次访问 Java 时,向 host 发请求要桥接源码,host 把源码注入进来。

加载协议:frida:load-bridge ​

这是 Frida 17 新增的 host↔script 协议:

关键:frida CLI(frida 命令)实现了这个 host 逻辑,但 r0capture.py 作为独立 host 没实现——所以 Frida 17 下 r0capture 的 Java 层 hook 全废。

后果:哪些功能失效 ​

script.js 里这一行决定了 Java hook 生死:

javascript
if (typeof Java !== 'undefined' && Java.available) { ... }

Frida 17 下 Java 未定义,整个 if 块不执行,导致:

修复方案 ​

r0capture.py 加两处改动即可:

1. host 端:实现 bridge 服务 ​

python
import frida_tools
from pathlib import Path

_bridges_dir = Path(frida_tools.__file__).parent / "bridges"

def serve_bridge(name, script):
    bridge_path = _bridges_dir / f"{name.lower()}.js"
    if not bridge_path.exists():
        return
    source = bridge_path.read_text(encoding="utf-8")
    script.post({
        "type": "frida:bridge-loaded",
        "filename": bridge_path.name,
        "source": source,
    })

def on_message(message, data):
    payload = message.get("payload")
    # 识别 bridge 请求
    if isinstance(payload, dict) and payload.get("type") == "frida:load-bridge":
        serve_bridge(payload.get("name"), script)
        return
    # ... 正常处理 SSL 明文

2. 脚本端:注入 lazy getter 引导 ​

在 script.js 加载前,注入一段引导代码,让 Java 变成一个"用到时才加载"的 lazy getter:

javascript
(function () {
  if (typeof Java !== 'undefined') return;  // 老版本已有,跳过
  function defineBridge(name) {
    Object.defineProperty(globalThis, name, {
      configurable: true,
      get: function () {
        send({ type: "frida:load-bridge", name: name });  // ① 请求
        var b;
        recv("frida:bridge-loaded", function (s) {        // ② 等回传
          b = Script.evaluate(s.filename,
            "(function () { " + s.source + "\nreturn bridge; })()");
        }).wait();
        Object.defineProperty(globalThis, name,          // ③ 替换成真值
          { value: b, configurable: true, writable: true });
        return b;
      }
    });
  }
  defineBridge("Java");
})();

多 script 不共享 globalThis

Frida 17 下每个 script 有独立 globalThis,引导代码要在每个 script 里都注入一次(包括 selftest 用的独立 script)。

验证:--selftest ​

修复后用 --selftest 一键验证整个链路(Java 桥接 + SSL hook + pcap 写入):

bash
python3 r0capture.py -H 127.0.0.1:27042 7033 --selftest -v -p st.pcap
# 看到 [selftest] result={'code': 200, 'bodylen': 558} 就是全通了

selftest 脚本本身也自带 defineBridge 引导,且它的 bridge 请求由独立的 on_selftest_message 处理(post 回 selftest script 而非主 script)——避免多 script 串扰。

推荐版本搭配 ​

FridaAndroid
17.x16
16.5.214
15.2.212

下一篇:Conscrypt 与 0.0.0.0 →

基于 VitePress 构建 · 教学用途