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 脚本。