本文字数:1912 字

阅读时长约为:20 分钟

阅读难度:中

前言

随着 Android 引入无缝更新后,系统固件从原本简单直接的内容压缩包(下图一)转变成了并那么不直白的 payload.bin 镜像分区打包(下图二)。流行的 Root 工具 Magisk,KernelSU 等需要提取对应 init_boot 或者 boot 分区镜像修补刷入,增加了使用难度。

图一:MIUI 7 线刷包解压
图二:一加 12 全量升级固件包解压

5ec1cff 大佬修改的 payload-dumper 工具添加了对从来自网络的包含 payload.bin (的 zip 归档)的 url (如 OTA 更新地址)直接提取分区的支持,简而言之,提取所需的镜像不再需要下载数个 GB 的完整系统固件,只需要少量的时间和存储空间就能从 OTA 更新包或地址中提取你想要的分区。

另一方面,像 F2FS,EROFS 这些更新更高效的文件系统开始广泛应用,让提取和打包对应的分区镜像变的复杂。本文目的在于分享在线提取分区镜像以及解包 EROFS 镜像的简单办法。

payload.bin 简单转储办法

在线提取分区镜像(感谢 PedroZ

用法比较简单,上方 Partition Name 填写所需要提取的分区名,例如 boot,init_boot,vendor_boot 等,注意一次只能填写一个分区,下放粘贴固件下载地址即可,完成后点击 submit 稍等片刻就会进行所需的分区下载。

FastbootEnhance(仅支持 Windows)

适用于 Windows 的图形化工具,支持导入系统固件提取分区镜像,也支持 Fastboot 和 FastbootD 状态下刷写分区镜像。

命令行工具使用教程

所需准备

支持 Windows(WSL2),Linux,macOS 和 Android。Windows 推荐微软商店安装 Fedora WSL 方便操作,macOS 需安装 Homebrew 包管理器,Android 则需要安装 Termux 进行操作。

brew install pip python git erofs-utils
sudo dnf install pip python git erofs-utils

安装所需的包后,便可以安装我们所需的 payload-dumper 在线提取分区镜像

pip install git+https://github.com/5ec1cff/payload-dumper

Android 需要的额外准备

“我”发现获取某些分区的时候仍然存在需要下载大量数据的问题。

经调查,发现原因是 python 的标准库 zipfile 直到 3.12 才支持在未压缩的 zip 中快速 seek 。在此之前, seek 的实现必须要完整读取 seek 到的位置之前的内容,这可能是由于压缩数据流必须完整读取才能解压。

不过 ota 更新包中的 payload.bin 在 zip 中往往是未压缩,并不需要完整读取。这意味着,在 python 3.12 之前,假如要读取的分区所在偏移恰好非常大,则仍然需要下载很多不必要的数据。

综上,建议使用 python 3.12 运行该程序以获得最佳性能。

由于 Termux 仓库的 Python 版本仍是旧版 3.11,存在需要大量下载文件的问题,好在有他人做好现成的 Python 3.12 for Termux,为我们省去了修补和编译的大量时间。以下是手动安装教程。

首先需要下载所需的 python-3.12.3-aarch64.tar.zst 二进制包并进行解压,为了方便,将两次解压后获得的 python-3.12.3 文件夹放置于手机内置存储根目录。之后打开 Termux 进行剩余操作。

pkg install stow python git erofs-utils
cd /sdcard #移动到内置存储根目录
mkdir -p $PREFIX/stow
mv python-3.12.3 $PREFIX/stow/ #移动解压后的二进制包到所需目录
cd $PREFIX/stow
stow -v --stow python-3.12.3
chmod +x python-3.12.3 #对文件添加执行权限
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py #下载 pip 安装脚本
python3.12 get-pip.py #运行 pip 安装脚本
python3.12 -m pip install git+https://github.com/5ec1cff/payload-dumper #安装 payload-dumper
echo export PATH=$PATH:/data/data/com.termux/files/usr/stow/python-3.12.3/bin >> ~/.bashrc #添加环境变量

payload-dumper 用法

我们可以通过命令查看 payload_dumper 用法。

payload_dumper -h
usage: payload_dumper [-h] [--out OUT] [--diff] [--old OLD]
                      [--partitions PARTITIONS] [--workers WORKERS] [--list]
                      [--metadata]
                      payloadfile

OTA payload dumper

positional arguments:
  payloadfile           payload file name

options:
  -h, --help            show this help message and exit
  --out OUT             output directory (default: 'output')
  --diff                extract differential OTA
  --old OLD             directory with original images for differential OTA
                        (default: 'old')
  --partitions PARTITIONS
                        comma separated list of partitions to extract
                        (default: extract all)
  --workers WORKERS     number of workers (default: CPU count - 8)
  --list                list partitions in the payload file
  --metadata            extract and display metadata file from the payload

不理解没有关系,下面说明会用到的命令结构。

payload_dumper  payloadfile                         --out OUT --partitions PARTITIONS                  
调用的工具        系统固件,可以是文件目录也可以是在线链接  可选命令,不输入也不影响使用,out 后续跟文件输出目录,partitions 后续跟所需镜像分区

需补充的是文件目录并不需要手动填写,用文件管理拖动对应的文件夹/文件即可粘贴文件目录(PS:WSL2 是以网络路径访问本机,第三方 Fedora WSL 可以自动转化添加 /mnt/ 可以直接拖动粘贴,因此推荐使用)

我们可以通过下面两个实例来理解使用。

通过在线链接提取

例如我们需要从 一加 OnePlus ACE 3 Pro 全量包 提取 boot 镜像,我创建了一个镜像分区的文件夹,并将目录拖动到 --out 后方,回车稍等片刻需要的 boot.img 变回出现在新建的文件夹中。

payload_dumper 
https://gauss-componentotacostmanual-cn.allawnfs.com/remove-4389ca2b1cc4aa10c775178c4edae79e/component-ota/24/06/25/33e6b8725c924367b8079b3add65a8db.zip # OTA 固件下载地址
--partitions boot # 分区声明,后面跟所需的 boot 分区
--out /Users/zhouyu/Downloads/镜像分区 # 文件输出路径,后面跟文件目录

通过本地固件提取

例如需要从下载完成解压完成的固件提取 system 镜像,我们如法炮制即可,稍等后所需的 system.img 便出现在相应的目录内。

payload_dumper
/Users/zhouyu/Downloads/d19651b82745466c8eb65426ef23c072/payload.bin # payload.bin 文件目录
--partitions system # 分区声明,后面跟所需的 system 分区
--out /Users/zhouyu/Downloads/镜像分区 # 文件输出路径,后面跟文件目录

 


EROFS 分区镜像解压

根据官方文档 erofs-utils 分为如下四个部分,

erofs-utils
===========

Userspace tools for EROFS filesystem, currently including:

  mkfs.erofs    filesystem formatter
  erofsfuse     FUSE daemon alternative
  dump.erofs    filesystem analyzer
  fsck.erofs    filesystem compatibility & consistency checker as well
                as extractor

因为我们只需要解压分区镜像,所以只需要使用其中的 fsck.erofs 即可,解压方法如下。

fsck.erofs --extract[=X]            IMAGE
调用的工具   可选命令,“=”后方跟解压目录  分区镜像

我们使用上方解压获得的 system.img 作演示,并新建名为系统分区的文件夹,输入命令后即可获得所需的系统文件内容。

fsck.erofs 
/Users/zhouyu/Downloads/镜像分区/system.img # 分区镜像目录
extract=/Users/zhouyu/Downloads/系统分区 # 解压目录