首页
社区
课程
招聘
[原创]Art模式下Xposed实现原理
发表于: 2020-2-26 17:52 13236

[原创]Art模式下Xposed实现原理

2020-2-26 17:52
13236

算是作为一个 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编辑 ,原因:
收藏
免费 8
支持
分享
最新回复 (13)
雪    币: 19
活跃值: (331)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
给小哥点个赞
2020-2-26 18:19
0
雪    币: 1867
活跃值: (3973)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
3
小哥有带注释的工程么?
2020-2-27 00:16
0
雪    币: 3368
活跃值: (14038)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
4
virjar 小哥有带注释的工程么?
没上传,今天可以上传一份
2020-2-27 09:54
0
雪    币: 1867
活跃值: (3973)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
珍惜Any 没上传,今天可以上传一份
辛苦小哥
2020-2-27 13:57
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
6
学习学习
2020-2-29 19:38
0
雪    币: 3907
活跃值: (5817)
能力值: ( LV12,RANK:200 )
在线值:
发帖
回帖
粉丝
7
学习学习!
2020-2-29 20:28
1
雪    币: 1759
活跃值: (2334)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
8
分析得很透彻,不愧是大佬
2020-3-3 09:38
0
雪    币: 1
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
牛逼,感谢老哥!!收藏了,慢慢消化
2020-3-8 02:28
0
雪    币: 4883
活跃值: (18890)
能力值: ( LV13,RANK:317 )
在线值:
发帖
回帖
粉丝
10
感谢分享!
2020-4-9 14:30
0
雪    币: 182
活跃值: (214)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
学习了
2020-6-9 10:27
0
雪    币: 1
活跃值: (1077)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
“告诉虚拟机这个方法不需要JIT编译,并将其设置成Native”,请教下“并将其设置成Native” 这行代码在那个位置?
2021-8-23 17:59
0
雪    币: 3368
活跃值: (14038)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
14
修改方法的flag
2021-8-24 18:45
0
游客
登录 | 注册 方可回帖
返回
//