~/blog▌
login

Frida 入门:Hook 函数的三个层次与调试技巧

2 min read yourname
目录(5 节)

Frida 的 Hook 能力分三个层次:Java 层方法拦截 → Native 函数拦截 → 内存级读写。从上往下难度递增、能力递增。本文按层次给出可运行的最小脚本与排错思路,帮你把"注入成功"到"拿到数据"的距离缩到最短。

环境怎么搭?

# PC 端(以 Python 环境为例)
pip install frida-tools
frida --version

# Android 设备端:下载对应架构的 frida-server 推送并运行
adb push frida-server-android-arm64 /data/local/tmp/fs
adb shell "chmod +x /data/local/tmp/fs && /data/local/tmp/fs &"

# 验证连接
frida-ps -U

测试目标建议使用 OWASP UnCrackable 或自写的 demo app——不要拿线上商业产品练手。

层次一:Java 层 Hook

目标在 jadx 里能看到的方法,用 Java.perform 拦截:

// hook_java.js — 拦截某类的静态方法并打印参数与返回值
Java.perform(() => {
  const Cls = Java.use('com.demo.app.CryptoUtil');
  Cls.sign.overload('java.lang.String').implementation = function (input) {
    const ret = this.sign(input);
    console.log('[sign] in :', input);
    console.log('[sign] out:', ret);
    return ret;
  };
});
frida -U -l hook_java.js -f com.demo.app   # spawn 模式,覆盖 attach 抓不到早期调用的场景

常见坑:方法重载时必须用 overload() 指定签名;类名被混淆就用脚本枚举当前内存里的类。

层次二:Native 层 Hook

目标在 so 库里,先用偏移量定位,再 Interceptor.attach:

// hook_native.js — 拦截 so 中的未导出函数(偏移 0x1A2B3C)
const base = Module.getBaseAddress('libnative.so');
Interceptor.attach(base.add(0x1A2B3C), {
  onEnter(args) {
    // 按函数约定读参数:指针按字节读,整型按位读
    console.log('[n] arg0 ptr:', args[0].readCString());
  },
  onLeave(ret) {
    console.log('[n] ret:', ret.toInt32());
  }
});

定位偏移的方法:IDA 打开 so → 找到目标函数 → 记录函数起始地址减去模块基址。导出函数可以直接 Module.getExportByName(null, 'symbol')。

层次三:内存级操作

前两层都不奏效时(函数被内联、逻辑写在宏里),退到内存层:Memory.scan 搜特征字节、Memory.readByteArray 直接读数据区、Memory.protect 改页属性。这是"最后手段",脚本可移植性差,每次版本更新都要重新定位。

调试心法

三个技巧贯穿三层次:

  1. 差分观察:同一操作重复两次,对比 dump 结果,找"变的"和"不变的"字段;
  2. 从调用栈反推:console.log(Java.use('android.util.Log').getStackTraceString(Java.use('java.lang.Exception').$new())) 打印 Java 调用栈,定位是谁在调目标函数;
  3. 最小化注入:一次只 Hook 一个函数,确认生效再加下一个——批量 Hook 出错时几乎无法定位。

Frida 在完整分析流程中的位置,见 逆向方法论五步;拿到关键数据后如何还原算法,将在会员篇 签名算法分析实战 中以自建靶场为例完整演示。

常见问题

Frida 是什么?

一个跨平台动态插桩框架,能把 JavaScript 脚本注入到运行中的进程里,拦截并修改函数行为,常用于逆向分析、安全研究与自动化测试,支持 Android/iOS/Windows/macOS/Linux。

Frida 环境 how to 搭建?

PC 端 pip install frida-tools,Android 设备端运行对应架构的 frida-server 并转发端口,PC 用 frida -U -l script.js -f 包名 附着目标进程。

Java 层 Hook 和 Native 层 Hook 怎么选?

目标在 Java/Kotlin 代码里(jadx 能看到)用 Java.perform;目标在 so 库里(IDA 里看到)用 Interceptor.attach。先用 Java 层试,拿不到再下沉到 Native。

Hook 不到目标函数的常见原因?

类被混淆导致名字对不上(用枚举脚本列出实际类名)、函数被内联优化(换更大粒度的调用点)、时机太早(用 spawn 模式替代 attach)。

Frida 有什么合规边界?

只对自己拥有或获授权的设备与应用进行分析;不得用于破解、外挂或绕过他人系统的访问控制。