Xposed 原理
Xposed 使用替换app_process的方式(这是个二进制文件)
xposed 的 app_main2.cpp中做了xposed的初始化
/** 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;
// XposedBridge.jar 加载到 ClassPath 中
return addJarToClasspath();
}
主要是在这里代理了原来的流程,并加载了XposedBridge.jar到classpath中
初始化完成后进入魔改的runtimeStart:
调用 XPOSED_CLASS_DOTS_ZYGOTE,即XposedBridge.jar中的 XposedBridge 类的 main 方法
protected static void main(String[] args) {
// Initialize the Xposed framework and modules
try {
if (!hadInitErrors()) {
initXResources();
SELinuxHelper.initOnce();
SELinuxHelper.initForProcess(null);
runtime = getRuntime();
XPOSED_BRIDGE_VERSION = getXposedVersion();
// Xposed初始化
if (isZygote) {
XposedInit.hookResources();
XposedInit.initForZygote();
}
// 加载 Xposed 模块
XposedInit.loadModules();
} else {
Log.e(TAG, "Not initializing Xposed because of previous errors");
}
} catch (Throwable t) {
Log.e(TAG, "Errors during Xposed initialization", t);
disableHooks = true;
}
// Call the original startup code => 原始执行链
if (isZygote) {
ZygoteInit.main(args);
} else {
RuntimeInit.main(args);
}
}
它会在此加载Xposed的资源文件,以此完成后续的Hook操作。
那么也就有了对Xposed的检测方法
- 检查内存中是否有XposedBridge.jar
- 检查是否有xposed-installer 这个apk
- 反射调用xposed的一些核心类,如果可以反射找到,说明注入了XposedBridge.jar