【Frida Android】基础篇15(完):Frida-Trace 基础应用——JNI 函数 Hook
文章目录
- 一、什么是JNI函数Hook?
- 二、示例1:Hook 应用中的`check_1flag`函数
- 2.1 目标
- 2.1.1 步骤1:获取目标进程的PID
- 2.1.2 步骤2:用Frida-Trace追踪JNI函数
- 2.1.3 步骤3:查看生成的追踪脚本
- 2.1.4 步骤4:触发函数调用并观察日志
- 2.1.5 步骤5:修改脚本自定义返回值
 
 
- 三、示例2:Hook 应用中的`stringFromJNI`函数
- 3.1 目标
- 3.1.1 步骤1:获取目标进程的PID
- 3.1.2 步骤2:用Frida-Trace追踪函数
- 3.1.3 步骤3:查看导出的JNI函数
 
 
- 四、技术总结
- 五、后续计划
 
⚠️本博文所涉安全渗透测试技术、方法及案例,仅用于网络安全技术研究与合规性交流,旨在提升读者的安全防护意识与技术能力。任何个人或组织在使用相关内容前,必须获得目标网络 / 系统所有者的明确且书面授权,严禁用于未经授权的网络探测、漏洞利用、数据获取等非法行为。
一、什么是JNI函数Hook?
在Android开发中,Java代码有时会调用原生代码(C/C++编写),这些调用通过JNI(Java Native Interface) 实现。JNI函数有固定的命名规范:Java_包名_类名_方法名(比如Java_com_ad2001_a0x9_MainActivity_check_1flag)。
Frida-Trace是Frida工具集中的一个实用工具,它可以快速追踪应用中符合JNI命名规范的函数,帮助我们观察函数调用、修改返回值等,非常适合新手入门Hook技术。
本章示例应用的链接:
https://pan.baidu.com/s/16EE2XE-OZS_xBRPlWUODbw?pwd=n2vb
提取码: n2vb
使用APK1:Challenge 0x9.apk
使用APK2:Challenge 0xA.apk
二、示例1:Hook 应用中的check_1flag函数
 
2.1 目标
追踪并修改com.ad2001.a0x9应用中名为check_1flag的JNI函数,实现自定义返回值。
大家可以对比【Frida Android】基础篇11:Native层hook基础——修改原生函数的返回值 中纯 Frida Hook 的手法,更加容易理解 Frida-Trace 的作用。
2.1.1 步骤1:获取目标进程的PID
首先需要找到应用的进程ID(PID),用adb命令查看:
# 查看包含"com.ad2001.a0x9"的进程(Windows用findstr,Linux/macOS用grep)
adb shell ps | findstr com.ad2001.a0x9
# 输出示例:u0_a44        6471  1126 12673696 178896 0                  0 S com.ad2001.a0x9
# 这里的6471就是目标进程的PID
2.1.2 步骤2:用Frida-Trace追踪JNI函数
执行以下命令,让Frida-Trace连接设备并追踪目标函数:
# -U:表示连接USB设备
# -p 6471:附加到PID为6471的进程(替换为你的实际PID)
# -i "Java_com_ad2001_a0x9_*":匹配所有以"Java_com_ad2001_a0x9_"开头的JNI函数
frida-trace -U -p 6471 -i "Java_com_ad2001_a0x9_*"
执行后,Frida-Trace会自动生成追踪脚本,并在命令行显示追踪状态(如下图):

2.1.3 步骤3:查看生成的追踪脚本
Frida-Trace会在本地生成一个__handlers__目录,里面的脚本对应被追踪的函数。从下图可以看到,目标应用导出了check_1flag这个JNI函数:

2.1.4 步骤4:触发函数调用并观察日志
打开应用并点击按钮(触发check_1flag函数调用):

此时命令行会打印函数调用信息(来自自动生成脚本的onEnter函数):

2.1.5 步骤5:修改脚本自定义返回值
自动生成的脚本是基础模板,我们可以修改它来改变函数行为。比如,将check_1flag的返回值改为1337:
/** 自动生成的脚本,需根据函数签名修改* 文档参考:https://frida.re/docs/javascript-api/*/defineHandler({// 函数被调用时执行(进入函数)onEnter(log, args, state) {log('Java_com_ad2001_a0x9_MainActivity_check_1flag()');},// 函数执行结束时执行(离开函数)onLeave(log, retval, state) {// 修改返回值为1337retval.replace(1337);log('Java_com_ad2001_a0x9_MainActivity_check_1flag() -> ' + retval);}
});
保存脚本后再次触发函数调用,应用会使用我们修改后的返回值,成功获取Flag:

终端打印内容如下:0x539 是数字 1337 的十六进制表示。

三、示例2:Hook 应用中的stringFromJNI函数
 
3.1 目标
追踪com.ad2001.frida0xa应用中名为stringFromJNI的JNI函数,了解其调用情况。
3.1.1 步骤1:获取目标进程的PID
同样先通过adb找到进程PID:
# 查看包含"com.ad2001.frida0xa"的进程
adb shell ps | findstr com.ad2001.frida0xa
# 输出示例:u0_a45        6037  1126 12653200 173300 0                  0 S com.ad2001.frida0xa
# 这里的6037是PID
3.1.2 步骤2:用Frida-Trace追踪函数
执行命令追踪以Java_com_ad2001_frida0xa_开头的JNI函数:
frida-trace -U -p 6037 -i "Java_com_ad2001_frida0xa_*"
命令行会显示追踪状态,提示已开始监控目标函数:

3.1.3 步骤3:查看导出的JNI函数
从本地生成的脚本目录可以看到,该应用调用了stringFromJNI函数:

四、技术总结
通过上面的示例,我们可以总结Frida-Trace在JNI函数Hook中的核心用法:
-  核心作用:快速定位并追踪应用中的JNI函数(基于命名规范匹配),无需手动分析so文件。 
-  基本流程: - 用adb shell ps | findstr 包名获取目标进程PID;
- 用frida-trace -U -p PID -i "JNI函数匹配规则"启动追踪;
- 查看自动生成的脚本,了解函数结构;
- 修改脚本(如onEnter打印日志、onLeave修改返回值),实现自定义逻辑。
 
- 用
-  适合场景: - 快速验证JNI函数的调用时机;
- 临时修改函数返回值(如绕过验证、获取Flag);
- 分析应用中调用的原生函数列表。
 
-  新手提示: - 函数匹配规则"Java_包名_类名_*"中的*是通配符,可匹配任意字符;
- 脚本中的onEnter和onLeave分别对应函数调用的开始和结束;
- 修改返回值时,需注意返回值的类型(如示例1中的整数1337),需与原函数一致。
 
- 函数匹配规则
五、后续计划
感谢大家看到这里,后续我会更新实战篇系列,依然采用案例讲解的形式,提供实战 APK + Hook 源码,感兴趣的师傅可以关注下~🙏
