【Frida Android】实战篇:Frida-Trace 进阶追踪——JNI 函数参数捕获与修改
1. 为什么需要捕获JNI函数参数在Android安全分析和逆向工程中JNI函数往往是关键突破口。很多应用会把核心逻辑放在native层实现比如加密算法、授权验证、敏感数据处理等。单纯Hook Java层方法可能无法触及这些关键逻辑这时候就需要深入JNI层。传统做法是直接修改so文件或者用IDA分析汇编代码但这种方法门槛高、效率低。Frida-Trace提供了一种更优雅的解决方案——动态捕获JNI函数参数。我曾在分析某金融类APP时发现其关键校验逻辑全部放在native层通过参数捕获技术成功定位到了核心校验函数。2. 环境准备与目标设定2.1 实验环境搭建首先确保你的环境已经具备已root的Android设备或模拟器推荐Genymotion安装好Frida和frida-tools最新版为16.1.3目标APK我们使用一个自制的测试APK包含以下JNI函数JNIEXPORT jboolean JNICALL Java_com_example_demo_MainActivity_verifyPassword( JNIEnv *env, jobject thiz, jstring input) { // 密码验证逻辑 }2.2 目标函数分析我们的目标是Hook这个verifyPassword函数实现捕获输入的原始密码参数修改输入参数值观察修改后的验证结果3. 基础参数捕获实战3.1 启动Frida-Trace首先获取目标进程PIDadb shell ps -A | grep com.example.demo # 输出示例u0_a101 31415 551 4505600 82000 0 0 S com.example.demo启动frida-trace追踪JNI函数frida-trace -U -p 31415 -i Java_com_example_demo_*3.2 解析生成的Hook脚本在__handlers__目录下会生成对应的JavaScript文件// Java_com_example_demo_MainActivity_verifyPassword.js onEnter: function(log, args, state) { log(verifyPassword()); log(args[0]: args[0]); // JNIEnv* log(args[1]: args[1]); // jobject thiz log(args[2]: args[2]); // jstring input }3.3 参数类型转换技巧jstring需要特殊处理才能读取内容onEnter: function(log, args, state) { const jniEnv args[0]; const inputStr Java.vm.getEnv().getStringUtfChars(args[2], null).readCString(); log(Input password: inputStr); state.originalInput inputStr; // 保存原始值 }4. 进阶参数修改技术4.1 动态修改字符串参数要修改jstring参数需要创建新的字符串对象onEnter: function(log, args, state) { const env Java.vm.getEnv(); const newStr env.newStringUtf(hacked_password); args[2] newStr; // 替换原始参数 log(Modified input to: hacked_password); }4.2 处理基本数据类型参数对于int/long等基本类型参数// 假设函数签名为verify(int input) onEnter: function(log, args, state) { log(Original value: args[2]); // 直接读取 args[2] ptr(12345); // 修改为指定值 }4.3 数组参数处理实战当参数是jarray时的处理方法onEnter: function(log, args, state) { const env Java.vm.getEnv(); const array args[2]; const length env.getArrayLength(array); // 读取byte数组内容 const elements env.getByteArrayElements(array, null); const buffer elements.readByteArray(length); // 修改数组内容 const newBuffer Memory.alloc(length); newBuffer.writeByteArray([0x01, 0x02, 0x03]); env.setByteArrayRegion(array, 0, length, newBuffer); }5. 实战案例绕过密码验证5.1 目标函数分析假设目标函数逻辑如下jboolean verifyPassword(JNIEnv* env, jobject obj, jstring input) { const char* correct secret123; const char* userInput env-GetStringUTFChars(input, 0); int result strcmp(correct, userInput); env-ReleaseStringUTFChars(input, userInput); return result 0; }5.2 完整Hook脚本实现onEnter: function(log, args, state) { const env Java.vm.getEnv(); // 1. 捕获原始输入 const original env.getStringUtfChars(args[2], null).readCString(); log(Original input: original); // 2. 修改为正确密码 const newStr env.newStringUtf(secret123); args[2] newStr; // 3. 保存原始引用以便恢复 state.originalArg args[2]; }, onLeave: function(log, retval, state) { // 恢复原始参数可选 args[2] state.originalArg; // 也可以直接修改返回值 retval.replace(1); // 强制返回true }5.3 常见问题排查JNI环境获取失败// 确保先初始化JNI环境 if (!Java.vm.tryGetEnv()) { Java.vm.attachCurrentThread(); }内存泄漏问题// 记得释放分配的字符串 const chars env.getStringUtfChars(str, null); // ...使用chars... env.releaseStringUTFChars(str, chars);类型转换错误// 检查类型是否正确 if (env.isInstanceOf(obj, env.findClass(java/lang/String))) { // 安全转换 }6. 性能优化与高级技巧6.1 批量Hook多个JNI函数使用通配符批量捕获frida-trace -U -n com.example.demo -i Java_*_verify*6.2 条件断点技术只在特定条件下触发HookonEnter: function(log, args, state) { const input Java.vm.getEnv().getStringUtfChars(args[2], null).readCString(); if (input.length 8) { // 只处理长度大于8的输入 log(Processing long password: input); // 修改逻辑... } }6.3 持久化Hook配置将常用Hook保存为脚本// jni_hooks.js rpc.exports { hookVerify: function() { Interceptor.attach(Module.findExportByName(null, Java_com_example_demo_verify), { onEnter: function(args) { // Hook逻辑... } }); } };7. 安全防护与对抗思路7.1 常见防护手段应用可能采用以下防护措施JNI函数名混淆参数校验检查指针有效性调用栈检测7.2 对抗方案实例针对调用栈检测的绕过onEnter: function(log, args, state) { // 伪造调用栈 const thread this.context; thread.pc ptr(0x12345678); // 修改程序计数器 thread.sp ptr(0x87654321); // 修改栈指针 }实际项目中我曾遇到一个加固应用它的native层会检查调用来源。通过分析发现它只是简单检查返回地址是否在特定内存范围于是用类似上面的方法成功绕过了检测。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2453656.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!