Magisk模块常用功能编写

Magisk简述

概述

Magisk 是目前最流行的安卓手机 root 解决方案。

虽然像小米等手机厂商也提供了所谓支持 root 的开发版 Rom,但在较新的版本中,他们无法直接写入像 /system/ 之类的被保护的路径。这就导致了很多事情仍然做不了。最经典的就是连系统证书都修改不了。。。

而 Magisk 能避免写入被保护的路径,将自己的文件系统 “Mask” 在原生的文件系统上。这样既不需要直接修改的原始的数据,也能骗过程序使用 Magisk 提供的文件系统。

令人感叹的是 Magisk 的作者 topJohnWu 在发布项目的时候只是一名大二的学生,目前就职于 Apple 做机器翻译。

模块仓库

Magisk之所以火,很大程度上还是由于大家可以贡献自己的创造力分享自己写的Magisk模块。但是在使用别人的模块时还是要小心再小心。

官方的仓库其实只有 https://github.com/Magisk-Modules-Repo 这个由 JohnWu 自己维护的。这里的模块基本都可以放心使用。当然市面上也有各种其他的 Magisk 仓库,但是用这些的时候还是要先认真读一下代码吧。。。

Magisk安装

刷 TWRP

TWRP相关的信息可以在官网和一个非官方社区中搜索对应机型,并按照说明进行刷机。

当然,很大概率,这两个国外网站的信息可能不太适合社会主义国情,如果刷机失败了也不要灰心。国内的 @wzsx150 所在的 L.R.Team 在官方的基础上做了改进和懒人包教程并支持了Android10,也提供了国内大多数机型的刷机工具和教程,你值得拥有。

目前他们提供的相关内容在这里:

最后需要注意的是,如果在刷入TWRP完成后手机重启前,没有通过 TWRP 安装一些如第三方rom(如Magisk或SuperSU),那么手机重启后,TWRP就会被原生recovery重新覆盖。。。

刷入 Magisk

在刷入 TWRP 进入新的 recovery后,就可以刷入 Magisk了。安装 Magisk 的步骤可以参考官方文档

关于Root权限

通过 Magisk 可以获得有 root 权限的 shell,但是这个 root 权限依然是受限的。

获取 Root 权限

和原生的开发版不同,刷入 Magisk 的设备无法使用 adb root 这样的命令:

$ adb rootadbd cannot run as root in production builds

但是可以在进入 shell 后登入root 用户:

$ adb shell
cereus:/ $ su
cereus:/ #

当然,这需要在 Magisk 弹出的窗口中点击授权:

如果不想用交互式指令,则可以用 -c 参数:

$ adb shell su -c 'ls /data/data/'
android
android.ext.services
android.ext.shared
...

或者用管道实现:

$ echo 'ls /data/data/'|adb shell su
android
android.aosp.overlay
android.ext.services
android.ext.shared
...

不足之处

看起来我们可以在shell中直接获得root权限,但是当你修改了 /system 等目录下的文件后,你的所有变更在下次重启之后都会丢失。

因此这个 root 权限其实更像是一个 readonly 的root,并不是一个通用的 root。这个当然也并不是一无是处,在查看一些系统文件的时候还是很有帮助的。

持久化的 Root

要想获得真正的、能持久化的写文件的 Root 权限,就必须要通过自己编写 Magisk 模块,在启动的时候准备好需要覆盖的文件,像 Mask 一样加载进系统。

Magisk模块编写

基础知识

编写标准的 Magisk 模块建议直接参考 官方文档,这里不再赘述。需要注意的是 Magisk 模块的结构有过一次调整,因此存在新老两种模块的文件结构。当然新版的Magisk对这两种写法都做了兼容,但还是建议用新的写法。

如果需要学习自定义模块的写法,建议参考下面两个模块:

  • v2ray 模块,用的是新模块写法,用于启动一个系统维度的 v2ray 服务(用于科学上网)。
  • movecert 模块,用的是老模块的写法,用于将用户证书移动到系统证书的路径下,使系统默认信任用户证书。

另外还有几个经验点(新版写法):

  1. 静态的一次性操作建议放在customize.sh 中;启动后台服务的地方放在service.sh 中;修改 ro 开头的配置放在system.prop 中,其他配置可以直接用setprop 命令。
  2. 注意给文件正确的权限。

红米6的实践

以下代码放在 customize.sh中。

开启adb安全模式

小米开启adb安全模式默认需要登录小米账号,我们可以修改配置绕过。

remote_provider_preferences=/data/data/com.miui.securitycenter/shared_prefs/remote_provider_preferences.xml
 
grep -q 'security_adb_install_enable' $remote_provider_preferences
 
if [ $? -ne 0 ] ;then
  sed -i 's/<\/map>/<boolean name="security_adb_install_enable" value="true" \/>\n<\/map>/g' $remote_provider_preferences
  ui_print "- Insert security_adb_install_enable to true"
else
  sed -i '/security_adb_install_enable/ s|\([vV]alue="\)[^"]*\("\)|\1true\2|g' $remote_provider_preferences
  ui_print "- Change security_adb_install_enable to true"
fi
 

取消USB安装的确认框

小米在开启MIUI优化后,通过USB安装app会有个确认框,我们可以通过修改配置绕过。

remote_provider_preferences=/data/data/com.miui.securitycenter/shared_prefs/remote_provider_preferences.xml
 
grep -q 'permcenter_install_intercept_enabled' $remote_provider_preferences
if [ $? -ne 0 ] ;then
  sed -i 's/<\/map>/<boolean name="permcenter_install_intercept_enabled" value="false" \/>\n<\/map>/g' $remote_provider_preferences
  ui_print "- Insert permcenter_install_intercept_enabled to false"
else
  sed -i '/permcenter_install_intercept_enabled/ s|\([vV]alue="\)[^"]*\("\)|\1false\2|g' $remote_provider_preferences
  ui_print "- Change permcenter_install_intercept_enabled to false"
fi

一些页面优化

# 取消相关动画
settings put global window_animation_scale 0.0
ui_print "- Change window_animation_scale to 0"
 
settings put global transition_animation_scale 0.0
ui_print "- Change transition_animation_scale to 0"
 
settings put global animator_duration_scale 0.0
ui_print "- Change animator_duration_scale to 0"
 
# 保持开机状态
settings put global stay_on_while_plugged_in 7
ui_print "- Change stay_on_while_plugged_in to 7"
 
# 屏幕方向锁定
settings put system accelerometer_rotation 0
ui_print "- Change accelerometer_rotation to 0"
 
settings put system user_rotation 0
ui_print "- Change user_rotation to 0"
 
# ADB 配置
setprop persist.security.adbinput 1
ui_print "- Change persist.security.adbinput to 1"
 
setprop persist.security.adbinstall 1
ui_print "- Change persist.security.adbinstall to 1"
 

如果有一些其他配置需要统一修改,建议将手机的语言调成英文,然后在安卓源码或者 getprop settings 命令中搜索相关的关键字。

刷砖急救

常在河边走哪能不湿鞋。理论上只要一直搞机下去,迟早有一天会把手机刷成砖。刷成砖不可怕,可怕的是刷成的砖连 recovery、fastboot 都进不去、连 adb 都连不上。如果是这样,那基本就是真砖了。

目前我遇到了两种刷假砖后急救的case。

刷TWRP后无限重启

对于 红米9 等机型,直接刷入 recovery 后可能会一直无限重启。这时候只需要下载 vbmet.img ( tar -xvf vbmeta.tar ) 并在 fastboot 模式下把这个也刷进去即可:

$ fastboot --disable-verity --disable-verification flash vbmeta vbmeta.img

装了第三方Magisk模块后无限重启

乱装 Magisk 模块改配置是有概率导致手机无法正常开机的。但是只要还能进 recovery ,那八成还是有救的。Magisk 的模块默认是安装在 /data/adb/modules/ 下的,只要在 recovery 下找到有问题的模块文件夹并删除重启,多半都是能救回来的。具体可以参考 How to Uninstall Magisk Modules Using TWRP Recovery

参考资料

Developer Guides | Magisk

每个 Android 玩家都不可错过的神器

How to Uninstall Magisk Modules Using TWRP Recovery

Install User Certificate Via ADB

Enable "Install via USB" without signing in to Xiaomi account