Android 玩机进阶指南:手动备份分区表和基带等底层分区

前言

“某厂”与“某通”的一些列漏洞(草台班子)为广大玩机用户带来了“BL解锁节”,因而一批手机获得了 root 权限,但玩机的风险也随之而来:

一方面,来源不明的模块、脚本可能包含恶意“格机”代码;另一方面,手动的刷机,系统降级也可能引发一些分区数据的错误删改。

在这些分区中,尤其需要注意的是ModemPersist 等分区。前者是我们常见到的基带分区,一旦损坏将导致手机丢失信号、无法识别 SIM 卡;后者则存储了出厂校准数据、传感器参数及 DRM 密钥。这些分具有唯一性,一旦丢失几乎无法通过常规刷机手段找回,因此进行备份是必要的。

本文是对原 mrwei95 的博客 中方案的扩展与补充:

  • 增加针对物理分区表的备份逻辑

  • 优化了分区排除策略,减小备份体积

  • 引入了端到端的 Hash 校验机制,以确保备份数据传输的可靠。

旨在提供一个更加完整的备份方法。

为何需要手动备份而不使用成品工具?

第三方工具有黑盒属性,在备份与恢复、数据存储等方面不受控制(例如,需要对应软件才可恢复,需要特定版本才能恢复等);此外,对于一个未知工具,随意授予 root 权限是危险的。

环境准备

以 Windows 为例,且假定已经安装好必要的驱动程序与 platform-tools。

在开始备份之前,确保已完成以下准备工作:

  1. 手机已连接电脑,并开启 ADB 调试
  2. 手机必须拥有 Root 权限
  3. 关键步骤:在手机端的 Root 管理器(如 Magisk, APatch 或 KernelSU)中,手动为 Android Shell 授予 Root 权限。这是后续所有底层读写操作的前提。

备份操作流程

adb 交互与提权

首先,通过终端进入手机的 Shell 环境并切换至超级用户。

1
adb shell

进入以后执行:

1
su

创建备份目录

在手机内置存储(sdcard)中创建一个独立的目录,用于存放备份文件和生成的脚本。

1
mkdir /sdcard/000_Backup

生成分区备份脚本

我们需要遍历系统中的逻辑分区。为了节省空间和时间,需要排除掉不必要的,且体积巨大的数据分区(userdata)、缓存分区(cache)、动态分区(super)以及物理磁盘节点(sd[a-z])。

执行以下命令,它将自动生成备份镜像的 .sh 脚本和用于 Fastboot 恢复的 .bat 脚本:

1
2
3
4
ls -1 /dev/block/bootdevice/by-name | grep -ixvE "userdata|cache|super|sd[a-z]" | while IFS= read -r name; do 
echo "dd if=/dev/block/bootdevice/by-name/$name of=/sdcard/000_Backup/$name.img" >> /sdcard/000_Backup/001_Backup_Partitions.sh;
echo "fastboot flash $name $name.img" >> /sdcard/000_Backup/003_Restore_Partitions.bat;
done

生成 GPT 分区表备份脚本

通过 sgdisk 工具,我们可以将 sdasdf 等物理块设备的 GPT 分区表元数据完整导出,以便在恢复时进行参考。

1
2
3
ls -1 /dev/block/by-name | grep -ixE "sd[a-z]" | while IFS= read -r name; do 
echo "sgdisk --backup=/sdcard/000_Backup/${name}_gpt.bin /dev/block/by-name/$name" >> /sdcard/000_Backup/002_Backup_PartitionTables.sh;
done

备份与校验

运行生成的脚本,并针对所有生成的镜像文件计算 MD5 值,确保备份过程未发生数据损坏。

1
2
3
4
5
6
7
# 执行分区镜像备份
sh /sdcard/000_Backup/001_Backup_Partitions.sh
# 执行分区表备份
sh /sdcard/000_Backup/002_Backup_PartitionTables.sh

# 创建 MD5 校验表
cd /sdcard/000_Backup && md5sum * > /sdcard/000_Backup/004_MD5Hash.txt

数据归档

手机端打包

为了方便传输,将备份目录整体打包,并计算压缩包的 Hash 值。

1
2
cd /sdcard && tar -zcpvf PartitionBackup.tgz 000_Backup
md5sum PartitionBackup.tgz

拉取至电脑

在电脑端使用 ADB 拉取文件,并对比两端的 Hash 值。

1
2
3
adb pull /sdcard/PartitionBackup.tgz
# Windows 环境校验 MD5
certutil -hashfile PartitionBackup.tgz MD5

确保两端的 Hash 字符串完全一致后,备份才算真正成功。

结语

操作完成后,请记得:

  • 撤销 Android Shell 的 Root 授权

  • 关闭 ADB 调试

以保障设备日常使用的安全性。

恢复建议

如需恢复,强烈建议手动修改生成的 .bat 恢复脚本,在理解各个分区含义后,确定哪些分区需要手动刷回。

对于常规刷机包中已经包含的分区,通常无需重复恢复。重点应放在那些难以获取官方原厂镜像的底层分区上。

其它补充:分区路径对比

在进行底层备份时,理解 /dev/block/bootdevice/by-name/dev/block/by-name 的区别有助于我们更精准地定位数据。

我们可以通过以下实验进行对比:

1
2
3
adb shell ls -1 /dev/block/bootdevice/by-name > ./blocks_in_bootdevice.txt
adb shell ls -1 /dev/block/by-name > ./blocks_direct.txt
fc blocks_in_bootdevice.txt blocks_direct.txt

实验小结

  • /dev/block/bootdevice/by-name:通常是系统首选的符号链接路径,指向当前启动设备的分区。
  • /dev/block/by-name:包含了更完整的块设备映射。通过对比可以发现,该路径下包含了 sda, sdb, sdc, sdd, sde, sdf 等物理大分区节点。
  • 备份建议:逻辑分区(镜像)建议从 bootdevice 路径读取,而物理分区表(GPT)则必须通过 by-name 下的物理磁盘节点进行备份。

致谢

特别感谢 mrwei95 提供的核心技术思路。

一些细节在本文中没有提到,强烈建议补充阅读原文:Android设备备份字库