Skip to content

frida17 bootstrap 引导代码 ​

🚀 拼在 script.js 前面注入的引导段,把 Java 桥接做成本地懒加载全局对象。

📎 源码在线查看:r0capture.py#L408-L425(_FRIDA17_BOOTSTRAP)

拼接位置 ​

python
script = session.create_script(_FRIDA17_BOOTSTRAP + "\n" + _FRIDA_SCRIPT)

_FRIDA17_BOOTSTRAP 是一段纯 JS,拼在 script.js 最前面,最先执行。

完整代码 ​

javascript
(function () {
  if (typeof Java !== 'undefined') { return; }  // 老版本已内置
  function defineBridge(name) {
    Object.defineProperty(globalThis, name, {
      enumerable: true, 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");
})();

工作原理 ​

关键设计 ​

1. typeof Java !== 'undefined' 短路 ​

老版本 frida 已内置 Java,直接 return,bootstrap 无副作用,向后兼容。

2. Object.defineProperty getter 懒加载 ​

首次访问 Java 才触发 getter,发起 load-bridge 请求。

3. recv(...).wait() 同步等待 ​

getter 里 recv("frida:bridge-loaded", cb).wait() 同步阻塞,直到 host post 回源码,保证返回前 Java 已就绪。

4. 固化为 value ​

拿到 bridge 后,用 value: b 的数据描述符替换掉 getter 描述符:

javascript
Object.defineProperty(globalThis, name, { value: b, configurable: true, writable: true });

之后访问 Java 直接返回值,不再触发 getter,避免每次访问都重新加载。

selftest 的独立 bootstrap ​

selftest script 也内置了同样的 bootstrap(因为它是独立 script,不共享主 script 的 globalThis)。详见 selftest 脚本。

相关文档 ​

基于 VitePress 构建 · 教学用途