作者:裴广勇
Xposed 是Android平台上的一个著名开源框架,作者是rovo89。Xposed能够动态修改Android系统或者应用,给了用户 DIY 系统或者应用的能力。Xposed主要由两部分组成,Xposed框架和Xposed模块。Xposed框架提供Java hook的能力。Xposed模块运行在Xposed框架上,使用Xposed框架提供的Java hook能力动态修改系统或者目标应用。
Xposed开源代码网址是github.com/rovo89。Xposed代码工程结构如下图所示:
Xposed安装时需要替换系统分区文件,具体是使用修改后的app_process替换Android系统分区中的原生app_process(art虚拟机还会替换libart.so)。下图中左半部分是Android应用正常启动流程;右半部分是安装Xposed后,Andoid应用启动流程。
使用Xposed的前提是手机需要root。
依赖root权限替换系统分区文件是Xposed实现的一个路径。是否存在其他实现路径?
Xposed模块能正常运行在目标应用中,这是目标。通过分析Xposed的开源代码,可以总结出下面结论。在目标应用启动时,能控制目标应用进程,建立Xposed运行环境(主要指Xposed框架),加载Xposed模块并启动Xposed模块,这是Xposed模块能正常运行在目标应用中的核心逻辑。
一个第三方Android应用因为权限问题,不能控制其他应用进程,但是在其应用内部的任何操作是没有权限问题的,因为都是运行在同一个Linux用户下。如果Android应用能够提供一个沙箱,双开其他Android类应用, 同时能提供Java hook能力,就可以实现非root手机运行Xposed,这在技术上是可行的。
下面具体介绍应用双开和Xposed移植,首先是整体框架图:
1. 应用双开
应用双开核心原理是利用沙箱技术虚拟化一个Android系统。
所谓Android虚拟化技术,就是利用Hook技术和沙箱机制,在一个Android应用中模拟出一个Android系统。双开的应用运行在虚拟化出来的Android系统中,与外部的Android系统完全隔离。
要想虚拟化一个Android系统出来,首先要做到如下几点:
- Application运行环境构建及初始化
- Android四大组件生命周期管理
- 双开的App与Android系统的透明通信
- IO重定向
2. Xposed移植
Xposed框架移植涉及到两部分,一部分是Xposed框架C++部分的移植,具体是Java hook native库(libxposed_ dalvik.so和libxposed_art.so)的移植;一部分是Xposed 框架Java部分的移植,具体是XposedBridge.jar的移植。
移植libxposed_dalvik.so库相对简单,原生的代码不需要修改,编译后可直接使用。移植libxposed_art.so相对复杂,因为其部分实现是依赖于修改后的libart.so。移植libxposed_art.so需要实现一套新的Java hook机制。XposedBridge.jar的移植主要整理出用于加载Xposed模块和启动Xposed模块的代码。
目前,在art虚拟机上实现Java hook主要有两个方案,一个是inline hook,一个是虚拟机方法替换。
art虚拟机在加载一个类的时候会将类中方法解析成 ArtMethod 结构体,结构体中保存着一些运行时的必要信息以及需要执行的指令指针地址。这些指令指针地址为实现Java hook提供了条件。
Inline Hook即内部跳转Hook,通过替换函数开始处的指令为跳转指令,使得原函数跳转到自己的函数,通常还会保留原函数的调用接口。其缺点是无法对一些太短的函数Hook。下图是inline hook原理示意图:
虚拟机方法替换,在 native 层将原方法的 ArtMethod 结构体替换成新方法的结构体,执行原方法的时候便会执行到新方法的指令。由于不同的版本 ArtMethod 结构体参数会不一样,所以不同的版本有不同的实现,下图是Android6.0 版本的方法替换示例代码:
双开应用进程是双Application同时运行,一个是Host Application(第三方双开应用自己的Application),一个是双开应用的Application。我们可以在双开应用的Application启动之前,通过DexClassloader将XposedBridge.jar包加载到进程中,从而建立Xposed运行环境;建立Xposed运行环境后,通过DexClassloader加载Xposed模块并启动Xposed模块,具体如下图所示:
总结
经过从技术角度的分析,探讨了不root手机的情况下,在Android应用中运行Xposed插件的技术实现路径。在市场上,已经出现了支持Xposed插件运行的应用“分身大师X版”,其已实现在双开的应用中运行Xposed插件。从该产品来看,非root手机支持Xposed完全具有可行性