一、Frida 简单介绍
本质上是一个动态插桩框架,核心能力是在不修改 APK 的前提下,向运行中的 Android 进程注入 JavaScript 脚本,从而拦截、观察、修改 Java 方法或 Native 函数。
原理:
- frida-server 通过 ptrace 等方式附加到目标进程。
- 在目标进程中分配可执行内存,注入 Frida Agent。
- Agent 在进程内启动 JavaScript 引擎,并与电脑端建立通信通道。
- 你写的 JS 脚本被下发到目标进程执行,通过 Interceptor、Java.use 等 API 劫持函数。
- Java 层 Hook 主要靠 Frida 的 Java Bridge 与 ART/Dalvik 交互;Native 层 Hook 则直接操作 so 库中的函数地址。
二、下载安装
Frida 是 C/S 架构:电脑端是客户端,需要在 Android 设备上运行 frida-server。frida-server 可以通过下面的链接下载:
https://github.com/frida/frida
- 推送 frida-server 到安卓设备中
adb-s127.0.0.1:16384 root adb-s127.0.0.1:16384 push frida-server-17.23.3-android-arm64 /data/local/tmp/frida-server- 给 frida-server 授权执行权限
adb-s127.0.0.1:16384 shell"chmod 755 /data/local/tmp/frida-server"- 打印版本号测试
adb-s127.0.0.1:16384 shell"/data/local/tmp/frida-server --version"- 后台拉起 frida server
adb-s127.0.0.1:16384 shell"nohup /data/local/tmp/frida-server >/dev/null 2>&1 &"- 查看运行情况
adb-s127.0.0.1:16384 shell"ps -A | grep frida"- 下载 frida 连接客户端
注:要与服务器版本一致
pipinstall-Ufrida==17.23.3 frida-tools三、使用
模式
hook 启动阶段逻辑
frida-U-fcom.example.app-lhook.js --no-pauseApp 已经在运行了,Frida 通过 ptrace 附加到现有进程上注入。
frida-U-ncom.example.app-lhook.jsFrida API
| API | 作用 | 常用场景 |
|---|---|---|
Java.perform(fn) | 在 Java 运行时执行回调 | Java Hook 入口 |
Java.use(className) | 获取 Java 类的 JS 包装对象 | 定位目标类 |
Java.cast(obj, cls) | 把对象强转为指定类型 | 接口/父类转具体实现 |
Java.choose(className, cb) | 枚举堆上已有实例 | 找存活对象、调用实例方法 |
Java.enumerateLoadedClasses(cb) | 枚举已加载类 | 找隐藏类、动态加载类 |
Java.enumerateClassLoaders(cb) | 枚举类加载器 | 多 Dex、壳、插件场景 |
Java.array(type, values) | 创建 Java 数组 | 给 Java 方法传数组参数 |
Frida 绕 Root
场景:APP 通过判断su命令执行情况,来判断设备是否 root
那么,我们可以通过下面的代码定位 String 方法重载,然后使用 implementation 替换其实现:
var Runtime=Java.use("java.lang.Runtime");Runtime.exec.overload("java.lang.String").implementation=function(cmd){if(cmd==="su")throw Java.use("java.io.IOException").$new("not found");returnthis.exec(cmd);};