Frida 是安卓逆向最强大的动态分析工具。它能在 App 运行时注入 JavaScript,实时拦截任意函数调用——就像给 App 装了窃听器。
一、Frida 是什么?
Frida 是一个动态插桩(Dynamic Instrumentation)框架,核心能力:
在运行时注入 JavaScript 代码到目标进程
拦截任意函数:可以查看参数、修改返回值、替换整个实现
支持 Java 层(ART)和 Native 层(C/C++/汇编)
跨平台:Android / iOS / Windows / Linux / macOS
核心原理: frida-server 在手机端运行(需 Root),监听 PC 端的连接请求。PC 端通过 USB/TCP 发送 JavaScript 脚本,frida-server 将脚本注入到目标进程中执行。
二、环境搭建
PC 端安装
# 安装 frida-tools(包含 frida CLI 和 frida-ps)pip install frida-tools# 安装 objection(基于 Frida 的自动化框架)pip install objection# 验证安装frida --version# 应输出版本号,如 16.x.x
手机端配置
# 第一步:查看手机 CPU 架构adb shell getprop ro.product.cpu.abi# 输出示例:arm64-v8a# 第二步:下载对应版本 frida-server# 地址:https://github.com/frida/frida/releases# 文件名格式:frida-server-16.x.x-android-arm64.xz# 第三步:解压并推送到手机unxz frida-server-16.x.x-android-arm64.xzadb push frida-server-16.x.x-android-arm64 /data/local/tmp/frida-server# 第四步:赋权并启动adb shell "chmod 755 /data/local/tmp/frida-server"adb shell "/data/local/tmp/frida-server &"# 第五步:验证连接frida-ps -U# 列出手机上所有进程
⚠️ 注意: frida PC 端版本必须与 frida-server 版本完全一致,否则连接失败。
三、三种注入模式对比
| 模式 | 命令 | 特点 | 适用场景 |
|---|
| attach(附加) | frida -U <进程名> | 附加到已运行进程 | App 已在前台运行 |
| spawn(启动) | frida -U -f <包名> | 启动 App 并立即注入 | 需要捕获初始化逻辑 |
| gadget(嵌入) | 修改 APK 内置 so | 无需 Root,嵌入到 APK | 无 Root 设备 |
# attach 模式frida -U com.target.app -l hook.js# spawn 模式(最常用)frida -U-f com.target.app -l hook.js# 交互模式(REPL)frida -U com.target.app
四、第一个 Hook 脚本
下面这个脚本会拦截所有 Activity 的 onCreate,打印启动记录:
// hook_activity.jsJava.perform(function() {// 获取 Activity 类varActivity=Java.use("android.app.Activity");// Hook onCreate 方法Activity.onCreate.overload("android.os.Bundle" ).implementation=function(bundle) {// 打印类名console.log("[Activity] "+this.getClass().getName());// 调用原始方法(不可省略!)this.onCreate(bundle); };console.log("[*] Activity Hook 已激活");});# 运行脚本frida -U-f com.target.app -l hook_activity.js# 输出示例:# [*] Activity Hook 已激活# [Activity] com.target.app.MainActivity# [Activity] com.target.app.LoginActivity
五、JavaScript API 速查
Java 层操作
Java.perform(function() {// 获取类varCls=Java.use("com.example.MyClass");// Hook 普通方法Cls.methodName.implementation=function(arg1) {console.log("arg:", arg1);returnthis.methodName(arg1); // 调用原始方法 };// Hook 重载方法(方法名相同,参数不同)Cls.methodName.overload("java.lang.String", "int") .implementation=function(s, i) {console.log(s, i);returnthis.methodName(s, i); };// 主动调用静态方法varresult=Cls.staticMethod("param");// 主动调用实例方法Java.choose("com.example.MyClass", {onMatch: function(instance) {instance.doSomething(); },onComplete: function() {} });});内存与 Native 操作
// 读取内存字符串Memory.readUtf8String(ptr("0x12345678"))// 写入内存Memory.writeByteArray(addr, [0x90, 0x90])// 打印内存 hexdumpconsole.log(hexdump(addr, { length: 64 }))
六、objection 快速上手
objection 是基于 Frida 的命令行工具,封装了大量常用操作,无需写脚本:
# 连接并注入objection -g com.target.app explore# 常用命令(进入 objection shell 后)android hooking list classes # 列出所有类android hooking list class_methods com.example.MyClass # 列出方法android hooking watch class_method com.example.MyClass.login # Hook 方法android sslpinning disable # 一键禁用 SSL Pinningandroid root disable # 绕过 Root 检测memory list modules # 列出加载的 so
七、常见报错与解决
| 报错 | 原因 | 解决方案 |
|---|
Failed to attach: unable to find process | 进程未运行或包名错误 | 先打开 App,用 frida-ps -U 确认进程名 |
Script exited with error: ... version mismatch | PC 端和手机端版本不一致 | 重新下载匹配版本的 frida-server |
Process terminated | App 检测到 Frida 退出 | 见第 09 篇反检测对策 |
ClassNotFoundError | 类名错误或未加载 | 用 objection list classes 确认完整类名 |
无法连接 27042 | frida-server 未运行 | adb shell /data/local/tmp/frida-server & |
下一篇:Frida Java 层 Hook 实战