JniTrace
大约 3 分钟
目前有很多JniTrace方案,Jni的调用监控是分析过程必不可少的。为了保护代码,大多数关键函数都是native化的。而native化的关键函数必然少不了和Jni相关的api打交道。而该ROM级JniTrace是直接在函数执行的内部输出,而非hook打印。所以优势在于能绕过一定检测。缺点就是目前并没有对所有jni函数进行处理。并且其针对的是所有动态库的所有jni函数,导致输出量会巨大。下面介绍该栏目的功能

JNI模块名称
目标动态库的名称,在堆栈1的输出中,可以过滤掉一些输出。
JNI函数名称
当指定函数执行时,才激活JNI日志输出
CallMethod过滤
当通过Jni调用Java中的指定函数时,才触发CallMethod
的日志
无堆栈输出
由于是针对全局的监控输出,所以jni的调用量非常巨大,在这种情况下还进行堆栈输出,有一定概率导致崩溃。所以可以关闭到堆栈的输出,来降低出问题的概率。输出日志如下
mikrom /* TID 9698 */
mikrom [+] JNIEnv->GetMethodID
mikrom |- jclass :Landroid/system/ErrnoException;
mikrom |- char* :0x70727c7900
mikrom |: <init>
mikrom |- char* :0x70727c80b0
mikrom |: (Ljava/lang/String;I)V
mikrom /* TID 9698 */
mikrom [+] JNIEnv->CallNonvirtualVoidMethodV
mikrom /* TID 9698 */
mikrom [+] JNIEnv->GetStringUTFChars
mikrom |- jboolean* : 0
mikrom |= char* : rc4
mikrom |- jmethodID :0x0 {void android.system.ErrnoException.<init>(java.lang.String, int)}
mikrom |- va_list :0x6fe62a4420
mikrom /* TID 9698 */
mikrom [+] JNIEnv->GetStringUTFChars
mikrom |- jboolean* : 0
mikrom |= char* : cn.mik.kmodule.callback.Cipher
mikrom |: jstring : stat
mikrom |: jint : 2
堆栈输出1
最早先封装的堆栈输出方案,是基于自封装的so实现,jni调用过多时出现崩溃,输出日志如下
mikrom /* TID 11307 */
mikrom [+] JNIEnv->GetStringUTFChars
mikrom |- jboolean* : 0
mikrom |= char* : cn.mik.kmodule.callback.MessageDigest
-------------------------mikrom Backtrace-------------------------
#00 pc 00000000000ade48 /apex/com.android.runtime/lib64/bionic/libc.so (tgkill+8)
#01 pc 0000000000000c24 /system/lib64/libkbacktrace.so (_Z10kbacktracebPKc+148)
#02 pc 000000000062f994 /apex/com.android.art/lib64/libart.so (_ZN3art11ShowVarArgsERKNS_33ScopedObjectAccessAlreadyRunnableEPKcPhS4_+260)
#03 pc 00000000004be984 /apex/com.android.art/lib64/libart.so (_ZN3art3JNIILb0EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh+1316)
#04 pc 00000000005923dc /apex/com.android.art/lib64/libart.so (_ZN3artL18Class_classForNameEP7_JNIEnvP7_jclassP8_jstringhP8_jobject+92)
mikrom /* TID 11307 */
mikrom [+] JNIEnv->GetStringUTFChars
mikrom |- jboolean* : 0
mikrom |= char* : cn.mik.kmodule.callback.MessageDigest
-------------------------mikrom Backtrace-------------------------
#00 pc 00000000000ade48 /apex/com.android.runtime/lib64/bionic/libc.so (tgkill+8)
#01 pc 0000000000000c24 /system/lib64/libkbacktrace.so (_Z10kbacktracebPKc+148)
#02 pc 000000000062f994 /apex/com.android.art/lib64/libart.so (_ZN3art11ShowVarArgsERKNS_33ScopedObjectAccessAlreadyRunnableEPKcPhS4_+260)
#03 pc 00000000004be984 /apex/com.android.art/lib64/libart.so (_ZN3art3JNIILb0EE17GetStringUTFCharsEP7_JNIEnvP8_jstringPh+1316)
#04 pc 00000000005923dc /apex/com.android.art/lib64/libart.so (_ZN3artL18Class_classForNameEP7_JNIEnvP7_jclassP8_jstringhP8_jobject+92)
堆栈输出2
后来找到的android系统中自带的堆栈输出方案。测试同样有崩溃的可能,输出日志如下
mikrom /* TID 12030 */
mikrom [+] JNIEnv->GetMethodID
mikrom |- jclass :Ljava/io/InputStream;
mikrom |- char* :0x6ff6727160
mikrom |: read
mikrom |- char* :0x6ff6727158
mikrom |: ([BII)I
mikrom #00 pc 000000000062f2a8 /apex/com.android.art/lib64/libart.so (art::print_stack_trace()+88)
mikrom #01 pc 000000000062f6c8 /apex/com.android.art/lib64/libart.so (art::ShowVarArgs(art::ScopedObjectAccessAlreadyRunnable const&, char const*, _jclass*, char const*, char const*, _jmethodID*)+680)
mikrom #02 pc 00000000004828f4 /apex/com.android.art/lib64/libart.so (art::JNI<false>::GetMethodID(_JNIEnv*, _jclass*, char const*, char const*)+660)
mikrom #03 pc 000000000002c0e0 <anonymous:0000006ff660e000>
mikrom /* TID 12030 */
mikrom [+] JNIEnv->CallIntMethodV
mikrom |- jmethodID :0x11 {int java.io.InputStream.read(byte[], int, int)}
mikrom |- va_list :0x6ff642c6e0
mikrom |: jobject : 0x6ff642c4b0
mikrom |: jint : 0
mikrom |: jint : 8192
mikrom /* TID 12030 */
mikrom [+] JNIEnv->GetStringUTFChars
mikrom |- jboolean* : 0
mikrom |= char* : cn.mik.kmodule.callback.MessageDigest
mikrom #00 pc 000000000062f2a8 /apex/com.android.art/lib64/libart.so (art::print_stack_trace()+88)
mikrom #01 pc 00000000004be980 /apex/com.android.art/lib64/libart.so (art::JNI<false>::GetStringUTFChars(_JNIEnv*, _jstring*, unsigned char*)+1312)
mikrom #02 pc 00000000005923d8 /apex/com.android.art/lib64/libart.so (art::Class_classForName(_JNIEnv*, _jclass*, _jstring*, unsigned char, _jobject*)+88)
mikrom #03 pc 00000000000978ec /system/framework/arm64/boot.oat (art_jni_trampoline+124)
mikrom #04 pc 000000000022eb10 /system/framework/arm64/boot.oat (java.lang.Class.forName+112)
mikrom #05 pc 0000000000209398 /apex/com.android.art/lib64/libart.so (nterp_helper+152)
mikrom #06 pc 00000000000ffb16 /apex/com.android.art/javalib/core-oj.jar (java.lang.krom.Reflect.forName+2)
mikrom #07 pc 0000000000209334 /apex/com.android.art/lib64/libart.so (nterp_helper+52)
mikrom #08 pc 00000000001002d4 /apex/com.android.art/javalib/core-oj.jar (java.lang.krom.Reflect.on)
mikrom #09 pc 0000000000209334 /apex/com.android.art/lib64/libart.so (nterp_helper+52)
mikrom #10 pc 00000000000ff4b4 /apex/com.android.art/javalib/core-oj.jar (java.lang.krom.KCommon.CallInjectMethod+76)
mikrom #11 pc 00000000001a5b18 /system/framework/arm64/boot.oat (java.security.MessageDigest.update+184)
mikrom #12 pc 0000000000145930 /system/framework/arm64/boot.oat (sun.security.util.ManifestEntryVerifier.update+208)
mikrom #13 pc 00000000001018cc /system/framework/arm64/boot.oat (java.util.jar.JarVerifier.update+92)
mikrom #14 pc 0000000000312bf8 /system/framework/arm64/boot.oat (java.util.jar.JarVerifier$VerifierStream.read+200)
mikrom #15 pc 000000000021096c /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+556)
mikrom #16 pc 0000000000281328 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+1032)
mikrom #17 pc 000000000062efb4 /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithVarArgs<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, std::__va_list)+468)
mikrom #18 pc 000000000062f21c /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithVarArgs<_jmethodID*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+92)
mikrom #19 pc 0000000000489f4c /apex/com.android.art/lib64/libart.so (art::JNI<false>::CallIntMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+684)
mikrom #20 pc 000000000002c160 <anonymous:0000006ff660e000>