rhino 与 frida 双引擎——两套写法各自擅长什么
为什么有两套
JsHook 同时内置两套 JavaScript 运行时:rhino 引擎和 Frida 引擎。这不是功能重复,而是覆盖两类不同的用户群体:
- rhino 引擎:提供 Xposed 风格的 API,适合以前用过 Xposed/LSPosed 写模块的开发者。
- Frida 引擎:完整暴露 Frida 原生 JS API,适合熟悉 Frida 命令行工具链的用户。
两套引擎各自独立运行,不会在同一个脚本里混用。每个脚本在声明时就要确定是 rhino 类型还是 frida 类型。
rhino 引擎
rhino 是一个纯 Java 实现的 JavaScript 引擎,JsHook 在它上面封装了一套 Xposed 风格的 API。
特点:
- 运行在 JVM 内,与目标应用的 Java 层同进程
- 提供类似
XposedHelpers的静态辅助方法 - 更轻量,对目标应用性能影响小
- 只能 Hook Java 层
适合场景:
- 以前写过 Xposed 模块,想快速迁移
- 只需要 Hook Java 层,不碰 native
- 目标应用对性能敏感
注意:rhino 类型脚本不能和 frida 系框架(fridamod / fridainject / fridagadget)配合使用。rhino 脚本走的是另一套注入路径。
Frida 引擎
Frida 引擎是完整的 Frida JS API 实现,通过 fridamod / fridainject / fridagadget 三种框架注入。
特点:
- 完整的 Frida API:
Java.use()、Interceptor、Module、Memory、Process、NativeFunction - 同时覆盖 Java 层和 native 层(SO 库、IL2CPP)
- 支持内核驱动模式
- 支持加密脚本
- 可被电脑端 frida 直连调试
适合场景:
- 需要 native 层 Hook(libil2cpp.so、libgame.so 等)
- 需要内核驱动模式
- 需要加密脚本
- 需要电脑端联动调试
怎么区分脚本类型
在脚本仓库的 JSON 列表里,每条脚本有一个 type 字段:
{
"id": "abc123",
"title": "金币修改",
"type": "frida",
"url": "https://example.com/gold.js",
...
}
type 取值:rhino 或 frida。
JsHook 在给目标应用配置 Hook 服务时,会根据你勾选的脚本类型自动匹配可用框架——rhino 类型脚本只走 rhino 引擎,frida 类型脚本走 frida 系框架。如果选了不匹配的框架,会提示框架与脚本类型不兼容。
两套引擎的 API 不能混用
这是新手最容易踩的坑之一:
- 在 Frida 类型脚本里不能用 Xposed 风格的静态辅助方法
- 在 rhino 类型脚本里不能用
Interceptor.attach()、Module.findBaseAddress()等 Frida API Java.perform()和Java.use()是 Frida 风格,rhino 引擎下不可用
写脚本之前先确认自己用的是哪种引擎,然后按对应的 API 文档写。
选哪个
| 条件 | 推荐引擎 |
|---|---|
| 只会 Xposed 写法,不会 Frida | rhino |
| 需要 native 层 Hook | Frida |
| 需要内核驱动模式 | Frida(配合 fridamod) |
| 需要加密脚本 | Frida(配合 fridamod) |
| 需要电脑端联动 | Frida |
| 目标应用是 Unity(IL2CPP) | Frida |
| 只是 Hook 一些 Java 方法改改返回值 | 都行,看你熟悉哪套 |