Frida入门指南:简单易懂的动态代码插桩工具介绍与实战案例

1,570 阅读4分钟

Frida 是一款跨平台的动态代码插桩(Hook)工具,主要用于安全研究、逆向工程和调试。它可以在程序运行时,向目标进程注入自定义的JavaScript代码,实现对程序行为的监控和修改。下面用最简单的语言介绍Frida的核心知识点,并配合丰富的示例代码,帮助你快速理解和上手。

什么是Frida?

  • 动态插桩工具:Frida能在程序运行时“插入”自己的代码,观察和修改程序行为。
  • 跨平台支持:支持Android、iOS、Windows、Linux、macOS等多个操作系统。
  • 脚本语言:注入的代码用JavaScript写,控制端可以用Python或Node.js编写脚本。
  • 主要用途:安全测试(如绕过SSL Pinning)、逆向分析、调试程序、脱壳、网络协议分析等。

Frida解决了什么问题?

  • 实时调试和动态分析:不需要程序源码,直接在运行时观察函数调用、参数和返回值。
  • 函数Hook(拦截) :拦截程序中的函数,打印参数,修改返回值,甚至改变函数执行逻辑。
  • 绕过安全检测:如绕过应用的Root检测、SSL证书校验等安全机制。
  • 脱壳和内存分析:获取被加壳程序的真实代码,分析内存数据。
  • 防检测:也可用来检测程序是否被Frida注入,防止被攻击。

Frida的工作原理简述

  1. frida-server运行在目标设备上,负责接收客户端命令。
  2. 客户端(PC)通过USB或网络连接frida-server,发送JavaScript脚本。
  3. frida-gadget注入目标进程,在进程内部执行JavaScript脚本,实现Hook和修改。
  4. 脚本通过Frida API访问目标进程的函数和内存,实现动态控制。

环境搭建步骤

  1. 安装Python 3(推荐3.7及以上版本)。
  2. 安装Frida工具包:
pip install frida frida-tools
  1. 下载对应设备架构的frida-server,推送到Android设备并赋予权限:
adb push frida-server /data/local/tmp/
adb shell "chmod 777 /data/local/tmp/frida-server"
adb shell "/data/local/tmp/frida-server &"
  1. 设置端口转发,方便PC与设备通信:
adb forward tcp:27042 tcp:27042

基础命令示例

  • 查看设备上的进程列表
frida-ps -U
  • 附加到已运行的应用进程
frida -U -n com.example.app
  • 启动应用并注入脚本
frida -U -f com.example.app -l hook.js --no-pause

Java层函数Hook示例

假设目标应用中有一个MainActivity类,里面有一个targetFunction方法,我们想监控它的调用并修改返回值:

Java.perform(function () {
    var MainActivity = Java.use("com.example.app.MainActivity");
    MainActivity.targetFunction.implementation = function (arg) {
        console.log("targetFunction被调用,参数是:" + arg);
        var ret = this.targetFunction(arg);  // 调用原函数
        console.log("原始返回值:" + ret);
        return ret + 1;  // 修改返回值,返回原值+1
    };
});

保存为hook.js,然后用命令注入:

frida -U -n com.example.app -l hook.js

Native层函数Hook示例

假设有一个C函数nativeFunc,我们想打印调用参数并修改它:

setImmediate(function () {
    var addr = Module.findExportByName(null, "nativeFunc");
    Interceptor.attach(addr, {
        onEnter: function (args) {
            console.log("nativeFunc被调用,参数:" + args[0].toInt32());
            args[0] = ptr(1234);  // 修改第一个参数为1234
        },
        onLeave: function (retval) {
            console.log("nativeFunc返回值:" + retval.toInt32());
            retval.replace(5678);  // 修改返回值为5678
        }
    });
});

Python脚本调用Frida示例

你也可以用Python控制Frida,自动化注入脚本:

python
import frida

def on_message(message, data):
    if message['type'] == 'send':
        print("[*] " + message['payload'])
    else:
        print(message)

device = frida.get_usb_device()
session = device.attach("com.example.app")

with open("hook.js") as f:
    script = session.create_script(f.read())

script.on('message', on_message)
script.load()
input("Press Enter to exit...\n")

进阶应用案例

  • 绕过SSL Pinning:Hook系统的SSL验证函数,强制返回成功,方便抓包分析。
  • 脱壳:Hook加载壳的函数,dump内存中的dex或so文件,获取真实代码。
  • 自动化测试:结合Python脚本批量执行Hook脚本,实现自动化安全测试。

常用Frida命令参数说明

参数说明
-U连接USB设备
-n 附加到指定包名的进程
-f 启动指定包名的应用并注入
-l 加载指定的JavaScript脚本
--no-pause启动后不暂停,直接运行主线程
-p 附加到指定进程ID

小结

Frida是一款非常强大的动态代码插桩工具,能帮助我们在程序运行时实时观察和修改程序行为。它支持多平台、多语言,适合安全研究、逆向工程和调试。通过简单的JavaScript脚本,我们可以轻松Hook函数、修改参数和返回值,绕过安全检测,甚至脱壳。结合Python脚本还能实现自动化控制,极大提升工作效率。

欢迎大家动手试试上面的示例,逐步深入学习Frida的强大功能!