2024 年 9 月 26 日更新:增加了 Mix 7 的 64 位系统更新发布后的操作注意事项。
背景
墨案 Mix 7 是一部在设备正面配备了两枚实体按键的墨水屏阅读器。其外型类似Kindle Oasis,但使用极为先进 USB Type-C 接口进行充电和数据传输。尽管标榜开放系统,但是一部运行32位系统的设备在当下64位优先的局势下很难保证一个光明的未来,因此自己动手获取 root 权限或者安装第三方系统给设备续命就是不可或缺的操作了。
几年前设备刚到手的时候我就搜索过 Mix 7 解锁和 root 的相关内容,不知道是销量太低还是大家真的觉得这玩意挺开放又或者是这种小操作简单到不值一提,结果一无所获。我带着一丝遗憾关掉了浏览器,装上几个实用 app 就开始看书了。如今到了2024年,Android 15 发布在即,墨案也推出了 Mix 7 的屏幕换代产品,Mix 7 那自发布以来就没合并过安全补丁的 OTA 亦杳无音讯,已然成为了一枚弃子。我从包里拿出 Mix 7,连上数据线,没有打开MTP传书,而是打开了开发者选项菜单。看着第一屏最底下的“DSU Loader“,我感觉世界好像还给我留了一扇窗。
从头再来
重拾动力之后,当然是先打开谷歌搜一搜有没有人起的比我早,已经走完了该走的路。简单搜了一下,我感觉 Mix 7 的销量实际惨淡,还真就没有用户想着折腾一把写篇文章,这下只能从0开始了。 从机器本身开始分析。先说硬件,这是我唯一一部使用 Rockchip 芯片的设备,先前只在电视盒子和单片机的配置清单上听说过这个厂家,没什么头绪;再看软件,Android 11,内核版本 4.19,没有解锁、没有第三方 recovery、没有系统包、没有 root、有一个我从没用过的 DSU(Dynamic System Update) Loader。看似无计可施,只好见招拆招。
不同的人可能会对搞机一词有着不同的定义,但共通的目标是取得设备更多的控制权,激进派会用各种花里胡哨的图标、主题和字体让自己的设备看起来面目全非焕然一新,而保守派会说激进派实在是太过保守,拿不到root权限根本不算是搞机。我个人向来是折中的,所以我既要换字体也要拿 root。
目前主流的 root 方案有 Magisk 和 KernelSU 两种,较为年轻的 KernelSU 依赖谷歌的GKI项目,然而GKI 是一项复杂的更改,将从 Android 11 平台版本中的 v5.4 内核开始,分几个阶段逐步推出。我们出厂内核4.19的电纸书就与通往新世界的快车无缘了,还是看看远处的 Magisk 吧。在目前标准的 Magisk root 方案中,有两个步骤是不可或缺的,其一是解锁 bootloader,这是任何刷机操作的基础;其二是获取当前系统的 boot 分区镜像,这是 Magisk 需要 patch 的文件,由于网上并没有 OTA 更新包或者类似的镜像文件流传,这个部分只能我自己想办法获取。
空中充值
获取更新包最好的方法自然是利用OTA程序直接下载,不过正如前文所述,Mix 7 已经许久没有发布更新,具体来说上一次系统更新的编译时间是 2023 年 6 月 21 日。这意味着我无法直接复制设备上现成的更新包,唯一可行的利用方式就是在 PC 上伪造请求获取系统更新的下载链接。凭借浅薄的计算机网络应用知识,我又一次安装了 Fiddler Classic,简单配置下监听端口,打开 PC 热点,把板子连接到热点……这时我发现这个板子简洁的 WiFi 连接界面上只有一行密码输入框,这一个小小的问题已然超出了我的知识范围。直觉告诉我这个问题可以解决,但我还不想太早把这次探索变成一堂计算机网络实验课,于是我开始在设备存储里乱翻,希望能找到一点蛛丝马迹。
在内部存储中戳来戳去,戳到Android/data/
文件夹的时候发现了一个可疑的包名:com.abupdate.fota_demo_iot
,打开之后,发现里面的 cache 文件夹中两个 log 文件,打开检查内容,其中的请求链接全部指向https://iotapi.abupdate.com
。经过搜索得知域名所有者为”上海艾拉比智能科技有限公司“,其主营业务为”OTA产品和解决方案“,可以确定该日志确实为检查更新时输出的日志。虽然没能成功抓包,但现在也拿到了更新服务器的地址,可喜可贺。继续检查日志文件,虽然没有直接翻到更新包的下载链接,但也有一些用得上的内容。日志中记录了几类不同的请求,具体内容及推测用途如下:
- 检查更新错误后的行为报告。
2022-10-18 23:35:01.119 04113 PostJsonRequest: url:https://iotapi.abupdate.com/product/1621842168/3891fc8e6660b1ef/ota/reportBehavior 2022-10-18 23:35:01.124 04113 PostJsonRequest: { "mid": "■■■■■■■■■■", //本机序列号 "context": [ { "deltaId": "7691739", "status": 2003, "reason": "check failed", "recordTime": 1666107300 } ], "timestamp": 1666107301, "sign": "e1e6e5588476e604ee5e9bbe89681165" //不知道什么算法生成的签名 }
- 设备版本报告
2022-10-19 23:44:48.124 04118 PostJsonRequest: url:https://iotapi.abupdate.com/product/1621842168/3891fc8e6660b1ef/ota/productSettingInfo 2022-10-19 23:44:48.130 04118 PostJsonRequest: { "mid": "■■■■■■■■■■", "sdkversion": "2.0.7", "appversion": "2.1.20", "timestamp": 1666194288, "sign": "172333dc6bc38489408f669cab793493" }
3.检查更新
2022-10-19 23:44:48.426 04118 PostJsonRequest: url:https://iotapi.abupdate.com/product/1621842168/3891fc8e6660b1ef/ota/checkVersion 2022-10-19 23:44:48.430 04118 PostJsonRequest: { "mid": "■■■■■■■■■■", "version": "MAS_EPD108_L81B801_T49_V08", "networkType": "WIFI", "timestamp": 1666194288, "sign": "172333dc6bc38489408f669cab793493" }
尽管不知道具体算法,但可以观察到使用相同时间戳的不同请求也使用相同的签名,可以认为在同一设备上,签名的变化只与时间戳相关,这意味着我可以修设备正常生成的请求,降低请求内容中记录的版本号来获取到新版本(当前版本)的下载链接。感觉有点难,等一会把设备成功解锁了再试。
二龙戏珠
在消费电子领域,任何一个问题都不会是完全孤立的问题。—我说的
那么,有没有一种方法可以在没有 root 权限和升级包的前提下获取到本机的 boot 分区镜像呢?办法当然有,只要你在本机上开出一个有 root 权限的 shell 就可以把 boot 分区 dd 出来。有人就要说了,我是因为没有 root 权限才来折腾这一套的,这段话真的就属于属于是了属于是。
作为一名普普通通的消费者,我碰到的每一个问题一定会有其他用户碰到,我能解决的问题一定已经有其他用户成功解决,如果问题没解决那就是问题的定义有问题,这就是消费主义带给我的自信!带着这样的自信,我再次打开浏览器,在输入框中写下“extract loot.img from device”(是的,我打搓自了,而且错得很离谱),搜索引擎返回的第二条便是这样一篇文章。文章不长,内容却很是实用,可以说完美解决了我的问题。
问:没有获取到本机 root 权限如何在本机提取用来获取 root 权限的 boot 分区镜像?答:换一个有 root 权限的系统再提取。 问:没有第三方 recovery 怎么切换到第三方系统?答:用系统自带的DSU Loader。 问:真的吗?我不信。答:只需要解锁 bootloader 就能用。
没错,有了 DSU Loader,一切皆有可能。这样一来,只要能解锁 bootloader,一切就都会好起来的。
小病重启
按照通用刷机流程,首先尝试重启到 recovery 探探虚实,怎奈出师不利,电源和两个音量键怎么配合也没按出 recovery 与 fastboot ,只好乖乖从电脑上操作adb。我一个adb reboot fastboot
打上去,“啪”地一下回车,很快啊,屏幕一黑一白,就进入了 fastbootd。
来到 fastboot 自然是先敲一行fastboot flashing unlock
,然而终端里没有任何回显,也不知道解锁是否成功抑或设备压根就不支持解锁,鉴于我是只折腾过红米手机的低端 miboy,这么贴近自然的解锁指令还是第一次用,我就暂且蒙在鼓里。进入 recovery 界面,同样的原汁原味,但是该有的功能一个不缺。
抱着对厂家草台程度的期待,我尝试从 PC 上 adb sideload magisk.zip
,果不其然报了一个签名错误不给刷。看来系统外的操作就只能告一段落了。
重启回到系统,运行adb shell getprop
,检查 ro.boot.flash.locked
值,返回值为 0,使用第三方软件检查同样报告 bootloader 未锁定,鉴定为解锁成功。
一波三折
设备成功解锁,接下来就要准备 DSU了。首先按照文章介绍去下载了基于 LinageOS 且自带 root 权限的 GSI 镜像,再下载 DSU Sideloader ,最后解压镜像把文件扔到设备存储上。在传输文件的时候,不知为何进度条纹丝不动,过一会还自动取消,我百思不得其解,最后换了根数据线就好了,各位朋友在刷机时也务必多准备一根数据线以防万一。
万事俱备,只欠东风。文件就绪之后,DSU 的安装过程反倒没什么可说的,如果你想经常使用安装的 GSI 系统,就多分配些用户空间,两边的用户数据是相互隔离(?)的。漫长的等待后,在 PC 的终端里输入adb shell sh "/storage/emulated/0/Android/data/vegabobo.dsusideloader/files/install"
完成安装,最后点击通知里的重启按钮就大功告成了。
不出意外,意外发生了,不知道是选错了 GSI,还是墨水屏的驱动有什么 bug,重启之后屏幕就卡在了开机第一屏。由于墨水屏的特性,我甚至不知道设备是卡在了启动阶段还是单纯的显示问题。简单思考了一下,我从电脑上启动 scrcpy ,尝试获取到更具体的显示数据,却提示ERROR: Server connection failed
,又以为是 adb key 出了问题,开始着手复制电脑的公钥过去。做到一半才想起来:我是来拿 root 权限的,想传公钥就得需要 root 权限,我能拿到 root 权限为什么还要传公钥,不如早死早超生。一行adb shell
再接一个su
,事就这样成了。
最困难的部分已经解决,下一个步骤便是找到 boot 分区的位置并进行复制。这里使用前文链接中提供的脚本进行定位,粘贴进 root shell 运行即可:
for PARTITION in "boot" "boot_a" "boot_b"; do
BLOCK=$(find /dev/block ( -type b -o -type c -o -type l ) -iname "$PARTITION" -print -quit 2>/dev/null)
if [ -n "$BLOCK" ]; then
echo "$PARTITION" = $(readlink -f "$BLOCK")
fi
done
注:这段脚本复制自原文,为了不让文本糊成一坨,在每行间增加了一个换行符。
对于Mix 7 这样的 AB 分区设备,返回的值形式如下:
boot_a = /dev/block/mmcblk2p12 boot_b = /dev/block/mmcblk2p13
此时需要运行getprop ro.boot.slot_suffix
来确定当前使用的分区,命令输出为_a
或_b
。之后即可使用dd
命令复制对应后缀的分区到临时目录,生成 boot 分区镜像了。
# dd if=/dev/block/mmcblk2p12 of=/data/local/tmp/boot_a.img
然后敲两遍chmod 777 退出shell:
# chmod 777 /data/local/tmp/ # exit $ chmod 777 /data/local/tmp/ $ exit
最后,运行adb pull
即可提取 boot.img 到 PC 上。 boot.img 到手,使用 Magisk patch 镜像再进入 fastboot 刷入镜像完成主系统的 root 操作。
赛后总结
经过这一通折腾,我取得了墨案 MIX 7 Android 系统的 root 权限,可以修改精简系统内不需要的应用,进行更多自定义设置了。事后详细检查前文中提到的日志文件,发现里面确实记载有 OTA 文件的下载地址,不过所有文件都以增量包的形式提供,对系统破解好像没有太大的帮助。尽管已经使用magisk取得了系统内的 root 权限,但进入 recovery 时,adb 的状态仍旧是 unauthorized,不能进行常规的刷机操作,简单搜索后没有发现可用的解决方案,大概只有编译出第三方 recovery 后才能解决。前文中开机成功但是卡在第一屏的 DSU 在取得 root 权限后,就好像完全失效了一样,重启之后也只会在第一屏卡一会,之后就自动重启回到主系统,连adb 也连接不上了。如果想进一步搞机,大概需要想办法备份系统各分区后尝试直接从 fastboot 刷入系统镜像文件了。隔壁的墨水屏手机海信 A9 据说有很多搞机内容,下次想搞机时可以去看一看找找灵感。
更新
墨案于 2024 年 9 月发布了 Mix 7 的 64 位系统更新,本次更新对本文主要内容的有效性无影响。
已 root 的 32 位系统在安装对应 OTA 更新后请勿于 Magisk 中使用“安装到未使用的槽位(OTA 后)”选项为新版本系统安装 Magisk,否则会导致更新失败,回滚到更新前版本。请在更新完成后按照前述流程重新提取 boot.img 并在64位环境中 patch 后刷入。
fastboot 下输入指令无反应时,应考虑更新 fastboot usb 驱动。
另,本次 OTA 的更新包疑似全量包,使用 payload_dumper 可以提取包括 boot 分区在内的各分区镜像,可以考虑使用自其中提取的 boot.img 进行 root 操作(我没有试)。
下期预告
如果还有下一期的话,大概会包含以下主题:利用Magisk的系统自定义(预装软件,字体,Launcher,etc. ),patch 系统镜像的相关操作。
参考资料
部分资料已于正文中以超链接的形式进行了直接引用,因此会有重复。
Boot Image Extraction Guide - https://gist.github.com/gitclone-url/a1f693b64d8f8701ec24477a2ccaab87
Andy Yan's personal builds // GSI Files
以下是我觉得可能会有用但是没有仔细看的资料,在此列出以供有兴趣继续研究的各位读者和未来的我查阅。
瑞芯微RK3566 Android11.0 Ebook SDK开发指南