模块开发指南
更新: 7/8/2025字数: 0 字时长: 0 分钟
对于大部分内容,SakitinSU 与Magisk
和KernelSU
基本保持一致,此处仅介绍不同之处。
TIP
如果将 SakitinSU 仅用于其他 root 实现的模块管理器,那么模块标准应当以当前 root 实现为准,SakitinSU不会干涉其他 root 实现的任何行为
但模块的WebUI 需要考虑到 SakitinSU 的模块 WebUI
IMPORTANT
请确保模块内的所有文本文件均使用UNIX (LF)
换行类型,而不是Windows (CR + LF)
或Macintosh (CR)
!
Systemless[1]
SakitinSU 的 Systemless 是一种类似于 Magisk 的挂载机制,其接口完全兼容 Magisk,例如.replace
用法。但 SakitinSU 的挂载机制兼容性更强。是基于动态识别分区实现的。也就是说,模块可以直接通过 Systemless 挂载例如odm
以及其他 root 实现无法挂载的分区,无需为此而付出额外的心血。
并且,为了保证更强的安全性,SakitinSU 的 Systemless 会无视模块挂载的文件/目录的 SELinux 上下文、目录的权限以及文件/目录的用户/组,如果文件挂载到了不存在的目录,那么其SELinux 上下文、权限、用户/组均会继承自父目录。通常来说,这些行为不会影响模块的运行,反而有助于提高稳定性。
TIP
SakitinSU 的 Systemless 会使用模块目录中的systemless
文件夹执行挂载,如果模块通过system
文件夹使用 Systemless,那么systemless
文件夹会被自动创建
如果模块仅适配 SakitinSU,那么可以直接通过systemless
文件夹使用 Systemless
Shell
SakitinSU 在此处与其他 root 实现有较大差异,SakitinSU 运行的 Shell 脚本默认并不在BusyBox
中以 “独立模式” 运行。
为了提升 Shell 脚本开发的便利性,SakitinSU 使用sush(用 Rust 编写的Bash
) 运行 Shell 脚本,并且优先使用uutils(用 Rust 编写的coreutils
) 的命令集,以 Magisk 的 BusyBox 作为替补。也就是说,命令优先从 uutils 获取,没有的命令才会从 BusyBox 获取。
由于并不在 BusyBox 中以 “独立模式” 运行,命令都是通过PATH
环境变量注入的,请勿在模块的 Shell 脚本内硬编码修改PATH
!
环境变量
为了便于区分,SakitinSU 在模块运行时注入以下变量:
SSU
(布尔值): 在 SakitinSU 环境下运行时,此值将为true
。但这并不能代表可以通过$SSU && # code ...
来执行代码,应当始终使用[ "$SSU" = true ]
或类似方法来检测 SakitinSUSSU_VER
(字符串): SakitinSU 的版本号 (不包括补丁号)SSU_VER_CODE
(整数值): SakitinSU 的纯数字版本号 (包括补丁号)
Recovery
SakitinSU 不支持通过 Recovery 安装模块,并且在模块安装时META-INF/com/google/android/update-binary
中的代码不会被执行。
SU 调用
SakitinSU 的 SU 实现默认附带了一个仅能用于直接执行 Shell 命令的sudo
,可以直接通过sudo
来执行例如sudo ls /
。
sudo
仅作为一个简易的su -c
替代品而存在,但是任何模块内都不应该通过sudo
或su -c
执行 Shell 命令!
同样的,任何模块也不应该通过硬编码来获取命令,例如/data/adb/ssu/bin/busybox crond
,因为无论是在 BusyBox 的 “独立模式” 还是直接通过PATH
注入命令,命令都已经可以直接调用,无需任何硬编码的手动获取行为。
ANSI 转义码[2]
SakitinSU 允许在module.prop
或 Shell 脚本中使用ANSI 转义码
来丰富文本的显示,例如可在module.prop
使用如下代码:
id=ssu_cmd_ext
name=Command Set Extension
version=Auto-generated by SSU
versionAnsi=\e[1mAuto-generated\e[0m by SSU
versionCode=1
author=SSU Developers (OOM. WG.)
description=Add coreutils, busybox, and bash to /system/bin.
descriptionAnsi=Add \e[1mcoreutils, busybox, and bash\e[0m to \e[1m/system/bin\e[0m.
使用如上module.prop
后,模块在 SakitinSU 管理器中显示时Auto-generated
、coreutils, busybox, and bash
以及/system/bin
均会被加粗。
在module.prop
中,可使用nameAnsi
、versionAnsi
、authorAnsi
以及descriptionAnsi
来显示包含 ANSI 转义码的文本。
虽然不包含Ansi
后缀同样可以使用,但是为了确保兼容性,请这么做。
SakitinSU 是通过顺序解析来读取module.prop
中的内容的,所以请确保包含Ansi
后缀的值是靠后的。展开查看渲染效果
模块 WebUI
SakitinSU 与KernelSU
同样允许模块使用 WebUI 提供功能,详见模块 WebUI。
module.prop
SakitinSU 管理器有一个机制用来检测module.prop
是否损坏或符合规范,如果损坏或不符合规范,SakitinSU 管理器会在该模块的上方显示一个标签。
WARNING
有些模块会使用sed
命令来修改module.prop
以实现实时更新内容,但此方法有一定概率会导致module.prop
文件损坏,请避免通过sed
修改或者通过其他方式来显示实时内容,也可以实现一个module.prop
损坏检测机制,在其损坏时恢复至默认内容
SakitinSU 管理器具体会检测如下内容:
module.prop
内是否包含不符合语法的内容id
、name
、version
、author
、description
是否为空 (如有带有Ansi
后缀的同样检测)id
是否符合此正则表达式:^[a-zA-Z][a-zA-Z0-9._-]+$
versionCode
是否大于0module.prop
内是否存在大小写不规范的情况 (SakitinSU 管理器会正常解析,但仍会显示标签)
如果只是module.prop
损坏,重装模块通常可解决此问题,如果不符合规范,则需要开发者自行修复以解决此问题。
内核接口
SakitinSU 使用/data/adb/ssu/._settings
作为内核设置目录,通常包含以下文件:
._su_list
: 授权使用超级用户权限的列表._bypass_list
: 绕过 SELinux 限制的列表._hide_list
: 需要隐藏 root 使用痕迹的列表
以上文件均采用二进制 UID
(32 位整数) +\0
+软件包名
格式存储,多个值之间以\n
间隔
IMPORTANT
以上文件均为只读,任何模块/软件都不应该修改 SakitinSU 的内核配置文件,仅 SakitinSU 管理器有修改权限!
其他模块/软件修改理应无效,SakitinSU 会在后续更新中逐步添加对内核配置文件写入的限制
其他差异
SakitinSU 会在后续更新中提供模块备份接口、模块更新接口 (在更新时执行原本模块的代码)、模块存储接口等功能,这些内容尚在规划中,会在后续更新中推出。