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函数调用可以看到这个函数的作用。

相关推荐