XPosed解析--callback_XposedBridge_initNative分析
callback_XposedBridge_initNative函数为XposedBridge注册回调方法的JNI接口,在整个Xposed中起关键作用,连接了module与Xposed框架,下面来分析一些这个函数。
完整的代码如下:libxposed_dalvik.cpp
jboolean callback_XposedBridge_initNative(JNIEnv* env) { xposedHandleHookedMethod = (Method*) env->GetStaticMethodID(classXposedBridge, "handleHookedMethod", "(Ljava/lang/reflect/Member;ILjava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"); if (xposedHandleHookedMethod == NULL) { ALOGE("ERROR: could not find method %s.handleHookedMethod(Member, int, Object, Object, Object[])", CLASS_XPOSED_BRIDGE); dvmLogExceptionStackTrace(); env->ExceptionClear(); return false; } Method* xposedInvokeOriginalMethodNative = (Method*) env->GetStaticMethodID(classXposedBridge, "invokeOriginalMethodNative", "(Ljava/lang/reflect/Member;I[Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"); if (xposedInvokeOriginalMethodNative == NULL) { ALOGE("ERROR: could not find method %s.invokeOriginalMethodNative(Member, int, Class[], Class, Object, Object[])", CLASS_XPOSED_BRIDGE); dvmLogExceptionStackTrace(); env->ExceptionClear(); return false; } dvmSetNativeFunc(xposedInvokeOriginalMethodNative, XposedBridge_invokeOriginalMethodNative, NULL); objectArrayClass = dvmFindArrayClass("[Ljava/lang/Object;", NULL); if (objectArrayClass == NULL) { ALOGE("Error while loading Object[] class"); dvmLogExceptionStackTrace(); env->ExceptionClear(); return false; } return true; }
xposedHandleHookedMethod=(Method*)env->GetStaticMethodID(classXposedBridge,"handleHookedMethod",
"(Ljava/lang/reflect/Member;ILjava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
这个函数式通过JNI环境指针env,查找classXposedBridge类中的handleHookedMethod函数,具体java源码在XposedBridge:handleHookedMethod,其中GetStaticMethodID可以返回Method对象指针,当Xposed框架调用hookedMethodCallback函数时会调用handleHookedMethod方法,从而调用到java层的回调。
Method*xposedInvokeOriginalMethodNative=(Method*)env->GetStaticMethodID(classXposedBridge,"invokeOriginalMethodNative",
"(Ljava/lang/reflect/Member;I[Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
这段是获取XposedBridge:invokeOriginalMethodNative方法,这个方法是native,会通过jvm调用XposedBridge_invokeOriginalMethodNativeJNI函数。
invokeOriginalMethodNative和JNI函数XposedBridge_invokeOriginalMethodNative如何关联呢?在java层并没有XposedBridge_invokeOriginalMethodNative的注册,而在这里确调用了此JNI方法,关键在这个函数dvmSetNativeFunc。
dvmSetNativeFunc(xposedInvokeOriginalMethodNative,XposedBridge_invokeOriginalMethodNative,NULL);
此函数是真正执行JNI方法注册的函数,建立了Method和JNI方法的关联,对此方法进一步解析:
void dvmSetNativeFunc(Method* method, DalvikBridgeFunc func, const u2* insns) { ...... if (insns != NULL) { /* update both, ensuring that "insns" is observed first */ method->insns = insns; android_atomic_release_store((int32_t) func, (void*) &method->nativeFunc); } else { /* only update nativeFunc */ method->nativeFunc = func; } ...... }
这里的method->nativeFunc=func;就是把JNI函数XposedBridge_invokeOriginalMethodNative的地址赋值给Method的nativeFunc变量,当java层调用invokeOriginalMethodNative时就会调用到此JNI方法。
objectArrayClass=dvmFindArrayClass("[Ljava/lang/Object;",NULL);
这个函数用来加载Object类,为后面调用hook做准备,结合hook函数调用可以看到这个函数的作用。