本文档描述了 Magisk 中用于促进安全应用更新和实现应用隐藏机制的 Stub APK 系统。该系统允许 Magisk 在运行时动态加载完整的应用程序代码,同时保持最小的占用空间。有关应用如何隐藏自身以避免检测的信息,请参阅应用隐藏机制。
Stub APK 系统是 Magisk 架构中的关键组成部分,解决了两个主要挑战:
该系统通过安装一个最小的“Stub”APK 来工作,该 APK 包含足够的代码,可以在运行时从存储在应用私有数据目录中的外部 APK 文件动态加载和执行完整的 Magisk 应用程序。
来源:app/shared/src/main/java/com/topjohnwu/magisk/StubApk.java app/shared/src/main/java/com/topjohnwu/magisk/utils/DynamicClassLoader.java
Stub APK 包含最小的组件,这些组件实现 Android 的应用程序生命周期,同时将实际功能委托给动态加载的完整 APK。
来源:app/shared/src/main/java/com/topjohnwu/magisk/StubApk.java app/shared/src/main/java/com/topjohnwu/magisk/utils/DynamicClassLoader.java
Stub APK 系统管理应用程序数据目录中的两个关键 APK 文件:
这些文件通过 StubApk 类中的实用方法进行管理
| 方法 | 描述 |
|---|---|
current(Context) | 返回当前活动 APK 的文件引用 |
update(Context) | 返回待处理更新 APK 的文件引用 |
restartProcess(Activity) | 重启应用程序以应用更新 |
来源:app/shared/src/main/java/com/topjohnwu/magisk/StubApk.java42-56
Stub APK 系统的核心功能是通过自定义类加载器实现的,该加载器可以从外部 APK 文件加载类。
DynamicClassLoader 类扩展了 Android 的 BaseDexClassLoader 以实现自定义类加载行为
类加载顺序如下:
来源:app/shared/src/main/java/com/topjohnwu/magisk/utils/DynamicClassLoader.java23-46
Stub APK 系统还负责动态加载外部 APK 中的资源
对于 Android 11+ (API 30+),系统使用 ResourcesLoader API,而较旧的 Android 版本则通过反射使用 addAssetPath 方法。
来源:app/shared/src/main/java/com/topjohnwu/magisk/StubApk.java58-85 app/shared/src/main/java/com/topjohnwu/magisk/utils/DynamicClassLoader.java48-64
Stub APK 系统依赖于构建时代码生成,以创建具有混淆名称的必要组件,从而增强安全性并逃避检测。
在构建过程中,会生成具有随机名称的几个关键组件:
来源:buildSrc/src/main/java/Codegen.kt75-181 buildSrc/src/main/java/Codegen.kt185-229
构建系统会修改 Android Manifest 以包含用作占位符的随机化组件
manifest updater
这种方法有助于 Magisk 逃避安全扫描器寻找特定组件签名的检测。
来源:buildSrc/src/main/java/Codegen.kt95-180 buildSrc/src/main/java/Codegen.kt185-228 buildSrc/src/main/java/Codegen.kt25-59
构建系统使用一种复杂的方法来生成随机但有效的 Java 类名
随机化在 CI 构建中使用固定种子以保证可重现性,而在本地构建中使用随机种子以增加变异性。
来源:buildSrc/src/main/java/Codegen.kt185-228 buildSrc/src/main/java/Codegen.kt25-59
为了保护敏感资源,Stub APK 系统在构建过程中加密资源文件
加密的资源将在运行时根据应用程序需要进行解密。
来源:buildSrc/src/main/java/Codegen.kt231-261
Stub APK 系统为处理更新实现了特定的流程
update.apkcurrent.apk 替换为 update.apkcurrent.apk 的新代码进行加载restartProcess() 方法通过以下方式确保干净重启:
来源:app/shared/src/main/java/com/topjohnwu/magisk/StubApk.java87-93
StubApk.Data 内部类管理关键的映射信息,将 Stub 组件连接到实际实现
这种映射允许 Stub APK 将功能委托给动态加载的 APK 中的正确实现类。
| 字段 | 目的 |
|---|---|
STUB_VERSION | 跟踪 Stub 实现的版本 |
CLASS_COMPONENT_MAP | 将真实组件类名映射到 Stub 组件名称 |
ROOT_SERVICE | 指向 root 服务类的引用 |
来源:app/shared/src/main/java/com/topjohnwu/magisk/StubApk.java95-119
Stub APK 系统包含针对不同 Android 版本的特定处理
ResourcesLoader API这些适应性确保 Stub APK 系统在不同 Android 版本上一致运行。
来源:app/shared/src/main/java/com/topjohnwu/magisk/StubApk.java27-39 app/shared/src/main/java/com/topjohnwu/magisk/StubApk.java58-85
刷新此 Wiki
最后索引时间2025 年 4 月 18 日(c8a16b)