Magisk 是目前最流行的安卓手机 root 解决方案。
虽然像小米等手机厂商也提供了所谓支持 root 的开发版 Rom,但在较新的版本中,他们无法直接写入像 /system/
之类的被保护的路径。这就导致了很多事情仍然做不了。最经典的就是连系统证书都修改不了。。。
而 Magisk 能避免写入被保护的路径,将自己的文件系统 “Mask” 在原生的文件系统上。这样既不需要直接修改的原始的数据,也能骗过程序使用 Magisk 提供的文件系统。
令人感叹的是 Magisk 的作者 topJohnWu 在发布项目的时候只是一名大二的学生,目前就职于 Apple 做机器翻译。
Magisk之所以火,很大程度上还是由于大家可以贡献自己的创造力分享自己写的Magisk模块。但是在使用别人的模块时还是要小心再小心。
官方的仓库其实只有 https://github.com/Magisk-Modules-Repo 这个由 JohnWu 自己维护的。这里的模块基本都可以放心使用。当然市面上也有各种其他的 Magisk 仓库,但是用这些的时候还是要先认真读一下代码吧。。。
TWRP相关的信息可以在官网和一个非官方社区中搜索对应机型,并按照说明进行刷机。
当然,很大概率,这两个国外网站的信息可能不太适合社会主义国情,如果刷机失败了也不要灰心。国内的 @wzsx150 所在的 L.R.Team 在官方的基础上做了改进和懒人包教程并支持了Android10,也提供了国内大多数机型的刷机工具和教程,你值得拥有。
目前他们提供的相关内容在这里:
最后需要注意的是,如果在刷入TWRP完成后手机重启前,没有通过 TWRP 安装一些如第三方rom(如Magisk或SuperSU),那么手机重启后,TWRP就会被原生recovery重新覆盖。。。
在刷入 TWRP 进入新的 recovery后,就可以刷入 Magisk了。安装 Magisk 的步骤可以参考官方文档。
通过 Magisk 可以获得有 root 权限的 shell,但是这个 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 权限,就必须要通过自己编写 Magisk 模块,在启动的时候准备好需要覆盖的文件,像 Mask 一样加载进系统。
编写标准的 Magisk 模块建议直接参考 官方文档,这里不再赘述。需要注意的是 Magisk 模块的结构有过一次调整,因此存在新老两种模块的文件结构。当然新版的Magisk对这两种写法都做了兼容,但还是建议用新的写法。
如果需要学习自定义模块的写法,建议参考下面两个模块:
另外还有几个注意点(新版写法):
customize.sh
中主要用于编写安装时执行的脚本,这里的脚本能够执行adb shell 中的指令。需要注意的是这个脚本只在安装过程中执行,重启后不会再次执行。post-fs-data.sh
或者 service.sh
中;区别在于系统会阻塞等待 post-fs-data.sh
执行完,而 service.sh
则会与系统并发执行(常用于启动一些服务)。比较坑的是,这两个脚本使用的上下文是 magisk 自带的 busybox,因此在执行 adb shell 中的一些指令时,一定要使用绝对路径。post-fs-data.sh
和 service.sh
在每次系统重启后都会执行。system.prop
中,其他配置可以直接用setprop
命令。小米开启adb安全模式默认需要登录小米账号,我们可以在 customize.sh
中修改配置绕过。
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
小米在开启MIUI优化后,通过USB安装app会有个确认框,我们可以在 customize.sh
中修改配置绕过。
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
命令中搜索相关的关键字。
由于未知原因,红米6 在刷入 Magisk 后必然会出现一个 "您的设备内部出现了问题。请联系您的设备制造商了解详情。" 的错误弹窗:
因此我们可以在 service.sh
中写一个自动关闭脚本:
dump_path=/data/local/tmp/dump.xml
for i in $(seq 1 10)
do
rm -f $dump_path
uiautomator dump $dump_path
grep -q '设备内部' $dump_path
if [ $? -eq 0 ];then
sleep 1
input tap 540 1270
rm -f $dump_path
sleep 1
uiautomator dump $dump_path
grep -q '设备内部' $dump_path
if [ $? -ne 0 ];then
echo "process done in $i times" >> $dump_path
break
fi
fi
sleep 10
done
又由于一些未知原因,手机在重启后总是默认充电模式,导致无法自动连接 adb 。经实践发现把连接模式强制设置为 PTP 模式可以解决,因此我们也可以在 service.sh
中加入如下自动设置脚本:
adb_log_path=/data/local/tmp/adb.log
for i in $(seq 1 10)
do
rm -f $adb_log_path
/system/bin/svc usb setFunction ptp true && /system/bin/svc usb getFunction &> $adb_log_path
sleep 5
done
考虑到启动加载顺序未知等原因,为了保险起见这里需要多循环执行几次,否则还是会有概率修改失败。。。
常在河边走哪能不湿鞋。理论上只要一直搞机下去,迟早有一天会把手机刷成砖。刷成砖不可怕,可怕的是刷成的砖连 recovery、fastboot 都进不去、连 adb 都连不上。如果是这样,那基本就是真砖了。
目前我遇到了两种刷假砖后急救的case。
对于 红米9 等机型,直接刷入 recovery 后可能会一直无限重启。这时候只需要下载 vbmet.img ( tar -xvf vbmeta.tar ) 并在 fastboot 模式下把这个也刷进去即可:
$ fastboot --disable-verity --disable-verification flash vbmeta vbmeta.img
乱装 Magisk 模块改配置是有概率导致手机无法正常开机的。但是只要还能进 recovery ,那八成还是有救的。Magisk 的模块默认是安装在 /data/adb/modules/
下的,只要在 recovery 下找到有问题的模块文件夹并删除重启,多半都是能救回来的。具体可以参考 How to Uninstall Magisk Modules Using TWRP Recovery。
How to Uninstall Magisk Modules Using TWRP Recovery
Install User Certificate Via ADB
Enable "Install via USB" without signing in to Xiaomi account