有些读者可能知道,Frida 有两个 JavaScript 运行时:一个基于 V8,另一个基于 Duktape。 我们过去还有一个基于 JavaScriptCore 的运行时,但后来事实证明,在所有不适合 V8 的场景中,例如微型嵌入式系统以及禁止 RWX 内存页的系统上,Duktape 运行时都表现得更好,因此 JavaScriptCore 运行时退役了。
值得一提的是,Duktape 提供了编译为字节码的 API。这样就能缓存已编译的代码,在需要 对新进程进行插桩时节省宝贵的启动时间。从本次发布开始,我们提供了全新的 API,可将 JavaScript 编译为字节码,当然也可以从字节码实例化脚本。V8 运行时尚不支持此 API, 不过下次升级 V8 后,我们应该可以利用最近版本中开始出现的 WebAssembly 基础设施来实现它。
闲话少叙,让我们通过 Session.disable_jit() 强制 Frida 优先使用 Duktape,试用一下 Duktape 运行时中的这项新 API。
在 Node.js 中:
const co = require('co');
const frida = require('frida');
co(function* () {
const systemSession = yield frida.attach(0);
yield systemSession.disableJit();
const bytecode = yield systemSession.compileScript(`
rpc.exports = {
listThreads() {
return Process.enumerateThreadsSync();
}
};
`);
const session = yield frida.attach('Twitter');
yield session.disableJit();
const script = yield session.createScriptFromBytes(bytecode);
yield script.load();
const api = yield script.getExports();
console.log('api.listThreads() =>', yield api.listThreads());
yield script.unload();
})
.catch(err => {
console.error(err);
});在 Python 中:
import frida
system_session = frida.attach(0)
system_session.disable_jit()
bytecode = system_session.compile_script("""
rpc.exports = {
listThreads() {
return Process.enumerateThreadsSync();
}
};
""")
session = frida.attach("Twitter")
session.disable_jit()
script = session.create_script_from_bytes(bytecode)
script.load()
api = script.exports
print("api.list_threads() =>", api.list_threads())请注意,此处同样存在 Duktape 文档中说明 的限制,因此请确保要加载的代码格式正确,并由同一版本的 Duktape 生成。升级到未来版本的 Frida 时,Duktape 可能也会升级;不过字节码至少与架构无关,也就是说,你可以在 64 位 x86 桌面系统上编译为字节码,再顺利加载到 ARM 上的 32 位 iOS 应用中。
以上是通过 API 编译字节码,不过你可能更希望改用 frida-compile CLI 工具:
$ npm install frida-compile
$ ./node_modules/.bin/frida-compile agent.js -o agent.bin -b开发期间还可以添加 -w 使用监视模式。该模式会监视输入,并在其中任意文件变化时执行 快速增量构建。
无论是否使用字节码(-b),我们都强烈推荐 frida-compile,因为它还有许多其他优点, 可以让你:
- 使用 require() 将脚本拆分成多个 .js 文件。
- 利用 npm 上成千上万个现有模块,其中也包括一些 Frida 专用模块。例如: frida-trace、 frida-uikit、 frida-screenshot 等。
- 使用 ES6 语法,并将代码编译为 ES5,以兼容 Duktape 运行时。
最后,我们来汇总一下变更:
7.2.0:
- core:支持编译和加载字节码,以及从字节码加载
- core:在 RPC 错误响应中包含错误名称和堆栈跟踪
- node:支持新的字节码 API
- node:在可用时为 RPC 错误补充 name 和 stack
- node:将示例迁移到 ES6
- python:支持新的字节码 API
- python:适配修订后的 RPC 协议
7.2.1:
- objc:支持解析精简 Objective-C 代理上的方法
7.2.2:
- objc:修复返回结构体和浮点值的方法处理
7.2.3:
- objc:公开 Objective-C 方法的原始句柄
7.2.4:
- core:修复在 iOS 9 上很容易复现的死锁
- java:提高 Java.perform() 的稳健性,并改进对非应用进程的处理
7.2.5:
- objc:修复 x86-64 上通过寄存器返回结构体的方法处理
7.2.6:
- core:将 Gum 移植到 MIPS
- core:避免在 Proxy 对象行为异常时吞掉异常
- objc:支持访问 Objective-C 实例变量
7.2.7:
- core:将 .so 注入器移植到 MIPS
- core:为 MIPS 模糊回溯器增加更多分支并链接指令
- core:修复 UnixInputStream 和 UnixOutputStream 在 TTY 上的可轮询行为, 解决脚本卸载时挂起的问题
- core:移除 hexdump() 偏移量中的“0x”前缀
7.2.8:
- objc:修复类型提示解析
- objc:支持包含类型提示
- objc:公开 ObjC.Block 的 types 字段
- objc:支持正确声明 void *
- core:(MIPS)修复获取/设置栈参数时的栈偏移
7.2.9:
- core:修复 V8 运行时中无法写入寄存器的错误
7.2.10:
- core:支持附加到 iOS 模拟器进程
- core:修复 7.2.4 引入的 Android 类解析回归
7.2.11:
- core:始终通过 SpringBoard 终止 iOS 应用
7.2.12:
- objc:在卸载和 GC 时注销 Objective-C 类
7.2.13:
- core:修复 iOS 9 上的应用终止逻辑
7.2.14:
- core:让 Duktape 运行时像 V8 运行时一样可被抢占
- core:修复 V8 运行时中的几个锁错误
7.2.15:
- core:也在 Duktape 运行时中实现 Kernel API
- core:移除危险的 Kernel.enumerateThreads() API
7.2.16:
- core:提高快速重新附加到同一进程时的稳健性
- core:修复分离时存在待处理调用所导致的死锁
- core:修复 32 位 ARM 上的挂钩回归
- core:修复 Linux 上 frida-gadget 中的 dlsym() 死锁
- core:修复 Windows 构建回归
- core:修复 iOS 7 回归
7.2.17:
- core:修复会话拆卸回归
7.2.18:
- core:修复 iOS 9 上长期存在的稳定性问题:注入的引导代码未进行伪签名,导致进程 最终失去 CS_VALID 状态
- core:消除不必要的磁盘 I/O,加快 iOS 应用启动速度
- core:修复 iOS 上的临时目录清理
7.2.19:
- core:修复 Duktape 运行时中与抢占相关的生命周期问题
7.2.20:
- core:重构 V8 运行时,以支持完全异步卸载
- core:重构 Duktape 运行时,以支持完全异步卸载
- core:让 Duktape 运行时完全可重入
- core:新增 Script.pin() 和 Script.unpin(),用于在关键时刻延长脚本生命周期, 例如等待来自无法控制的外部 API 的回调时
- core:修复 V8 和 Duktape 运行时中与定时器相关的泄漏
- objc:让脚本保持存活,直到 ObjC.schedule() 调度的回调执行完毕
- objc:向 ObjC 代理 API 添加 dealloc 事件
7.2.21:
- core:修复 detach() 时挂起的问题
7.2.22:
- core:修复脚本卸载时挂起的问题
- core:修复 detach() 期间连接突然中断时挂起的问题
7.2.23:
- core:修复脚本卸载期间两个低概率崩溃问题
7.2.24:
- core:修复 Duktape 运行时中的释放后使用问题
- core:修复 ModuleApiResolver 中的释放后使用错误
- core:改进设置异常处理程序时的卸载行为
7.2.25:
- core:修复 iOS 9.3.3 上的应用启动
- frida-server:修复另一个客户端附加到同一进程时,分离操作“挂起”的问题
尽情使用吧!
oleavr