如何用Frida追踪Android应用的Java/Kotlin函数调用栈?
解决Android Java/Kotlin应用Frida函数追踪与调用栈打印问题
一、修复frida-trace无法追踪Java函数的问题
frida-trace默认追踪Native层函数,直接使用checkRequest*会在Native层查找,自然无法匹配Java/Kotlin代码中的目标函数。同时*send*返回大量非Java函数,也是因为未限定Java运行时范围。
正确的frida-trace命令需指定Java运行时,并明确目标函数的类范围:
frida-trace -U -f com.your.app.package --runtime=java -j "com.your.app.package.*.checkRequest*"
- 替换
com.your.app.package为你的应用实际包名,缩小搜索范围才能精准匹配目标函数 --runtime=java强制Frida在Java层查找函数,避免混入Native层结果
二、自定义Frida脚本打印可读调用栈
ChatGPT生成的脚本往往未精准限定类范围或处理函数重载,以下是可直接使用的稳定脚本:
Java.perform(function() { // 枚举所有包含目标包名且方法含checkRequest的类 var targetClasses = Java.enumerateClassesSync(function(className) { return className.startsWith("com.your.app.package") && className.match(/checkRequest/); }); targetClasses.forEach(function(cls) { var clazz = Java.use(cls); // 遍历类中所有方法,匹配checkRequest开头的函数 Object.getOwnPropertyNames(clazz.$classMethods).forEach(function(methodName) { if (methodName.startsWith("checkRequest")) { // 处理所有重载方法 clazz[methodName].overloads.forEach(function(overload) { overload.implementation = function() { // 打印调用信息 console.log(`[+] 调用: ${cls}.${methodName}`); console.log("调用栈:"); // 利用Android系统API生成可读栈信息 console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new())); // 执行原方法并返回结果 return this[methodName].apply(this, arguments); }; }); } }); }); });
使用方式:
- 将脚本保存为
trace-stack.js - 执行命令:
frida -U -f com.your.app.package -l trace-stack.js --no-pause
三、关键注意事项
- 必须确认应用包名正确,否则Frida无法attach到目标进程
- Kotlin编译后会生成带
$后缀的类名(如内部类、lambda相关类),枚举类时需注意匹配这类名称 - 若目标函数为私有/protected,Frida仍可hook,但需先通过
frida -U -f com.your.app.package --no-pause -e "Java.enumerateClassesSync()"枚举所有类,确认目标类的完整名称 - 调用栈使用
android.util.Log.getStackTraceString生成,可保留类名、方法名及行号(若应用保留调试信息)
内容的提问来源于stack exchange,提问作者Муса
相关产品推荐
相关产品推荐

