1、Xposed原理介绍

Xposed 框架是一个运行在 Android 操作系统之上的钩子框架,是以模块扩展方式来实现对系统部分功能的修改。

app_process

Xposed 框架 Native 部分,用于替换原生 app_process,并为 XposedBridge 提供 JNI 方法。

XposedBridge
Xposed 框架 Java 部分,编译后会生成一个 jar 包,Xposed 框架的 app_process 会将此加入到系统 class path 中。

android_art
Xposed 框架定制的 Android ART

XposedInstaller
Xposed 框架插件管理 App

XposedTools
用于编译项目的工具集

Android 系统是基于 Linux 的,其第一个由内核启动的用户进程是 init 进程。init 进程随后会创建 zygote 进程,Android 应用程序进程都是由 zygote 进程孵化而来。zygote 所对应的可执行程序是 app_process,xposed 框架通过替换系统的 app_process 可执行文件以及虚拟机动态链接库,让 zygote 在启动应用程序进程时注入框架代码,进而实现对应用程序进程的劫持。

Xposed框架通过替换**/system/bin/app_process**程序来控制Zygote进程

在核心功能启动后,Xposed框架会通过HookZygoteInit类的handleLoadPackage方法,来判断当前进程是否是需要hook的应用程序进程。

如果当前进程需要hook,Xposed框架会开始进行hook操作。在hook操作中,Xposed框架会将Java层函数的指针替换为对应的native函数的指针,并将这些native函数注册为本地JNI方法。

Xposed框架会将Java层函数转换为native函数,并将这些native函数的指针保存在XposedBridge类的sHookedMethodCallbacks静态变量中。

Xposed框架会通过JNI的RegisterNatives方法,将这些native函数注册为本地JNI方法。

当应用程序调用被hook的Java层函数时,实际上会调用对应的native函数,从而实现hook操作。

2、代码解析

xposed 的 app_main2.cpp中做了xposed的初始化

1
2
3
4
5
6
7
8
9
10
11
12
/** 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();
}

Zygote进程,使其在启动过程中加载XposedBridge.jar。XposedBridge.jar包中包含了Xposed框架的核心代码

XposedBridge.jar中的 XposedBridge 类的 main 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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);
}
}

3、Xposed检测

  1. 检查内存中是否有XposedBridge.jar
  2. 检查是否有xposed-installer 这个apk
  3. 反射调用xposed的一些核心类,如果可以反射找到,说明注入了XposedBridge.jar
2025-03-18

⬆︎TOP