当前位置: 移动技术网 > IT编程>开发语言>Java > xposed 框架创建以及初始化

xposed 框架创建以及初始化

2020年07月23日  | 移动技术网IT编程  | 我要评论
一、xposed 的实现在art 虚拟机上,xposed的实现,依赖的是: app_proces: 在开机是选者是否启动 xposed 的流程,初始化xposed等 libxposed_art.so && libart.so: 替代系统的libart.so库 XposedBridge.jar: xposed 的java 层实现。二、 启动xposed 框架:app_process 文件夹有有两个入口文件:Android.mk 会在编

一、xposed 的实现

在art 虚拟机上,xposed的实现,依赖的是:

    app_proces:         在开机是选者是否启动 xposed 的流程,初始化xposed等
    libxposed_art.so && libart.so:     替代系统的libart.so库
    XposedBridge.jar:  xposed 的java 层实现。

二、 启动xposed 框架:

app_process 文件夹有有两个入口文件:
Android.mk 会在编译 根据当前sdk 版本选者对应的 源文件作为入口

   app_main.cpp         sdk 21 之前
   app_main2.cpp        sdk 21 之后

在M版本上 入口文件为:app_main2.cpp。

系统在开机时 通过app_process 去创建 zygote 虚拟机:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

会调用到 app_main2.cpp的main方法中,在此方法中,会去初始化 xposed,并根据初始化结果去创建对应的虚拟机:

isXposedLoaded = xposed::initialize(true, startSystemServer, NULL, argc, argv);
runtimeStart(runtime, isXposedLoaded ? XPOSED_CLASS_DOTS_ZYGOTE : "com.android.internal.os.ZygoteInit", args, zygote);

三、xposed 框架的创建以及初始化

xposed.cpp–>initialize 初始化xposed 框架内的相关变量。:

bool initialize(bool zygote, bool startSystemServer, const char* className, int argc, char* const argv[]) {
            在此方法内会初始化xposed的相关变量,
            xposed->zygote = zygote;
            xposed->startSystemServer = startSystemServer;
            xposed->startClassName = className;
            xposed->xposedVersionInt = xposedVersionInt;
            并会将xposed 的java 层XposedBridge加载到系统中:tp
            return addJarToClasspath();  //即将XposedBridge.jar 加载到系统的CLASSPATH 路径中。
}

会根据初始化结果创建对应的虚拟机,如果初始化成功,会将zygoteInit 替换为 de.robv.android.xposed.XposedBridge,然后初始化
如果初始化失败,那么会按照正常流程去进行初始化

runtimeStart(runtime, isXposedLoaded ? XPOSED_CLASS_DOTS_ZYGOTE : "com.android.internal.os.ZygoteInit", args, zygote);
AndroidRuntime.cpp--->start

在此start,有三个步骤
1、创建对应虚拟机,
2、初始化虚拟机
3、调用传入的de.robv.android.xposed.XposedBridge类,初始化java层

        void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
        {
            //创建虚拟机,原生逻辑
            if (startVm(&mJavaVM, &env, zygote) != 0) {
                return;
            }
            //初始化虚拟机
            onVmCreated(env);

            //初始化xposed java层,即初始化XposedBridge.jar
            //获取 XposedBridge类的main方法,并调用。
            char* slashClassName = toSlashClassName(className);
            jclass startClass = env->FindClass(slashClassName);
            if (startClass == NULL) {
                ......
            } else {
                jmethodID startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");
            }
            if (startMeth == NULL) {
            ......
            } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
            }
        }

a、虚拟机初始化:
初始化xposed 的art虚拟机的流程为:

     cmds/xposed/app_main.cpp-->AppRuntime->onVmCreated
         cmds/xposed/xposed.cpp--->onVmCreated
        void onVmCreated(JNIEnv* env) {
            //通过读取/proc/self/maps 判断当前使用虚拟机,如果为art,那么 xposedLibPath 赋值为libxposed_art.so
            if (!determineRuntime(&xposedLibPath)) {...}
            //打开 libxposed_art.so so库,获取他的xposedInitLib 函数并调用,
            void* xposedLibHandle = dlopen(xposedLibPath, RTLD_NOW);
            bool (*xposedInitLib)(XposedShared* shared) = NULL;
            *(void **) (&xposedInitLib) = dlsym(xposedLibHandle, "xposedInitLib");  //libxposed_art.so 库的 xposedInitLib 函数会将,其自身的 onVmCreatedCommon 赋值给 xposed,
            //因为xposedInitLib onVmCreatedCommon 赋值给了 xposed,所以此处会调用 libxposed_art.so  onVmCreatedCommon 方法
            if (xposedInitLib(xposed)) {
                xposed->onVmCreated(env);
            }
        }

到libxposed_art.so 中继续进行初始化操作
libxposed_common.cpp—>onVmCreatedCommon

            void onVmCreatedCommon(JNIEnv* env) {
                //initXposedBridge  初始化Xposed java层,的相关natvie 方法与hook方法。
                //initZygoteService 系统原生逻辑
                if (!initXposedBridge(env) || !initZygoteService(env)) {
                    return;
                }
                //将initXposedBridge 函数内,初始化完成的 XposedBridge,与相关hookmethod 赋值给 artMethod
                if (!onVmCreated(env)) {
                    return;
                }
            }

b、初始化xposed 的XposedBridge.jar java 层 函数
找到de/robv/android/xposed/XposedBridge 类,注册其native 方法,并获取其handleHookedMethod方法

      bool initXposedBridge(JNIEnv* env) {
          classXposedBridge = env->FindClass(CLASS_XPOSED_BRIDGE);
          register_natives_XposedBridge(env, classXposedBridge)
          methodXposedBridgeHandleHookedMethod = env->GetStaticMethodID(classXposedBridge, "handleHookedMethod"
      }

将 XposedBridge类,与相关hookmethod 赋值给 artMethod, 在之后,hook 回调before 和after method 时使用

        bool onVmCreated(JNIEnv*) {
            // TODO: Handle CLASS_MIUI_RESOURCES?
            ArtMethod::xposed_callback_class = classXposedBridge;
            ArtMethod::xposed_callback_method = methodXposedBridgeHandleHookedMethod;
            return true;
        }

//到此有关xposed 框架的初始化完成。

四、AndroidRuntime::start 创建完并初始化虚拟机后,会调用传入的de.robv.android.xposed.XposedBridge类,初始化java层XposedBridge.jar

protected static void main(String[] args) {
XposedInit.hookResources(); //hook 住系统资源相关的方法
XposedInit.initForZygote(); // hook 住zygote 的相关方法。
XposedInit.loadModules(); // 加载系统中已经安装的xposed 模块
if (isZygote) {
ZygoteInit.main(args); //原生逻辑, ZygoteInit 的初始化
} else {
RuntimeInit.main(args);//原生逻辑,RuntimeInit 的初始化
}
}

到此xposed 框架创建完成。

本文地址:https://blog.csdn.net/xiaolli/article/details/107506138

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网