Xposed源码分析


主要行为替换Zygote,进行拓展

1.system/bin/app_process.cpp

if (zygote) {
        runtime.start(keepLoadingXposed ? XPOSED_CLASS_DOTS : "com.android.internal.os.ZygoteInit",
                startSystemServer ? "start-system-server" : "");
} else if (className) {
        // Remainder of args get passed to startup class main()
        runtime.mClassName = className;
        runtime.mArgC = argc - i;
        runtime.mArgV = argv + i;
        runtime.start(keepLoadingXposed ? XPOSED_CLASS_DOTS : "com.android.internal.os.RuntimeInit",application ? "application" : "tool");
}

其中XPOSED_CLASS_DOTS在xposed.h

#define XPOSED_CLASS_DOTS "de.robv.android.xposed.XposedBridge"

2.XposedBridge.java,main函数

if (initNative()) {//java函数jni的注册
if (startClassName == null) {
// Initializations for Zygote
initXbridgeZygote();//fork some main android class
}
loadModules(startClassName);//load xposed apks and call callbacks
} else {
log("Errors during native Xposed initialization");
}

1.initNative()主要负责java函数jni的注册

//xposedHandleHookedMethod
//xposedInvokeOriginalMethodNative
//objectArrayClass
//xresourcesClass
//xresourcesTranslateResId
//xresourcesTranslateAttrId
//register_android_content_res_XResources

主要实现Xposed.cpp->de_robv_android_xposed_XposedBridge_initNative

 2.initXbridgeZygote()和loadModules相当于是Xposed对原Zygote的扩展

initXbridgeZygote()主要是做了几个hook操作

findAndHookMethod(ActivityThread.class, "handleBindApplication", "android.app.ActivityThread.AppBindData", new XC_MethodHook());
findAndHookMethod("com.android.server.ServerThread", null,
Build.VERSION.SDK_INT < 19 ? "run" : "initAndLoop", new XC_MethodHook());
hookAllConstructors(LoadedApk.class, new XC_MethodHook());
findAndHookMethod("android.app.ApplicationPackageManager",null,"getResourcesForApplication",ApplicationInfo.class, new XC_MethodHook());
if (!new File(BASE_DIR + "conf/disable_resources").exists()) {
hookResources();
}

find Method主要利java的反射

findAndHookMethod-findMethodExact-

Method method = clazz.getDeclaredMethod(methodName, parameterTypes);//reflect

-hookMethod(Member hookMethod, XC_MethodHook callback)

3.loadModules(startClassName);

Try to load all modules defined in BASE_DIR/conf/modules.list

And 安排好各种回调 IXposedHookZygoteInitIXposedHookLoadPackage,IXposedHookInitPackageResources和IXposedHookCmdInit

Xposed扩展模块必须继承上面的4个接口之一,重写其中的handleXXX函数,即各种回调,它们就是在loadModules执行的

3.Hook原理

主要实现hookMethodNative,即Xposed.cpp中的de_robv_android_xposed_XposedBridge_hookMethodNative函数

// 保存原函数信息
    XposedHookInfo* hookInfo = (XposedHookInfo*) calloc(1, sizeof(XposedHookInfo));
    memcpy(hookInfo, method, sizeof(hookInfo->originalMethodStruct));
    hookInfo->reflectedMethod = dvmDecodeIndirectRef(dvmThreadSelf(), env->NewGlobalRef(reflectedMethodIndirect));
    hookInfo->additionalInfo = dvmDecodeIndirectRef(dvmThreadSelf(), env->NewGlobalRef(additionalInfoIndirect));

// 将函数入口替换为xposedCallHandler,每次调这个被hookmethod,其实质上调用的是xposedCallHandler

    SET_METHOD_FLAG(method, ACC_NATIVE);
    method->nativeFunc = &xposedCallHandler;
    method->insns = (const u2*) hookInfo;
    method->registersSize = method->insSize;
    method->outsSize = 0;

xposedCallHandler中根据函数参数的TYPE,即(IF...这些参数在ClassUtil.java中定义)组织好参数:

xposedSetObjectArrayElement(argsArray, dstIndex++, obj);

最后:

dvmCallMethod(self, xposedHandleHookedMethod, NULL, &result, originalReflected, (int) original, additionalInfo, thisObject,argsArray);

xposedHandleHookedMethod是对XposedBridge类handleHookedMethod的引用,

de_robv_android_xposed_XposedBridge_initNative中链接:

xposedHandleHookedMethod = (Method*) env->GetStaticMethodID(xposedClass, "handleHookedMethod","(Ljava/lang/reflect/Member;ILjava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");

XposedBridge类的handleHookedMethod, disableHooks则调用原函数,否则beforeHookedMethod-invokeOriginalMethodNative-afterHookedMethod

if (disableHooks) {
try {
return invokeOriginalMethodNative(method, originalMethodId, additionalInfo.parameterTypes,additionalInfo.returnType, thisObject, args);
//......
do {
try {((XC_MethodHook)callbacksSnapshot[beforeIdx]).beforeHookedMethod(param);
//......
try {
param.setResult(invokeOriginalMethodNative(method,originalMethodId,
additionalInfo.parameterTypes, additionalInfo.returnType, param.thisObject, param.args));
}
//......
try {
((XC_MethodHook) callbacksSnapshot[afterIdx]).afterHookedMethod(param);
}


属原创!


你可能感兴趣的:(Android,xposed)