How to hook Android Native methods with Frida (Noob Friendly)
字数 1035 2025-08-22 12:22:24

Frida Hook Android Native方法详细教程

1. 准备工作

1.1 测试环境搭建

推荐使用Genymotion模拟器,因为它:

  • 轻量且性能良好
  • 默认具有root权限
  • 可集成到Android Studio中

1.2 Frida安装

在电脑上安装Frida需要执行以下命令:

pip install frida-tools  # 安装基础工具
pip install frida        # 安装Python绑定

1.3 Frida-server部署

  1. Frida发布页下载对应设备架构的frida-server
  2. 解压并重命名为简单名称如frida-server
  3. 推送到设备:
adb push path/to/frida-server /tmp
  1. 在设备上运行:
adb shell
cd /tmp
chmod +x frida-server
./frida-server

验证是否成功:

frida-ps -U  # 应显示进程列表

2. 目标应用分析

2.1 提取APK内容

APK本质是zip文件,解压后可查看内容结构:

lib/
  arm64-v8a/
    libnative-lib.so
  armeabi-v7a/
    libnative-lib.so
  x86/
    libnative-lib.so
  x86_64/
    libnative-lib.so

2.2 分析共享库

使用nm工具分析.so文件:

nm --demangle --dynamic libnative-lib.so

输出示例:

00002000 A __bss_start
U __cxa_atexit
U __cxa_finalize
00002000 A _edata
00002000 A _end
00000630 T Java_com_erev0s_jniapp_MainActivity_Jniint
000005d0 T Jniint
U rand
U srand
U __stack_chk_fail
U time

关键点:

  • Java_com_erev0s_jniapp_MainActivity_Jniint: JNI函数
  • Jniint: 原生C函数

3. Hook方法一:Java层Hook

3.1 JavaScript代码

Java.perform(function() {
    // 创建MainActivity的JavaScript包装
    var Activity = Java.use('com.erev0s.jniapp.MainActivity');
    
    // 替换Jniint实现
    Activity.Jniint.implementation = function() {
        console.log("Inside Jniint now...");
        return 80085; // 自定义返回值
    };
});

3.2 执行Hook

保存为myhook.js后运行:

frida -U -l myhook.js com.erev0s.jniapp

或自动启动应用:

frida -U -l hookNative.js -f com.erev0s.jniapp --no-pause

4. Hook方法二:Native层Hook

4.1 JavaScript代码

Interceptor.attach(Module.getExportByName('libnative-lib.so', 'Jniint'), {
    onEnter: function(args) {
        // 函数进入时的操作
    },
    onLeave: function(retval) {
        // 替换返回值为0
        retval.replace(0);
    }
});

4.2 注意事项

  • 首次运行可能报错,因为函数尚未加载
  • 触发目标函数后重新加载脚本即可

5. 两种方法对比

方法 优点 缺点 适用场景
Java层Hook 实现简单 无法访问原生函数内部 只需修改返回值时
Native层Hook 可访问函数内部 需要函数已加载 需要分析函数参数/逻辑时

6. 常见问题解决

  1. frida-ps -U无输出

    • 检查frida-server是否运行
    • 检查设备连接
  2. 找不到导出函数

    • 确保目标函数已被调用/加载
    • 检查.so文件名和函数名拼写
  3. 权限问题

    • 确保设备有root权限
    • 或使用非root方法如frida-gadget

7. 进阶技巧

  1. 动态加载库

    var lib = Module.load('/path/to/lib.so');
    
  2. 查找导出函数

    var exports = Module.enumerateExportsSync('libnative-lib.so');
    
  3. 修改函数参数

    onEnter: function(args) {
        args[0] = ptr(1234); // 修改第一个参数
    }
    
  4. 调用原函数

    var orig_func = Module.getExportByName('libnative-lib.so', 'Jniint');
    var result = orig_func(arg1, arg2);
    

8. 参考资源

  1. Frida官方文档
  2. Frida JavaScript API参考
  3. JNI编程指南

通过本教程,您应该已经掌握了使用Frida在Java层和Native层hook Android应用的基本方法。根据实际需求选择合适的方法,并逐步深入探索Frida的强大功能。

Frida Hook Android Native方法详细教程 1. 准备工作 1.1 测试环境搭建 推荐使用Genymotion模拟器,因为它: 轻量且性能良好 默认具有root权限 可集成到Android Studio中 1.2 Frida安装 在电脑上安装Frida需要执行以下命令: 1.3 Frida-server部署 从 Frida发布页 下载对应设备架构的frida-server 解压并重命名为简单名称如 frida-server 推送到设备: 在设备上运行: 验证是否成功: 2. 目标应用分析 2.1 提取APK内容 APK本质是zip文件,解压后可查看内容结构: 2.2 分析共享库 使用 nm 工具分析.so文件: 输出示例: 关键点: Java_com_erev0s_jniapp_MainActivity_Jniint : JNI函数 Jniint : 原生C函数 3. Hook方法一:Java层Hook 3.1 JavaScript代码 3.2 执行Hook 保存为 myhook.js 后运行: 或自动启动应用: 4. Hook方法二:Native层Hook 4.1 JavaScript代码 4.2 注意事项 首次运行可能报错,因为函数尚未加载 触发目标函数后重新加载脚本即可 5. 两种方法对比 | 方法 | 优点 | 缺点 | 适用场景 | |------|------|------|----------| | Java层Hook | 实现简单 | 无法访问原生函数内部 | 只需修改返回值时 | | Native层Hook | 可访问函数内部 | 需要函数已加载 | 需要分析函数参数/逻辑时 | 6. 常见问题解决 frida-ps -U无输出 : 检查frida-server是否运行 检查设备连接 找不到导出函数 : 确保目标函数已被调用/加载 检查.so文件名和函数名拼写 权限问题 : 确保设备有root权限 或使用非root方法如frida-gadget 7. 进阶技巧 动态加载库 : 查找导出函数 : 修改函数参数 : 调用原函数 : 8. 参考资源 Frida官方文档 Frida JavaScript API参考 JNI编程指南 通过本教程,您应该已经掌握了使用Frida在Java层和Native层hook Android应用的基本方法。根据实际需求选择合适的方法,并逐步深入探索Frida的强大功能。