Frida 的原理和使用

481 阅读3分钟

🧠 Frida 是什么?一句话版本

Frida 是一款功能强大的 动态插桩工具,它可以让你在一个运行中的应用里插入自定义的 JavaScript 代码,来监控、修改、甚至劫持应用的行为。


🧙 用故事讲 Frida:神偷的魔法眼镜

想象一下:

你是一个神偷,想要潜入一座巨大的魔法城堡(比如一个 App),这座城堡有人守卫、有机关(加密函数、接口调用),而你要:

  • 偷听守卫说话(监控函数参数/返回值)
  • 偷换信件(修改函数参数/返回值)
  • 甚至改变机关逻辑(hook 核心函数)

但你不能砸门、不能暴露自己,于是你戴上了一个神奇的 Frida 魔法眼镜。戴上这副眼镜后:

  • 你可以看到代码在运行
  • 你可以插入自己的逻辑
  • 你还可以动态修改应用行为

Frida 就是这个不会破坏程序结构、还能实时插桩的魔法工具。


🔧 Frida 原理(通俗解释)

👀 1. 注入器(Injector)

Frida 首先会使用一种方式把它的“魔法核心”注入目标进程中:

  • 在 Android 上是通过 ptracefrida-server 以 root 身份注入
  • 在 iOS/macOS/Windows 上是通过 动态库注入(Dylib / DLL Injection)

🧠 2. frida-agent(内存驻留脚本)

注入后,Frida 会把你写的 JavaScript(Hook 脚本)传进目标进程里,让它和目标代码“肩并肩”一起跑。

你写的脚本会通过 Frida 提供的 API(比如 Java.perform, Interceptor.attach)来 hook 或替换原本的逻辑。

🔄 3. 通信桥(Frida Core)

Frida 运行时在后台建立一个 IPC 通道(一般是 Frida 客户端 ↔ Agent),用于通信、数据交换、控制。


🧪 使用 Frida 的常见场景

目标示例
Hook Java 函数破解登录验证、查看密钥
Hook Native 函数(C/C++)劫持 libc, OpenSSL
拿到内存中敏感信息抓取运行时的 token、密码
劫持动态加载的 so反反调试、绕过安全保护

💻 实战:一步步用 Frida Hook Java 方法

假设你有一个 Android 应用,其中有这样一个方法:

java
复制编辑
public class AuthUtil {
    public static boolean checkPassword(String input) {
        return "s3cret".equals(input);
    }
}

你想要:

  • Hook 这个函数
  • 查看输入的 password
  • 修改返回值(比如总是返回 true)

🧰 准备环境(以 Android 为例):

bash
复制编辑
adb push frida-server /data/local/tmp/
adb shell "chmod 755 /data/local/tmp/frida-server && /data/local/tmp/frida-server &"

在主机运行:

bash
复制编辑
frida-ps -U          # 查看进程列表
frida -U -n com.target.app -l script.js

📜 编写 Hook 脚本(script.js):

javascript
复制编辑
Java.perform(function () {
    var AuthUtil = Java.use("com.target.app.AuthUtil");

    AuthUtil.checkPassword.implementation = function (input) {
        console.log("[*] 输入密码是:" + input);
        var result = this.checkPassword(input);  // 调原函数
        console.log("[*] 原返回:" + result);
        return true;  // 强制登录成功
    };
});

📌 说明:

  • Java.use():找到类
  • .implementation = function() {}:替换方法实现
  • this.checkPassword(input):调用原始实现
  • return true:我们改写了返回值

🔬 Hook Native 函数示例(C 层)

Hook libc 中的 open 函数(用来监控文件访问):

javascript
复制编辑
Interceptor.attach(Module.getExportByName("libc.so", "open"), {
    onEnter: function (args) {
        var path = Memory.readUtf8String(args[0]);
        console.log("open called with path: " + path);
    },
    onLeave: function (retval) {
        console.log("open 返回值: " + retval);
    }
});

🧩 Frida API 核心概念简表

API作用
Java.perform()Java 层 hook 的入口
Java.use(className)加载某个 Java 类
Interceptor.attach(addr, {...})Hook native 函数
Module.getExportByName("lib.so", "func")查找导出的函数地址
Memory.readUtf8String(ptr)读取内存中的字符串

⚠️ 使用注意事项

  • Android 7+ 要 root,或使用 Frida Gadget 植入 APK
  • Frida 会被一些安全方案检测到(可使用 cloaking 技术绕过)
  • 调试时注意目标应用是 Debuggable 或关闭了一些检测手段

📚 延伸学习建议

  1. 推荐教程

  2. 推荐实战项目

    • Hook 抓包:抓取 App 中的 token
    • Hook 解密:找解密函数并导出明文
    • Hook 反调试:绕过 App 的防护检测

✅ 总结一句话

Frida 就是一副魔法眼镜,让你看穿并控制运行中的应用程序行为,不改 APK,不重启设备,想 hook 哪里 hook 哪里。


需要我继续写一个具体的 Frida 脚本实战教程或自动化场景(如批量 Hook、导出函数表等)吗?