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部署
- 从Frida发布页下载对应设备架构的frida-server
- 解压并重命名为简单名称如
frida-server - 推送到设备:
adb push path/to/frida-server /tmp
- 在设备上运行:
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. 常见问题解决
-
frida-ps -U无输出:
- 检查frida-server是否运行
- 检查设备连接
-
找不到导出函数:
- 确保目标函数已被调用/加载
- 检查.so文件名和函数名拼写
-
权限问题:
- 确保设备有root权限
- 或使用非root方法如frida-gadget
7. 进阶技巧
-
动态加载库:
var lib = Module.load('/path/to/lib.so'); -
查找导出函数:
var exports = Module.enumerateExportsSync('libnative-lib.so'); -
修改函数参数:
onEnter: function(args) { args[0] = ptr(1234); // 修改第一个参数 } -
调用原函数:
var orig_func = Module.getExportByName('libnative-lib.so', 'Jniint'); var result = orig_func(arg1, arg2);
8. 参考资源
通过本教程,您应该已经掌握了使用Frida在Java层和Native层hook Android应用的基本方法。根据实际需求选择合适的方法,并逐步深入探索Frida的强大功能。