使用安卓增量 OTA 包提取出 boot.img
2024 年 09 月 25 日 • 5 分钟
前言
昨天我的 Moto S30Pro 终于推了安卓 14,由于我需要使用 root 来让手机正常连接 Pixel Watch,因此需要更新后还能保持 root(准确来说是 Apatch)。
互联网上流传着一种“招式”:
- 用 Apatch 还原系统 boot 镜像,不重启
- 正常进行系统更新,不重启
- 刷写修补后的 boot 镜像到另一个槽位
- 重启,成功保 root 更新
但是我在步骤 2 便无法进行了——更新一直无法通过校验。只好 fastboot 写入原厂 boot 再更新了,这样一来重启后 root 就掉了。
重新 root 需要安卓 14 的原厂 boot 来进行修补,但这一时半会官方还没放出全量包,因此得想别的办法提取一个。
现有的资源
目前手上只有一个安卓 13 的原厂 boot 镜像,根本无从下手。因此虽然不知道是否有用,但还是搞来了这次更新 的 OTA 包。
解压后有以下文件:
Ota_Version.31.0.3.tundra_cn.china.Hans.CN.zip
├── META-INF
├── payload_properties.txt
├── payload.bin
├── metadata.json
├── care_map.pb
└── apex_info.pb
payload.bin
的大小最大,一看就是好东西,上网一搜,果然有通过 payload 提取 boot 镜像的方式:
只可惜,生活总是不会那么一番风顺,手上的这个是增量 OTA 包不适用上述办法。
使用 payload_dumper 进行解包
通过增量 OTA 包的 payload 文件获取 boot 的唯一方式就是使用 payload_dumper 了:
前置条件是需要上一版本的 boot.img,既然这个已经有了,那就立马开干!
软件需求
- Python3
- Git
前置工作
克隆 payload_dumper 到本地:
git clone https://github.com/vm03/payload_dumper
安装依赖:
python -m pip install -r requirements.txt
之后,将上一版本的原厂 boot.img 放置在 old 文件夹内,payload.bin 放置在根目录下,一切结束后文件结构大概如下:
payload_dumper
├── old
│ └── boot.img
├── output
├── ...
├── payload.bin
├── payload_dumper.py
└── requirements.txt
可以开始下一步了。
开始导出
执行以下命令:
python payload_dumper.py --diff payload.bin --images boot
如果一切顺利,控制台应该没有任何报错,并且 output 文件夹下就有一个崭新的 boot.img
在等着我们,可以拿着去刷、去修补了。如果控制台有任何报错,即便 output 下有 boot 文件,也不要刷写!否则可能会因为刷入无效 boot 而进不去系统。
如果很不幸的像我一样遇到了如下报错:
Unsupported type = 9
那就得用下面这种方法了。
使用 update_payload_extractor 进行解包
通过这个 issue 得知,Type 9
是一种叫 PUFFDIFF
的数据格式。
虽然 payload_dumper 目前并不支持该格式的 payload,但是伟大的开源社区已经为我们指明方向了😌。其便是支持 PUFFDIFF
的 update_payload_extractor:
开干!
软件需求
- Linux
- Python3
- Git
是的,这个仓库需要在 Linux 下才能跑得起来。
前置工作
克隆 update_payload_extractor 到本地:
git clone update_payload_extractor
安装依赖:
pip3 install protobuf==3.20
之后,将上一版本的原厂 boot.img 重命名为 boot 并放置在 old 文件夹内(也可以直接移过去再用仓库内的 remove_img_extension_old.sh
脚本批量去掉扩展名),payload.bin 放置在根目录下,一切结束后文件结构大概如下:
update_payload_extractor
├── old
│ └── boot
├── output
├── ...
├── payload.bin
└── extract.py
开始导出
分别执行以下命令:
LD_LIBRARY_PATH=./lib64/ ./extract.py --output_dir output/ --old_dir old/ payload.bin --partitions boot
./add_img_extension_output.sh
一样的,如果一切顺利,控制台应该没有任何报错提示,并且 output 文件夹下就有一个崭新的 boot.img
,将其拷出来就能拿着去刷、去修补了。而我也通过这个 boot 镜像成功恢复了 Apatch 🥳。
最后
这次也是学到了很多,摸索中途还无视报错把 boot 刷了进去,导致手机反复重启进不去系统,差点就回退安卓 13 了😭。好在最后柳暗花明又一村!找到了路子,提取出了 boot 文件。