本文档详细介绍了 Magisk Android 应用程序的架构和实现,该应用程序是与 Magisk 系统交互的主要用户界面。该应用程序负责 Magisk 的安装、配置、模块管理和更新。本文档侧重于应用程序本身的技术方面,特别是其存根 APK 系统、动态代码加载和反检测机制。
有关设备上 Magisk 安装过程的信息,请参阅 安装系统。有关模块系统详情,请参阅 模块系统。
Magisk Android 应用程序采用复杂的架构,旨在方便更新和避免被检测,同时为用户提供完整的功能。
来源:app/shared/src/main/java/com/topjohnwu/magisk/StubApk.java1-120
存根 APK 系统是 Magisk 应用程序架构的关键组成部分。它包含一个安装在设备上的最小化 APK,该 APK 在运行时动态加载完整的 Magisk 应用程序。
存根 APK 系统在应用程序的数据目录中维护两个重要文件:
来源:app/shared/src/main/java/com/topjohnwu/magisk/StubApk.java23-56
存根 APK 通过两种机制加载完整应用程序:
DynamicClassLoader 从完整 APK 加载 Java 类ResourcesLoader (Android 11+) 或反射(较旧的 Android)加载资源来源:app/shared/src/main/java/com/topjohnwu/magisk/StubApk.java57-85 app/shared/src/main/java/com/topjohnwu/magisk/utils/DynamicClassLoader.java1-65
DynamicClassLoader 扩展了 Android 的 BaseDexClassLoader,为动态加载的 APK 提供自定义类加载机制。
DynamicClassLoader 在加载类时遵循特定顺序:
此顺序可确保正确的类解析,同时优先考虑来自动态加载的 APK 的类。
来源:app/shared/src/main/java/com/topjohnwu/magisk/utils/DynamicClassLoader.java23-46
Magisk 应用包含一个用于自我更新和以编程方式安装其他 APK 的机制。
APKInstall 工具使用 Android 的 PackageInstaller API 创建安装会话。
此系统允许 Magisk 应用:
来源:app/shared/src/main/java/com/topjohnwu/magisk/utils/APKInstall.java1-175
为了避免被检测,Magisk 应用采用了复杂的混淆技术来处理其 Android 组件。
Magisk 构建系统会为 Android 组件生成随机名称,以避免通过组件名称匹配进行检测。
构建系统
来源:buildSrc/src/main/java/Codegen.kt73-181
在构建过程中,Magisk 会生成一个带有随机组件名称的 manifest。
Manifest 包含随机打乱的组件:
来源:buildSrc/src/main/java/Codegen.kt98-181
为了进一步保护应用程序免受分析,Magisk 构建系统会加密资源。
在运行时,存根应用程序会:
来源:buildSrc/src/main/java/Codegen.kt231-261
存根 APK 系统维护着某些数据结构,以促进存根与完整应用程序之间的通信。
| 索引区 | 目的 | 类型 | 描述 |
|---|---|---|---|
| 0 | STUB_VERSION | 整数 | 存根 APK 的版本 |
| 1 | CLASS_COMPONENT_MAP | Map<String, String> | 将类名映射到组件名称 |
| 2 | ROOT_SERVICE | Class<?> | 根服务类 |
此数据结构允许存根应用程序正确路由意图并从完整应用程序加载正确的组件。
来源:app/shared/src/main/java/com/topjohnwu/magisk/StubApk.java95-119
在必要时(例如更新后),应用程序可以自行干净地重启。
此过程可确保在更新或配置更改后应用程序能够干净地重启。
来源:app/shared/src/main/java/com/topjohnwu/magisk/StubApk.java87-93
Android 应用程序作为主要用户界面与更广泛的 Magisk 系统集成。
Android 应用程序提供:
通过这些接口,Android 应用程序允许用户与运行在设备较低级别的核心 Magisk 系统进行交互。