本指南涵盖 Magisk 模块的开发——这些组件允许开发者修改 Android 系统行为和文件,而无需永久性地更改底层系统分区。有关安装 Magisk 本身或从源代码构建 Magisk 的信息,请参阅 从源代码构建 和 安装。
Magisk 模块通过受控的文件覆盖系统、自定义脚本、系统属性修改和代码注入功能,提供了强大的自定义 Android 设备的框架。本文档将详细介绍如何创建、打包和分发 Magisk 模块。
来源: docs/guides.md16-79 docs/details.md38-74
Magisk 模块是一个位于 /data/adb/modules 的文件夹,具有特定的结构。文件夹名称对应模块的唯一 ID。
/data/adb/modules
├── $MODID <--- The folder is named with the ID of the module
│ │
│ │ *** Module Identity ***
│ │
│ ├── module.prop <--- Stores the metadata of the module
│ │
│ │ *** Main Contents ***
│ │
│ ├── system <--- Files to be overlaid on /system
│ │ ├── ...
│ │ ├── ...
│ │ └── ...
│ │
│ ├── zygisk <--- Zygisk native libraries for code injection
│ │ ├── arm64-v8a.so
│ │ ├── armeabi-v7a.so
│ │ ├── riscv64.so
│ │ ├── x86.so
│ │ ├── x86_64.so
│ │ └── unloaded <--- Indicates incompatible libraries
│ │
│ │ *** Status Flags ***
│ │
│ ├── skip_mount <--- If exists, system folder won't be mounted
│ ├── disable <--- If exists, module will be disabled
│ ├── remove <--- If exists, module will be removed next reboot
│ │
│ │ *** Optional Files ***
│ │
│ ├── post-fs-data.sh <--- Executed in post-fs-data stage
│ ├── service.sh <--- Executed in late_start service stage
│ ├── uninstall.sh <--- Executed when module is removed
│ ├── action.sh <--- Executed when action button is clicked in app
│ ├── system.prop <--- Properties loaded as system properties
│ ├── sepolicy.rule <--- Custom sepolicy rules
│ │
│ │ *** Auto Generated Symlinks ***
│ │
│ ├── vendor <--- Symlink to $MODID/system/vendor
│ ├── product <--- Symlink to $MODID/system/product
│ ├── system_ext <--- Symlink to $MODID/system/system_ext
module.prop 文件以严格的格式定义了模块的元数据
id=<string>
name=<string>
version=<string>
versionCode=<int>
author=<string>
description=<string>
updateJson=<url> (optional)
要求
id 必须匹配正则表达式:^[a-zA-Z][a-zA-Z0-9._-]+$versionCode 必须是整数updateJson URL 提供 JSON 格式的更新信息更新 JSON 格式
Magisk 模块安装程序是一个 zip 文件,可以通过 Magisk 应用或自定义 Recovery 来刷入。最小结构是:
module.zip
│
├── META-INF <--- Only needed for flashing in recovery
│ └── com
│ └── google
│ └── android
│ ├── update-binary <--- The module_installer.sh script
│ └── updater-script <--- Should only contain "#MAGISK"
│
├── customize.sh <--- Optional customization script
│
├── ... <--- Module files
├── ...
来源: docs/guides.md141-165 scripts/module_installer.sh1-34
来源: scripts/util_functions.sh634-739 scripts/module_installer.sh1-34
customize.sh 脚本允许自定义安装过程。在文件解压后,安装程序会调用它。
可用变量
MAGISK_VER:Magisk 版本字符串(例如:v20.0)MAGISK_VER_CODE:Magisk 版本代码(例如:20000)BOOTMODE:如果在 Magisk 应用中安装,则为 trueMODPATH:模块文件安装的路径TMPDIR:安装的临时目录ZIPFILE:模块 zip 文件的路径ARCH:CPU 架构(arm, arm64, x86, x64, 或 riscv64)IS64BIT:如果 $ARCH 是 64 位,则为 trueAPI:Android API 级别可用函数
ui_print <msg>:将消息打印到控制台abort <msg>:打印错误消息并终止安装set_perm <target> <owner> <group> <permission> [context]:设置权限set_perm_recursive <dir> <owner> <group> <dirperm> <fileperm> [context]:设置递归权限您可以使用 REPLACE 和 REMOVE 变量指定要替换或删除的目录
要完全控制安装过程,请在 customize.sh 中设置 SKIPUNZIP=1,以便自行处理解压。
system 文件夹是大多数模块的核心,包含要覆盖到真实 /system 分区的文件。覆盖过程遵循以下规则:
system 文件夹中的文件会替换真实系统中的同名文件.replace 文件放在目录中将替换整个目录,而不是合并mknod <path> c 0 0 创建一个虚拟字符设备例如,替换 YouTube 应用
module/system/app/YouTube/.replace
module/system/app/YouTube/YouTube.apk
移除系统应用
# In customize.sh
mknod $MODPATH/system/app/Bloatware c 0 0
模块可以在启动过程的两个阶段运行脚本
post-fs-data 模式(post-fs-data.sh)
setprop 会导致启动死锁;请改用 resetprop -nlate_start service 模式(service.sh)
所有启动脚本都在 Magisk 的 BusyBox ash shell 中运行,并启用了“独立模式”。
在脚本中,使用 MODDIR=${0%/*} 来获取模块的基础目录路径。如果启用了 Zygisk,则环境变量 ZYGISK_ENABLED 将设置为 1。
来源: docs/guides.md114-117 docs/guides.md244-270
system.prop 文件允许模块修改系统属性。每行都遵循 key=value 格式,类似于 build.prop。
示例
# Disable signature verification
ro.secure=0
ro.debuggable=1
属性由 Magisk 的 resetprop 工具加载,该工具甚至可以修改只读属性。
可以通过 sepolicy.rule 文件添加自定义 SELinux 策略规则。每行都是一个策略语句,由 magiskpolicy 处理。
示例
allow appdomain app_data_file file { read write open getattr }
allowxperm untrusted_app self capability_service_ipc ioctl 0x0000
来源: docs/guides.md138-140 docs/tools.md156-232
Zygisk 允许模块在每个 Android 应用进程内部运行代码。对于 Zygisk 支持:
zygisk 文件夹中,并使用适当的名称arm64-v8a.soarmeabi-v7a.soriscv64.sox86.sox86_64.so当 Zygisk 模块不兼容时,在 zygisk 目录中创建一个名为 unloaded 的空文件。
遵循最小修改原则:
.replace正确处理权限:
set_perm 和 set_perm_recursive0755 权限脚本优化:
service.shpost-fs-data.sh跨设备兼容性:
启动循环原因:
安装错误:
更新问题:
来源: docs/guides.md1-15 docs/faq.md1-17
这是一个结构良好的 Magisk 模块的完整示例
example_module/
├── META-INF/
│ └── com/
│ └── google/
│ └── android/
│ ├── update-binary # module_installer.sh script
│ └── updater-script # Contains only "#MAGISK"
├── customize.sh # Custom installation logic
├── module.prop # Module metadata
├── post-fs-data.sh # Early boot script (if needed)
├── service.sh # Main boot script
├── system.prop # System properties to modify
├── sepolicy.rule # SELinux policy rules
├── system/ # System modifications
│ ├── app/
│ │ └── ModifiedApp/
│ │ ├── .replace # Replace entire directory
│ │ └── ModifiedApp.apk # Replacement APK
│ ├── bin/
│ │ └── custom_binary # Added binary
│ └── etc/
│ └── custom_config # Configuration file
├── zygisk/ # Zygisk support (optional)
│ ├── arm64-v8a.so # Architecture-specific libraries
│ ├── armeabi-v7a.so
│ ├── x86.so
│ └── x86_64.so
└── uninstall.sh # Cleanup when module is removed
可以通过以下方式安装模块:
Magisk 应用:安装模块的推荐方式
自定义 Recovery:传统方法(不推荐用于现代设备)
来源: docs/guides.md16-77 scripts/util_functions.sh634-739
Magisk 模块提供了一个强大的框架,可以在不进行永久性系统修改的情况下定制 Android 设备。在开发模块时,请关注
遵循这些指南,您可以创建能够增强 Android 功能同时保持系统稳定性和安全的模块。