Xposed源码分析

来源:互联网 发布:linux dd命令 编辑:程序博客网 时间:2024/06/05 08:17


主要行为替换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 ZygoteinitXbridgeZygote();//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 <code>BASE_DIR/conf/modules.list</code>

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);}


属原创!


0 0