Magisk 模块系统提供了一个框架,通过用户安装的模块来扩展 Magisk 的功能。本页将介绍模块在 Magisk 环境中的结构、安装、加载和执行方式。有关开发自己的模块的信息,请参阅 模块开发。
模块系统允许在不修改实际系统文件的情况下进行系统修改,它利用了文件系统覆盖机制。这使用户能够在保持原始系统完整性的同时,增强他们的 Android 体验。
来源: native/src/core/module.cpp283-491 scripts/util_functions.sh634-739 native/src/core/scripting.cpp78-151
Magisk 模块以具有特定结构的 ZIP 文件形式分发
| 组件 | 类型 | 描述 |
|---|---|---|
module.prop | 文件 | 模块的元数据,包括 ID、名称、版本、作者 |
customize.sh | 脚本 | 可选的安装脚本,在模块安装过程中运行 |
system.prop | 文件 | 要注入系统属性的可选属性 |
sepolicy.rule | 文件 | 可选的自定义 SELinux 策略规则 |
post-fs-data.sh | 脚本 | 可选脚本,在早期启动阶段执行 |
service.sh | 脚本 | 可选脚本,在后期启动阶段执行 |
/system/ | 目录 | 要覆盖到 Android 系统上的文件 |
/zygisk/ | 目录 | Zygisk 模块功能的可选原生库 |
uninstall.sh | 脚本 | 卸载模块时执行的可选脚本 |
对于模块,特定的文件具有特殊功能
.replace 文件在目录中表示整个目录应被替换,而不是合并disable 文件表示模块当前已被禁用remove 文件标记模块将在下次启动时被移除update 文件是在模块被更新时创建的来源: scripts/util_functions.sh593-611 native/src/core/module.cpp95-122 scripts/module_installer.sh1-34
当安装模块 ZIP 时,该过程遵循以下步骤
来源: scripts/util_functions.sh634-739 scripts/module_installer.sh1-34
安装程序支持两种安装方法
install.sh 和模板回调customize.sh 以获得更大的灵活性安装过程中,模块将被放置在 /data/adb/modules/ 中,每个模块都有一个以模块 ID 命名的目录。
模块在启动过程中的多个阶段进行加载
在启动时,系统首先检查模块更新并准备要加载的模块
来源: native/src/core/module.cpp361-382 native/src/core/module.cpp403-457
模块脚本在启动过程的特定时间执行
| 脚本 | 执行计时 | 目的 |
|---|---|---|
post-fs-data.sh | 挂载 /data 之后 | 早期系统修改 |
service.sh | 后期启动(服务启动)期间 | 后期系统修改、后台服务 |
这些脚本以 root 权限在全局命名空间中运行,允许它们根据需要修改系统。
来源: native/src/core/scripting.cpp78-151
文件系统修改机制是模块系统的核心
来源: native/src/core/module.cpp18-24 native/src/core/node.hpp9-14 native/src/core/module.cpp127-186
系统使用节点树来表示文件系统结构,其中包含不同的节点类型
inter_node:基本目录节点tmpfs_node:需要虚拟化的目录(使用 tmpfs)module_node:来自模块、覆盖系统文件的文件root_node:分区根目录启动过程中,Magisk
这创建了一个分层视图,模块文件看起来像是替换了系统文件,但实际上并未修改它们。
Magisk 提供了几种管理模块的机制
可以通过在其目录中创建 disable 文件来禁用模块。被禁用的模块仍然已安装,但在启动时不会被加载。
来源: native/src/core/module.cpp415-417
模块可以通过两种方式移除
remove 文件(将在下次启动时移除)当使用 remove 文件移除模块时
uninstall.sh 是否存在,如果存在则执行它来源: native/src/core/module.cpp503-529 native/src/core/module.cpp406-413
模块更新由以下方式处理
/data/adb/modules_update/来源: native/src/core/module.cpp361-385
Zygisk 是模块系统的一个特殊扩展,它允许模块将代码注入到应用程序进程中
当模块包含 Zygisk 组件时
/zygisk/ 目录中Zygisk 模块可以通过提供不同的库来支持多种架构
/zygisk/arm64-v8a.so 用于 64 位 ARM 设备/zygisk/armeabi-v7a.so 用于 32 位 ARM 设备/zygisk/x86_64.so 用于 64 位 x86 设备/zygisk/x86.so 用于 32 位 x86 设备来源: native/src/core/module.cpp214-233 native/src/core/module.cpp426-446 native/src/core/zygisk/entry.cpp1-121
模块系统与多个其他 Magisk 组件进行交互
启动过程在特定阶段触发模块加载
post-fs-data:挂载 /data 可用后的早期阶段late_start:服务启动时的后期阶段来源: native/src/core/daemon.rs156-166 native/src/core/daemon.rs185-218
模块文件会打上适当的 SELinux 上下文标签
u:object_r:system_file:s0u:object_r:vendor_file:s0自定义 SELinux 规则,源自模块(sepolicy.rule),用于确保模块正常运行。
来源:scripts/util_functions.sh593-608
黑名单系统可以阻止特定应用程序检测或使用 Magisk,这会影响模块在这些应用程序中的运行方式。
来源:native/src/core/deny/utils.cpp33-440
有关开发 Magisk 模块的详细信息,请参阅 模块开发。
模块开发者需重点考虑的事项
customize.sh 进行安装逻辑处理