1 | include <jni.h> |
上面是我自己写的jni实现.
stackplz hook NewStringUTF 打印堆栈
1 | ./stackplz -n com.zj.my_md5 -l /apex/com.android.art/lib64/libart.so -w _ZN3art3JNIILb1EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh[str] --stack |
结果如下, 可以看到调用堆栈已经打印出来了.
hook 一下GetStringUTFChars 看看入参?
先查看一下导出函数地址
1 | ./stackplz -n com.zj.my_md5 -l /apex/com.android.art/lib64/libart.so -w GetStringUTFChars --dumpret |
执行结果如下
1 | findBTFAssets btf_file=a12-5.10-arm64_min.btf |
执行结果解析
0x4b7528 是函数最后一条指令的地址. _ZN3art3JNIILb0EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh 是导出函数名, 0x4b6e60 是导出函数在so中的偏移
我们试试hook _ZN3art3JNIILb0EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh
1 | ./stackplz -n com.zj.my_md5 -l /apex/com.android.art/lib64/libart.so -w _ZN3art3JNIILb0EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh[int,str] |
看看结果
1 | idx:0 [/apex/com.android.art/lib64/libart.so] -> sym:_ZN3art3JNIILb0EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh off:0x0 |
发现并没有调用,说明很可能是调用的另一个函数, 试试另一个函数 _ZN3art3JNIILb1EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh
1 | ./stackplz -n com.zj.my_md5 -l /apex/com.android.art/lib64/libart.so -w _ZN3art3JNIILb1EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh[int,str] |
结果如下
乱码 这是为什么呢? 原来 GetStringUTFChars 的入参是jstring, 出参是char * 所以我们要inline hook GetStringUTFChars 的最后一条指令的地址, 然后打印x0的值(arm64调用约定, 返回值一般放在x0寄存器)。
试试看, 代码如下
1 | ./stackplz -n com.zj.my_md5 -l /apex/com.android.art/lib64/libart.so -w 0x51acb8[str:x0] |
执行结果
可以看到 hook成功
同理可以Hook NewStringUTF, NewStringUTF 的入参是 char *, 所以只需要hook 偏移或者导出函数地址就可以了, 不需要hook 函数的最后一条指令的地址
1 | ./stackplz -n com.zj.my_md5 -l /apex/com.android.art/lib64/libart.so -w _ZN3art3JNIILb1EE12NewStringUTFEP7_JNIEnvPKc[int,str] --regs |
亲测可行, 并且不同的so, 可以调用的导出函数并不一样. 例如某音和我自己写的so, 虽然都是调用的 NewStringUTF, 但是对应的导出函数名是不一样的,建议两个都试一下
hook 某音 GetStringUTFChars
1 | ./stackplz -n com.ss.android.ugc.aweme -l /apex/com.android.art/lib64/libart.so -w 0x4b7528[str:x0] |
效果如下
打印的无关信息过多, 试着过滤掉一部分. 只要/data开头的数据. -f 表示filter w:/data 表示 white 白名单. str.f0表示对第一个char* 应用f0过滤策略, 即 w:/data
1 | ./stackplz -n com.ss.android.ugc.aweme -l /apex/com.android.art/lib64/libart.so -w 0x4b7528[str.f0:x0] -f w:/data |
看看结果
hook GetStaticMethodID
1 | ./stackplz -n com.ss.android.ugc.aweme -l /apex/com.android.art/lib64/libart.so -w GetStaticMethodID --dumpret |
结果如下 豁然开朗
硬件断点 hook 0x1e66c 打印调用堆栈
1 | ./stackplz -p `pidof com.zj.my_md5` --brk 0x715adae66c:x --stack |
0x715adae66c 是绝对地址. 通过so基址加偏移得到的.