版权归作者所有,如有转发,请注明文章出处:cyrus-studio.github.io/blog/
使用 Chrome 断点调试 JS
只需要在执行 frida 命令时,加上下面参数即可:
css
--runtime=v8 --debug
参数说明:
-
--runtime=v8,指定 Frida 使用 V8 引擎(Google Chrome 使用的 JS 引擎)来运行 JS 脚本。默认 Frida 使用 QuickJS 引擎(轻量但功能有限,调试能力较差)。
-
--debug,启用调试模式,输出更多细节信息,包括:脚本加载日志、错误栈追踪、JS 异常信息等
关于 Frida 的详细使用参考:一文搞懂如何使用 Frida Hook Android App
比如:
- 启动应用并附加到当前启动进程
ini
frida -H 127.0.0.1:1234 -l classloader_utils.js -f com.shizhuang.duapp --runtime=v8 --debug
- 附加到当前设备的前台应用
ini
frida -H 127.0.0.1:1234 -F -l classloader_utils.js --runtime=v8 --debug
当你看到:Chrome Inspector server listening on port 9229,这说明你已经成功开启了一个 Frida(V8 模式)调试服务
bash
(anti-app) PS D:\Python\anti-app\frida_java> frida -H 127.0.0.1:1234 -F -l classloader_utils.js --runtime=v8 --debug
____
/ _ | Frida 14.2.18 - A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about 'object'
. . . . exit/quit -> Exit
. . . .
. . . . More info at https://www.frida.re/docs/home/
Chrome Inspector server listening on port 9229
[Remote::**]->
在 Chrome 浏览器地址栏输入:
arduino
chrome://inspect
点击 Open dedicated DevTools for Node

切换到 Sources Tab,Ctrl + Shift + P 加载调试脚本,在 Node 中打开要调试的脚本,可以看到源码,下断点调试

动态调试相关快捷键:
快捷键(Windows) | 快捷键(Mac) | 功能说明 |
---|---|---|
F12 / Ctrl + Shift + I | Cmd + Option + I | 打开/关闭开发者工具 |
Ctrl + P | Cmd + P | 快速打开文件(搜索源码) |
Ctrl + Shift + F | Cmd + Option + F | 全局搜索源码内容 |
F8 | F8 | 继续执行(Resume) |
F10 | F10 | 单步执行(Step Over) |
F11 | F11 | 进入函数(Step Into) |
F9 | F9 | 单步调试(Step) |
Shift + F11 | Shift + F11 | 跳出函数(Step Out) |
Ctrl + F8 | Cmd + F8 | 切换断点的启用/禁用状态 |
Esc | Esc | 切换 Console 面板 |
Ctrl + / | Cmd + / | 注释/取消注释选中代码 |
Alt + ← / → | Ctrl + - / + | 源码导航前进/后退 |
在 Console 中可以直接调用 js 中的函数

原理拆解(结合 Frida 源码)
用 Chrome 断点调试 Frida 脚本,本质上是利用 Frida 提供的 V8 引擎(--runtime=v8)和 Chrome DevTools 协议(Inspector Protocol)建立调试通道。
增加 --debug 参数会开启 Chrome DevTools 协议服务(WebSocket 监听 9229 端口),Chrome DevTools 就可以像调试 Node.js 一样对 Frida 脚本进行断点、单步、变量查看等操作。
python
def _on_script_created(self, script: frida.core.Script) -> None:
if self._enable_debugger:
script.enable_debugger()
self._print("Chrome Inspector server listening on port 9229\n")
Frida 支持 qjs(默认) 和 v8 JS 引擎,在 frida-core 源码中可以看到:
csharp
const OptionEntry[] options = {
{ "device", 'D', 0, OptionArg.STRING, ref device_id, "connect to device with the given ID", "ID" },
{ "file", 'f', 0, OptionArg.STRING, ref spawn_file, "spawn FILE", "FILE" },
{ "pid", 'p', 0, OptionArg.INT, ref target_pid, "attach to PID", "PID" },
{ "name", 'n', 0, OptionArg.STRING, ref target_name, "attach to NAME", "NAME" },
{ "realm", 'r', 0, OptionArg.STRING, ref realm_str, "attach in REALM", "REALM" },
{ "script", 's', 0, OptionArg.FILENAME, ref script_path, null, "JAVASCRIPT_FILENAME" },
{ "runtime", 'R', 0, OptionArg.STRING, ref script_runtime_str, "Script runtime to use", "qjs|v8" },
{ "parameters", 'P', 0, OptionArg.STRING, ref parameters_str, "Parameters as JSON, same as Gadget", "PARAMETERS_JSON" },
{ "eternalize", 'e', 0, OptionArg.NONE, ref eternalize, "Eternalize script and exit", null },
{ "interactive", 'i', 0, OptionArg.NONE, ref interactive, "Interact with script through stdin", null },
{ "development", 0, 0, OptionArg.NONE, ref enable_development, "Enable development mode", null },
{ "version", 0, 0, OptionArg.NONE, ref output_version, "Output version information and exit", null },
{ null }
};
Frida 提供 V8 和 QuickJS 两个 runtime,是为了在追求高性能(V8)和低资源消耗、快速启动、移植性强(QuickJS)之间做出权衡,并支持更强的调试能力(V8 支持 Chrome DevTools)。