Linux下Frida Hook含多维数组的JNI函数报错,如何解决?
问题现象
在Linux x86_64环境下使用Frida构建JNI库模糊测试器,Hook接收int[][]类型参数的Native方法时,抛出如下错误:
Exception in thread "main" java.lang.NoClassDefFoundError: [L[I;
at CallCrashingFun.crashingMethod_dbarr(Native Method)
at CallCrashingFun.main(CallCrashingFun.java:100)
Caused by: java.lang.ClassNotFoundException: [I
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
未添加Hook时,目标方法可正常运行,输出:
DbArray: [
[2,2,2,]
]
相关代码
Frida Hook脚本
var t_class = Java.use("CallCrashingFun") var method_name = "crashingMethod_dbarr" t_class[method_name].implementation = function(dbint) { console.log("Hook works!") } /* Also tried with params t_class[method_name].overload.apply(t_class[method_name], param_types).implementation = function(dbint) { console.log("Hook works!") }*/ /* This however doesn't crash var imp_cp = t_class[method_name].implementation t_class[method_name].implementation = imp_cp */
测试Java代码
System.loadLibrary("native"); int arr[] = {2,2,2}; int[][] dbarr = {arr}; new CallCrashingFun().crashingMethod_dbarr(dbarr); private native void crashingMethod_dbarr(int[][] dbarr);
JNI C++代码
JNIEXPORT void JNICALL Java_CallCrashingFun_crashingMethod_1dbarr (JNIEnv *env, jobject thisObject, jobjectArray dbtab) { int i, j; std::cout << "DbArray: " << "[" << std::endl; jsize len = (env)->GetArrayLength(dbtab); for (i=0; i<len; i++) { std::cout << "["; jintArray insArr = (jintArray) (env)->GetObjectArrayElement(dbtab, i); jsize inlen = (env)->GetArrayLength(insArr); jint *body = (env)->GetIntArrayElements(insArr, 0); for (j=0; j<inlen; j++) { std::cout << body[i] << ","; // 注:此处存在索引错误,应为body[j],但不影响Hook问题 } std::cout << "]" << std::endl; } std::cout << "]" << std::endl; }
环境信息
- Java版本:
$ /usr/bin/java --version
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
openjdk 11.0.17 2022-10-18
OpenJDK Runtime Environment Temurin-11.0.17+8 (build 11.0.17+8)
OpenJDK 64-Bit Server VM Temurin-11.0.17+8 (build 11.0.17+8, mixed mode)
- Frida Server版本:
frida-server-16.0.8-linux-x86_64
解决方案
该问题是Frida自动解析多维数组类型时的类加载兼容性问题,通过显式指定方法的参数类型签名即可解决:
修正后的Hook脚本
var t_class = Java.use("CallCrashingFun"); var method_name = "crashingMethod_dbarr"; // 明确指定参数类型为int[][]的签名:[[I t_class[method_name].overload("[[I").implementation = function(dbint) { console.log("Hook works!"); // 若需要保留原方法逻辑,添加以下一行调用原方法 // this[method_name](dbint); };
原理说明
Java数组的类型签名规则:
[I代表int[](一维int数组)[[I代表int[][](二维int数组)- 多维数组每增加一维,签名前多一个
[
之前的错误源于Frida自动解析方法时,对多维数组类型的类加载处理异常,显式指定参数类型签名可让Frida精准定位目标方法,规避类加载错误。
内容的提问来源于stack exchange,提问作者mast313

