第3章 CLI 工具详解

本章基于 Frida 17.9.11 (frida-tools 14.x) 编写。

3.1 frida(交互式 REPL)

基本用法

# 附加到本地进程
frida Calculator
 
# 附加到 USB 设备上的应用
frida -U com.example.app
 
# 附加到指定设备
frida -D 0216027d1d6d3a03 com.example.app
 
# 启动新进程(挂起状态)
frida -U -f com.example.app
 
# 按应用标识符附加
frida -U -N com.example.app
 
# 加载脚本文件
frida -U com.example.app -l hook.js
 
# 启用调试(Node.js 兼容)
frida -U com.example.app -l hook.js --debug
 
# 连接远程 frida-server(带认证)
frida -H 192.168.1.100 --token "secret" com.example.app
 
# 使用 P2P 连接模式
frida -U --p2p com.example.app

常用参数

参数说明
-U, --usb连接 USB 设备
-D ID, --device ID连接指定设备
-R, --remote连接远程 frida-server
-H HOST, --host HOST连接指定主机上的 frida-server
--certificate CERTTLS 证书(用于远程连接)
--origin ORIGIN设置 Origin 头(远程连接)
--token TOKEN远程认证 token
--keepalive-interval SEC保活间隔(秒)
--p2p建立 P2P 连接
--stun-server ADDRP2P 模式下 STUN 服务器
--relay SPEC添加 P2P 中继
-f TARGET, --file TARGETSpawn 目标进程(从头开始)
-F, --attach-frontmost附加到前台应用
-n NAME, --attach-name NAME按进程名附加
-N ID, --attach-identifier ID按应用标识符附加
-p PID, --attach-pid PID按 PID 附加
-W PATTERN, --await PATTERN等待匹配 spawn
-l SCRIPT加载 JavaScript 脚本
--debug启用 Node.js 兼容调试器(端口 5858)
--runtime {qjs,v8}选择 JS 运行时
--stdio {inherit,pipe}控制 stdio 行为
--realm {native,emulated}附加领域
--squelch-crash抑制崩溃报告输出

REPL 特性

  • Tab 补全函数和类名
  • %reload 命令重新加载脚本
  • 使用 -l 时文件变更自动重载
  • 可直接访问: Process, Module, Interceptor, Stalker, Java, ObjC
  • 17.0+ 注意: Memory.readU32() 等静态方法已移除,使用指针方法如 ptr.readU32()
  • 17.0+ 注意: Module.findBaseAddress() 等静态方法已移除,使用 Process.getModuleByName()

3.2 frida-ps(进程列表)

# 列出 USB 设备上所有进程
frida-ps -U
 
# 仅列出运行中的应用
frida-ps -Ua
 
# 列出所有已安装应用(包括未运行的)
frida-ps -Uai
 
# 指定设备
frida-ps -D 0216027d1d6d3a03
 
# 列出远程设备
frida-ps -H 192.168.1.100
 
# 列出本地进程
frida-ps
参数说明
-U, --usb连接 USB 设备
-D ID, --device ID指定设备
-R, --remote连接远程 frida-server
-H HOST, --host HOST连接指定主机
-a仅列出运行中的应用
-i包含已安装但未运行的应用

3.3 frida-trace(函数追踪)

自动生成 hook handler 并追踪函数调用,支持 Native、Java、ObjC、Swift。

Native 函数追踪

# 追踪 recv* 和 send* 函数
frida-trace -U -i "recv*" -i "send*" com.example.app
 
# Spawn 模式追踪
frida-trace -U -f com.example.app -i "open"
 
# 带模块名装饰
frida-trace -U -i "recv*" -d com.example.app
 
# 追踪非导出函数(按偏移)
frida-trace -U -a "libfoo.so!0x1234" com.example.app
 
# 追踪整个模块的导出
frida-trace -U -I "libssl.so" com.example.app
 
# 排除特定函数
frida-trace -U -I "libssl.so" -x "SSL_read" com.example.app

Java 方法追踪

# 追踪 Java 方法(glob 模式)
frida-trace -U -j "com.example.app.MainActivity!on*" com.example.app
 
# 追踪所有方法,排除系统包
frida-trace -U -j "*!*" -J "java.lang.*!*" com.example.app

Objective-C 追踪

# 追踪 ObjC 方法
frida-trace -U -m "-[NSView drawRect:]" Safari
 
# 排除 ObjC 方法
frida-trace -U -m "-[NS* *]" -M "-[NSObject *]" Safari

完整参数列表

连接参数(与 frida 通用):

参数说明
-U, --usbUSB 连接
-D ID, --device ID指定设备
-R, --remote远程连接
-H HOST, --host HOST连接指定主机
--certificate CERTTLS 证书
--token TOKEN认证 token

目标选择:

参数说明
-f TARGET, --file TARGETSpawn 目标
-F, --attach-frontmost附加前台应用
-n NAME, --attach-name NAME按名称附加
-N ID, --attach-identifier ID按标识符附加
-p PID, --attach-pid PID按 PID 附加
-W PATTERN, --await PATTERN等待匹配 spawn

追踪选项:

参数说明
-i FUNC, --include FUNC包含函数(glob 模式)
-x FUNC, --exclude FUNC排除函数
-I MODULE, --include-module MODULE包含模块的所有函数
-X MODULE, --exclude-module MODULE排除模块
-a MODULE!OFFSET, --add MODULE!OFFSET追踪非导出函数
-j JAVA_METHOD, --include-java-method包含 Java 方法
-J JAVA_METHOD, --exclude-java-method排除 Java 方法
-m OBJC_METHOD, --include-objc-method包含 ObjC 方法
-M OBJC_METHOD, --exclude-objc-method排除 ObjC 方法
-T包含程序导入
-t MODULE包含模块导入

会话与输出:

参数说明
-S PATH, --init-session PATH会话初始化 JS 文件
-P JSON, --parameters JSON全局暴露 JSON 参数
-O FILE, --options-file FILE从文件加载选项
-d, --decorate日志中添加模块名
-q, --quiet静默格式
-o OUTPUT, --output OUTPUT输出到文件
--ui-port PORTUI 服务端口

⚠️ 重要: include/exclude 操作是程序化的,顺序很重要!每个 -i/-x 按顺序修改工作集。


3.4 frida-ls-devices(设备列表)

$ frida-ls-devices
Id                                        Type    Name
----------------------------------------  ------  ----------------
local                                     local   Local System
0216027d1d6d3a03                          tether  Samsung SM-G920F
simulator                                 simmy   iPhone 15 Pro
tcp                                       remote  Local TCP

设备类型:

  • local — 主机本身
  • tether — USB 连接的设备
  • remote — TCP/网络连接
  • simmy — Apple 模拟器(17.4+ 新增 Simmy 后端)

3.5 frida-kill(终止进程)

# 终止指定 PID
frida-kill -U 5029
 
# 指定设备
frida-kill -D 0216027d1d6d3a03 5029

典型工作流:

  1. frida-ps -Ua — 找到目标 PID
  2. frida-kill -U <PID> — 终止
  3. frida-ps -Ua — 确认已终止

3.6 frida-discover(函数发现)

发现程序内部的非导出函数,可用于后续 frida-trace 追踪:

# 发现运行进程中的函数
frida-discover -U com.example.app

发现的函数可通过 frida-trace -a MODULE!OFFSET 追踪。


3.7 frida-strace(系统调用追踪)— 17.8+ 新增

跨平台系统调用追踪工具,支持 Android 和 iOS(无需 root/越狱),底层基于 eBPF(Linux/Android)和 ktrace/kdebug(iOS)实现。

基本用法

# Spawn 并追踪应用的系统调用
frida-strace -f "com.example.app"
 
# 追踪已运行的进程(按 PID)
frida-strace -p 1234
 
# 追踪多个进程
frida-strace -p 1234 -p 5678
 
# Spawn 多个程序
frida-strace -f "com.example.app" -f "/bin/ls -la"
 
# 按用户名追踪(Android)
frida-strace -u u0_a123
 
# 按 UID 追踪
frida-strace --uid 10123
 
# 仅追踪特定系统调用
frida-strace -p 1234 -i openat -i read -i write
 
# 排除特定系统调用
frida-strace -p 1234 -x futex -x clock_gettime

参数列表

参数说明
-f, --file TARGETSpawn 目标(可重复),参数以字符串传入
-p, --pid PID追踪指定 PID(可重复)
-u, --user NAME追踪指定用户的进程(可重复)
--uid UID追踪指定 UID 的进程(可重复)
-i, --include SYSCALL仅追踪指定系统调用(可重复)
-x, --exclude SYSCALL排除指定系统调用(可重复)
--limit NUI 中保留的最大事件数(默认 5000)

特性:

  • 自动解码系统调用参数(文件路径重建、fd 解析)
  • 集成调用栈和符号解析
  • -i-x 互斥,不能同时使用
  • 至少需要指定一个目标(-f-p-u--uid

3.8 frida-pm(包管理)— 17.2+ 新增

无需 Node.js 的 Frida 包管理工具,用于搜索和安装 Frida 专属模块(如 frida-objc-bridge、frida-il2cpp-bridge 等)。

基本用法

# 搜索包
frida-pm search trace
frida-pm search il2cpp
 
# 搜索并输出 JSON
frida-pm search --json objc
 
# 安装包
frida-pm install frida-objc-bridge
frida-pm install frida-il2cpp-bridge@^2.0.0
 
# 安装为开发依赖
frida-pm install -D frida-compile
 
# 安装到指定目录
frida-pm install --project-root ./my-agent frida-objc-bridge
 
# 跳过开发依赖
frida-pm install --omit dev
 
# 使用自定义 registry
frida-pm --registry my-registry.example.com search trace

参数列表

全局选项:

参数说明
--registry HOST指定包注册表

search 子命令:

参数说明
query搜索关键词
--offset N结果偏移(分页)
--limit N最大结果数
--json输出原始 JSON

install 子命令:

参数说明
specs包规格(如 name@version
--project-root DIR项目根目录
-P, --save-prod保存为生产依赖(默认)
-D, --save-dev保存为开发依赖
--save-optional保存为可选依赖
--omit {dev,optional,peer}跳过指定类型依赖(可重复)
--quiet抑制进度条输出

特性:

  • 自动过滤 keywords:frida-gum,搜索结果零噪声
  • 无需 Node.js 即可安装包
  • 自动创建 package.json(如果不存在)

3.9 frida-ls / frida-pull / frida-push / frida-rm(文件操作)— 17.x 新增

一组远程文件操作工具,通过 Frida instrumentation 实现设备文件管理。

frida-ls(列出文件)

# 列出设备上目录内容
frida-ls -U /data/data/com.example.app/
 
# 列出文件详细信息
frida-ls -U /data/data/com.example.app/shared_prefs/

frida-pull(拉取文件)

# 从设备下载文件到当前目录
frida-pull -U /data/data/com.example.app/databases/app.db
 
# 下载到指定路径
frida-pull -U /data/data/com.example.app/databases/app.db ./local_copy.db
 
# 下载多个文件到目录
frida-pull -U /data/data/com.example.app/file1 /data/data/com.example.app/file2 ./output/

frida-push(推送文件)

# 推送文件到设备
frida-push -U ./payload.so /data/local/tmp/payload.so
 
# 推送多个文件
frida-push -U ./file1 ./file2 /data/local/tmp/

frida-rm(删除文件)

# 删除设备上的文件
frida-rm -U /data/local/tmp/payload.so
 
# 强制删除(忽略不存在)
frida-rm -U -f /data/local/tmp/old_file
 
# 递归删除目录
frida-rm -U -r /data/local/tmp/test_dir/
参数说明
-f, --force忽略不存在的文件
-r, --recursive递归删除目录及内容

3.10 常用组合技

场景: 快速了解应用行为

# 1. 列出设备
frida-ls-devices
 
# 2. 找到目标应用
frida-ps -Uai | grep example
 
# 3. 追踪文件操作
frida-trace -U -f com.example.app -i "open*" -i "read" -i "write" -i "close"
 
# 4. 追踪网络操作
frida-trace -U -f com.example.app -i "connect" -i "send*" -i "recv*"
 
# 5. 追踪 Java 关键方法
frida-trace -U -j "com.example.app.*!*" com.example.app

场景: SSL 流量分析

# 追踪 SSL 相关
frida-trace -U -f com.example.app \
  -I "libssl.so" \
  -i "SSL_read" -i "SSL_write"

场景: 追踪内存分配

frida-trace -U -f com.example.app -i "malloc" -i "free" -i "mmap*"

场景: 系统调用追踪(17.8+)

# 追踪应用的文件系统操作
frida-strace -f "com.example.app" -i openat -i read -i write -i close
 
# 追踪网络相关系统调用
frida-strace -p $(pidof com.example.app) -i socket -i connect -i sendto -i recvfrom
 
# 排除高频噪声调用
frida-strace -f "com.example.app" -x futex -x clock_gettime -x ioctl

场景: 安装 Frida 模块并使用(17.2+)

# 1. 搜索可用包
frida-pm search il2cpp
 
# 2. 安装到项目
frida-pm install frida-il2cpp-bridge
 
# 3. 在脚本中 import 使用
frida -U -f com.example.app -l agent.js

3.11 版本迁移注意事项(17.0+)

Frida 17.0 进行了重大 API 清理,以下旧 API 在 CLI REPL 中不再可用:

已移除的静态方法(REPL 内):

// ❌ 旧写法(17.0 前)
Memory.readU32(ptr("0x12345678"))
Module.findBaseAddress("libc.so")
Module.getExportByName(null, "open")
 
// ✅ 新写法(17.0+)
ptr("0x12345678").readU32()
Process.getModuleByName("libc.so").base
Process.getModuleByName("libc.so").getExportByName("open")

已移除的回调风格枚举:

// ❌ 旧写法
Process.enumerateModules({
    onMatch(module) { ... },
    onComplete() { ... }
})
 
// ✅ 新写法(返回数组)
const modules = Process.enumerateModules()
for (const m of modules) { ... }

运行时 bridge 变更:

  • Java, ObjC, Swift bridge 不再内置于 GumJS runtime
  • 通过 frida-tools 14.x 的 REPL 和 frida-trace 仍可直接使用(自动加载)
  • 自定义 agent 需通过 frida-pm install 安装后 import