Magisk模块常用功能编写

2022-11-14 14:03:13 浏览数 (1)

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,也提供了国内大多数机型的刷机工具和教程,你值得拥有。

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

  • 恒创互联云盘 网页链接  (密码:wzsx150)

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

刷入 Magisk

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

关于Root权限

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

获取 Root 权限

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

代码语言:javascript复制
$ adb rootadbd cannot run as root in production builds

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

代码语言:javascript复制
$ adb shell
cereus:/ $ su
cereus:/ #

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

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

代码语言:javascript复制
$ adb shell su -c 'ls /data/data/'
android
android.ext.services
android.ext.shared
...

或者用管道实现:

代码语言:javascript复制
$ 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 中主要用于编写安装时执行的脚本,这里的脚本能够执行adb shell 中的指令。需要注意的是这个脚本只在安装过程中执行,重启后不会再次执行。
  2. 启动后台服务的地方放在 post-fs-data.sh 或者  service.sh 中;区别在于系统会阻塞等待 post-fs-data.sh 执行完,而 service.sh 则会与系统并发执行(常用于启动一些服务)。比较坑的是,这两个脚本使用的上下文是 magisk 自带的 busybox,因此在执行 adb shell 中的一些指令时,一定要使用绝对路径
  3. post-fs-data.sh 和  service.sh 在每次系统重启后都会执行。
  4. 修改 ro 开头的配置放在system.prop 中,其他配置可以直接用setprop 命令。
  5. 注意给文件正确的权限。

红米6的实践

开启adb安全模式

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

代码语言:javascript复制
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=")[^"]*(")|1true2|g' $remote_provider_preferences
  ui_print "- Change security_adb_install_enable to true"
fi

取消USB安装的确认框

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

代码语言:javascript复制
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=")[^"]*(")|1false2|g' $remote_provider_preferences
  ui_print "- Change permcenter_install_intercept_enabled to false"
fi

一些页面优化

代码语言:javascript复制
# 取消相关动画
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 中写一个自动关闭脚本:

代码语言:javascript复制
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

自动设置PTP

又由于一些未知原因,手机在重启后总是默认充电模式,导致无法自动连接 adb 。经实践发现把连接模式强制设置为 PTP 模式可以解决,因此我们也可以在 service.sh 中加入如下自动设置脚本:

代码语言:javascript复制
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。

刷TWRP后无限重启

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

代码语言:javascript复制
$ 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

0 人点赞