0x00 背景
之前提到当安装Xposed framework
后,Xposed framework
会替换一个新的app_process
至/system/bin/
中,app_process
就是Android
中的Zygote
进程,这期以app_process
的实现为主线来详细分析Xposed framework
的实现。
0x01 框架分析
首先从main
函数开始:
main() {
if (zygote) {
isXposedLoaded = xposed::initialize(true, startSystemServer, NULL, argc, argv);
runtimeStart(runtime, "de.robv.android.xposed.XposedBridge", args, zygote);
}
}
在修改的main
函数中,首先调用initialize
函数初始化Xposed
的运行时环境,然后再调用runtimeStart
启动运行时环境。
initialize
函数的内部实现如下:
namespace xposed {
XposedShared* xposed = new XposedShared;
/** Initialize Xposed (unless it is disabled). */
bool initialize(bool zygote, bool startSystemServer, const char* className, int argc, char* const argv[]) {
...
xposed->zygote = zygote;
xposed->startSystemServer = startSystemServer;
xposed->startClassName = className;
xposed->xposedVersionInt = xposedVersionInt;
...
if (startSystemServer) {
if (!xposed::service::startAll()) {
return false;
}
xposed::logcat::start();
}
...
return addJarToClasspath();
}
其内部主要做了三件事情,首先给XposedShared
对象内部的成员赋值,然后调用startAll()
接口启动所有服务,最后调用addJarToClasspath()
将XposedBridge.jar
添加至系统目录,之后会将它加入到Zygote
进程地址空间中。
这里最重要的就是startAll()
,进一步来看它的代码实现:
bool startAll() {
bool useSingleProcess = !xposed->isSELinuxEnabled;
if (xposed->isSELinuxEnabled && !membased::init()) {
return false;
}
if (!useSingleProcess) {
pid = fork();
if (pid == 0) {
//child
systemService();
}
}
pid = fork();
if (pid == 0) {
//child
appService(useSingleProcess);
}
}
代码有所删减,关于SELinux
的部分不详细展开,只要知道如果开启SELinux
时,需要初始化一段供Xposed
使用的内存,然后通过fork
系统调用创建子进程,并在子进程中调用systemService
和appService
来添加Xposed
需要的服务。
来看appService
的代码实现: