算是作为一个 Art 学习的切入点吧
网上找了很多资料,大多数基于dvm的资料。
(Dvm可以 参考 邓凡平先生的 博客 :https://blog.csdn.net/Innost/article/details/50461783)
今天也是自我总结一下 Art模式下的
在github 搜索 可得如下三个项目,分别介绍一下
XposedInstaller ,这是 Xposed 的插件管理和功能控制 APP,也就是说 Xposed 整体管控功能就是由这个 APP 来完成的,它包括启用 Xposed 插件功能,下载和启用指定插件 APP,还可以禁用 Xposed 插件功能等。注意,这个 app 要正常无误得运行必须能拿到 root 权限。
Xposed,这个项目属于 Xposed 框架,其实它就是单独搞了一套 xposed 版的 zygote。这个 zygote 会替换系统原生的 zygote。所以,它需要由 XposedInstaller 在 root 之后放到 /system/bin 下。
XposedBridge,这个项目也是 Xposed 框架,它属于 Xposed 框架的 Java 部分,编译出来是一个 XposedBridge.jar 包。
问题1 :
当我们获取Root以后安装Xposed会发生什么?
下载XposedInstaller 导入 AndroidStudio
先看看 安装之前 :
从页面初始化开始入手
StatusInstallerFragment-》onCreateView
第一次见到user_de目录 使用如下
安装完毕之后 ,当我们点击
获取手机的各种信息,拼接成下载的URL
我们以 安卓 7.1 arm64的 为标准
下载完毕的 zip内容如下 主要包含 system 和 META-INT两个文件夹
system->
---lib64->
------libart.so
------libart-compiler.so
------libart-disassembler.so
------libsigchain.so
------libxposed_art.so
---lib->
------libart.so
------libart-compiler.so
------libsigchain.so
------libxposed_art.so
---framework->
------XposedBridge.jar(注入到对应app进程里面的jar包)
---bin->
------app_process32_xposed
------app_process64_xposed
------dex2oat
------patchoat
xposed.prop->
xposed版本说明文件
META-INT->
---里面有文件配置脚本 flash-script.sh 配置各个文件安装位置
下载完毕会跳转到 InstallationActivity
onCreate 函数 -》创建 InstallationFragment
-》调用 startInstallation解压 zip文件-》执行done回调 -》
替换系统system对应目录下的文件-》执行刷机命令-》重启手机
问题2:
Xposed 如何注入到zygote 进程中的?
首先复习一下Art虚拟机启动流程:
主要大致流程
①Linux init进程解析配置脚本->②app_process(zygote进程对应的程序)->③ZygoteInit
① 解析配置脚本
service zygote:它告诉init进程,现在我们要配置一个名为zygote的服务。
/system/bin/app_process: 声明zygote进程对应的文件路径。init创建服务的处理逻辑很简单,就是启动(fork)一个子进程来运行指定的程序。对zygote服务而言这个程序就是/system/bin/app_process。
-Xzygote/system/bin--zygote--start-system-server:传递给app_process的启动参数。
②app_process 创建
frameworks\base\cmds\app_process.cpp-》main函数
frameworks\base\core\jni\AndroidRuntime.cpp-》start函数
核心函数为: init,startVm
三个函数主要功能:
1. JNI_GetDefaultJavaVMInitArgs -- 获取虚拟机的默认初始化参数
2. JNI_CreateJavaVM -- 在进程中创建虚拟机实例
3. JNI_GetCreatedJavaVMs -- 获取进程中创建的虚拟机实例
ART像Dalvik一样,都实现Java虚拟机接口,这三个接口也是ART虚拟机核心接口。
startVm函数很复杂牵扯逻辑也很多,不 逐一描述了。
③ZygoteInit
继续查看 frameworks\base\core\jni\AndroidRuntime.cpp-》start函数
参数className的值等于“com.android.internal.os.ZygoteInit”,本地变量env是从调用另外一个成员函数startVm创建的ART虚拟机获得的JNI接口。函数的目标就是要找到一个名称为com.android.internal.os.ZygoteInit的类,以及它的静态成员函数main,然后就以这个函数为入口,开始运行ART虚拟机。为此,函数执行了以下步骤:
① 调用JNI接口FindClass加载com.android.internal.os.ZygoteInit类。
② 调用JNI接口GetStaticMethodID找到com.android.internal.os.ZygoteInit类的静态成员函数main。
③ 调用JNI接口CallStaticVoidMethod开始执行com.android.internal.os.ZygoteInit类的静态成员函数main。
下面看看 Xposed是如何做拦截的
开打 Xposed项目
大于21编译走的是app_main2.cpp 看看 具体改动了哪些
经过查阅,被修改的main函数,一共有两个地方。
其一,红框的地方 是判断是否是Xposed版本的虚拟机
在解析开启启动init脚本的时候 添加了--xposedversion 版本号的命令
这块启动的已经是自定义的虚拟机了
handleOptions函数
第二个地方在 start函数这块,先看看 原函数。
原函数
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2020-2-26 18:04
被珍惜Any编辑
,原因: