因為 jni code 比較難 debug,還有一旦出問題,就會造成整個 vm crash.
所以 android 提供一個 switch, 讓 user 決定是不是要啟動 dalvik 對 jni 的安全檢查。
ro.kernel.android.checkjni
這個 option 在 build eng type 的 image 時,會被加進 build.prop
framework 中參考這個 option 是在:framework/base/core/jni/AndroidRuntime.cpp:
property_get("dalvik.vm.checkjni", propBuf, ""); if (strcmp(propBuf, "true") == 0) { checkJni = true; } else if (strcmp(propBuf, "false") != 0) { /* property is neither true nor false; fall back on kernel parameter */ property_get("ro.kernel.android.checkjni", propBuf, ""); if (propBuf[0] == '1') { checkJni = true; } }所以在 init.rc 中加上
setprop dalvik.vm.checkjni false
也可以。
在 dalvik 的 source code 中。
vm/Jni.c: } else if (strcmp(optStr, "-Xcheck:jni") == 0) { checkJni = true; } else if (strncmp(optStr, "-Xjniopts:", 10) == 0) { ... if (checkJni) { dvmUseCheckedJniVm(pVM); pVM->useChecked = true; } ... if (vm->useChecked) dvmUseCheckedJniEnv(newEnv);
也就是說,一旦 enable check:jni..
vm 就會..
vm/CheckJni.c void dvmUseCheckedJniEnv(JNIEnvExt* pEnv) { assert(pEnv->funcTable != &gCheckNativeInterface); pEnv->baseFuncTable = pEnv->funcTable; pEnv->funcTable = &gCheckNativeInterface; }
其中,gCheckNativeInterface 就是一些 check function..
static const struct JNINativeInterface gCheckNativeInterface = { NULL, NULL, NULL, NULL, Check_GetVersion, Check_DefineClass, Check_FindClass, Check_FromReflectedMethod, Check_FromReflectedField, Check_ToReflectedMethod, Check_GetSuperclass, Check_IsAssignableFrom, Check_ToReflectedField, ... ...
其中的一個,checkUtfString, 就是檢查 passing throught 的 string 是不是符合 modified utf 的格式。
/* * Verify that "bytes" points to valid "modified UTF-8" data. */ static void checkUtfString(JNIEnv* env, const char* bytes, bool nullOk, const char* func) { const char* origBytes = bytes; ... ... while (*bytes != '\0') { u1 utf8 = *(bytes++); // Switch on the high four bits. switch (utf8 >> 4) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: { // Bit pattern 0xxx. No need for any extra bytes. break; } .,,,
這個 function check fail 的話,在logcat 就會出現:
W/dalvikvm( 1044): JNI WARNING: illegal start byte 0xa6 W/dalvikvm( 1044): string: '米??007亞洲初登場超級紀念盤 Disc 2' W/dalvikvm( 1044): in Landroid/media/MediaScanner;.processFile (Ljava/lang/String;Ljava /lang/String;Landroid/media/MediaScannerClient;)V (NewStringUTF) ..
ref:
沒有留言:
張貼留言