Android OTA 相关工具(七) 使用 lpunpack 解包 super.img

这篇具有很好参考价值的文章主要介绍了Android OTA 相关工具(七) 使用 lpunpack 解包 super.img。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

从 Android 10(Q) 开始,引入了动态分区,伴随的就是一组动态分区内容数据增删改查相关的操作,以及这些操作所需要的工具,包括 lpdump, lpmake, lpunpack, lpadd, lpflash。

工具名称前缀 lp 表示是 logic partition,即逻辑分区。

所谓逻辑分区,是相对于物理分区而言,因为动态分区内部的各种分区并不是实际的物理分区。

因此,可以说动态分区本身的 super 是物理分区,但 super 内包含的各种分区就是逻辑分区。

前面两篇分别介绍了 lpdump 和 lpmake,本篇介绍 lpunpack。

本文基于 android-13.0.0_r41 编译生成的 lpunpack 介绍该工具的使用,但也适用于 Android 10(Q) 开始的其它 Android 版本。

《Android OTA 相关工具》系列,目前已有文章列表:

  • 《Android OTA 相关工具(一) 虚拟 A/B 之 snapshotctl》
  • 《Android OTA 相关工具(二) 动态分区之 dmctl》
  • 《Android OTA 相关工具(三) A/B 系统之 bootctl 工具》
  • 《Android OTA 相关工具(四) 查看 payload 文件信息》
  • 《Android OTA 相关工具(五) 使用 lpdump 查看动态分区》
  • 《Android OTA 相关工具(六) 使用 lpmake 打包生成 super.img》
  • 《Android OTA 相关工具(七) 使用 lpunpack 解包 super.img》

本文为洛奇看世界(guyongqiangx)原创,转载请注明出处。

文章链接:https://blog.csdn.net/guyongqiangx/article/details/132598451

1. lpunpack 的编译

lpmake 工具从 Android Q 版代码开始引入,源码位于 system/extras/partition_tools 目录下,默认编译 Android 后输出到 out/host/linux-x86/bin/lpmake ,第一次编译以后,通过 source 和 lunch 操作设置 Android 编译环境后就可以引用。

例如:

$ source build/envsetup.sh 
$ lunch aosp_panther-userdebug
$ which lpunpack 
/public/rocky/android-13.0.0_r41/out/host/linux-x86/bin/lpunpack

当然,也可以将 out/host/linux-x86/bin 添加到当前目录下使用:

$ echo $PATH
/home/rocky/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ export PATH=${PWD}/out/host/linux-x86/bin:$PATH
$ echo $PATH
/public/rocky/android-13.0.0_r41/out/host/linux-x86/bin:/home/rocky/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ which lpunpack 
/public/rocky/android-13.0.0_r41/out/host/linux-x86/bin/lpunpack

两种方式都差不多,不过个人推荐前者。

2. lpunpack 的帮助信息

lpunpack 的帮助信息非常简单:

android-13.0.0_r41$ lpunpack -h
lpunpack - command-line tool for extracting partition images from super

Usage:
  lpunpack [options...] SUPER_IMAGE [OUTPUT_DIR]

Options:
  -p, --partition=NAME     Extract the named partition. This can
                           be specified multiple times.
  -S, --slot=NUM           Slot number (default is 0).

直接将 raw 格式的 super 镜像解包到指定的输出目录。

lpunpack 不能识别 sparse 镜像格式,所以如果 super.img 是 sparse 格式,则需要先将其转换成 raw 格式。

有两个可选参数"–partition" 和 “–slot”,分别用于指定提取镜像的分区名称(name)和槽位(slot),如果没有提供选项参数,则默认提取所有存在的分区镜像。

3. lpunpack 的用法

从上一节的帮助信息可以看到,lpunpack 的用法比较简单,主要分成两步:

  1. 将 sparse 格式的 super.img 转换成 raw 格式
  2. 提取 raw 格式的 super.img 内部的分区镜像

这里以 android-13.0.0_r41 代码编译参考设备 panther 得到的 super.img 为例演示 lpunpack 的操作

准备工作:

# 设置环境
$ source build/envsetup.sh 
$ lunch aosp_panther-userdebug

# 编译 dist 输出
$ make dist -j80

# 查找系统的 super.img 镜像
$ find out -type f -name super.img
out/target/product/panther/obj/PACKAGING/super.img_intermediates/super.img
out/dist/super.img

# 把 dist 下的 sparse 格式的 super.img 转换成 raw 格式
$ file out/dist/super.img 
out/dist/super.img: Android sparse image, version: 1.0, Total of 2082816 4096-byte output blocks in 159 input chunks.

# 使用 simg2img 将 sparse 格式转换成 raw 格式
$ simg2img out/dist/super.img super_raw.img 

# 查看 super 分区的信息
$ lpdump super_raw.img 
Slot 0:
Metadata version: 10.2
Metadata size: 1256 bytes
Metadata max size: 65536 bytes
Metadata slot count: 3
Header flags: virtual_ab_device
Partition table:
------------------------
  Name: system_a
  Group: google_dynamic_partitions_a
  Attributes: readonly
  Extents:
    0 .. 1732063 linear super 2048
------------------------
  Name: system_b
  Group: google_dynamic_partitions_b
  Attributes: readonly
  Extents:
    0 .. 53343 linear super 1734656
------------------------
  Name: system_dlkm_a
  Group: google_dynamic_partitions_a
  Attributes: readonly
  Extents:
    0 .. 679 linear super 1789952
------------------------
  Name: system_dlkm_b
  Group: google_dynamic_partitions_b
  Attributes: readonly
  Extents:
------------------------
  Name: system_ext_a
  Group: google_dynamic_partitions_a
  Attributes: readonly
  Extents:
    0 .. 588663 linear super 1792000
------------------------
  Name: system_ext_b
  Group: google_dynamic_partitions_b
  Attributes: readonly
  Extents:
------------------------
  Name: product_a
  Group: google_dynamic_partitions_a
  Attributes: readonly
  Extents:
    0 .. 718839 linear super 2381824
------------------------
  Name: product_b
  Group: google_dynamic_partitions_b
  Attributes: readonly
  Extents:
------------------------
  Name: vendor_a
  Group: google_dynamic_partitions_a
  Attributes: readonly
  Extents:
    0 .. 1214359 linear super 3100672
------------------------
  Name: vendor_b
  Group: google_dynamic_partitions_b
  Attributes: readonly
  Extents:
------------------------
  Name: vendor_dlkm_a
  Group: google_dynamic_partitions_a
  Attributes: readonly
  Extents:
    0 .. 84063 linear super 4315136
------------------------
  Name: vendor_dlkm_b
  Group: google_dynamic_partitions_b
  Attributes: readonly
  Extents:
------------------------
Super partition layout:
------------------------
super: 2048 .. 1734112: system_a (1732064 sectors)
super: 1734656 .. 1788000: system_b (53344 sectors)
super: 1789952 .. 1790632: system_dlkm_a (680 sectors)
super: 1792000 .. 2380664: system_ext_a (588664 sectors)
super: 2381824 .. 3100664: product_a (718840 sectors)
super: 3100672 .. 4315032: vendor_a (1214360 sectors)
super: 4315136 .. 4399200: vendor_dlkm_a (84064 sectors)
------------------------
Block device table:
------------------------
  Partition name: super
  First sector: 2048
  Size: 8531214336 bytes
  Flags: none
------------------------
Group table:
------------------------
  Name: default
  Maximum size: 0 bytes
  Flags: none
------------------------
  Name: google_dynamic_partitions_a
  Maximum size: 8527020032 bytes
  Flags: none
------------------------
  Name: google_dynamic_partitions_b
  Maximum size: 8527020032 bytes
  Flags: none
------------------------

总结下 super 分区内的镜像内容:

  • 槽位 A 中包含 system_a, system_dlkm_a, system_ext_a, product_a, vendor_a 和 vendor_dlkm_a 镜像
  • 槽位 B 中包含 system_b 镜像(大小和 system_a 的镜像不一样)

关于如何下载 Android 代码并基于 Google 官方的参考设备进行编译,请参考:

《如何下载和编译 Android 源码?》

3.1 解包所有镜像

不带参数解包所有分区镜像。

$ mkdir temp
$ lpunpack super_raw.img temp/
$ ls -lh temp/
total 2.1G
-rw-r--r-- 1 rocky users 351M Aug 29 14:09 product_a.img
-rw-r--r-- 1 rocky users    0 Aug 29 14:09 product_b.img
-rw-r--r-- 1 rocky users 846M Aug 29 14:09 system_a.img
-rw-r--r-- 1 rocky users  27M Aug 29 14:09 system_b.img
-rw-r--r-- 1 rocky users 340K Aug 29 14:09 system_dlkm_a.img
-rw-r--r-- 1 rocky users    0 Aug 29 14:09 system_dlkm_b.img
-rw-r--r-- 1 rocky users 288M Aug 29 14:09 system_ext_a.img
-rw-r--r-- 1 rocky users    0 Aug 29 14:09 system_ext_b.img
-rw-r--r-- 1 rocky users 593M Aug 29 14:09 vendor_a.img
-rw-r--r-- 1 rocky users    0 Aug 29 14:09 vendor_b.img
-rw-r--r-- 1 rocky users  42M Aug 29 14:09 vendor_dlkm_a.img
-rw-r--r-- 1 rocky users    0 Aug 29 14:09 vendor_dlkm_b.img

3.2 解包指定名称分区镜像

使用 “-p” 参数解包单个分区 system_a 的镜像:

$ rm -rf temp/*
$ lpunpack -p system_a super_raw.img temp/
$ ls -lh temp/
total 843M
-rw-r--r-- 1 rocky users 846M Aug 30 19:48 system_a.img

使用多个 “-p” 参数解包多个分区(system_a 和 vendor_a)镜像:

$ rm -rf temp/*
$ lpunpack -p system_a -p vendor_a super_raw.img temp/
$ ls -lh temp/
total 1.5G
-rw-r--r-- 1 rocky users 846M Aug 30 19:50 system_a.img
-rw-r--r-- 1 rocky users 593M Aug 30 19:50 vendor_a.img

3.3 解包指定槽位分区镜像

根据 help 信息,可以使用 “-S”/“–slot” 选项指定槽位,解包单个槽位镜像。

但必须吐槽一下这个选项,Bug 丛生。

槽点 1:使用 “-S”(大写) 选项,提示不认识 “-S” 选项

android-13.0.0_r41$ lpunpack -S 1 super_raw.img temp
lpunpack: unrecognized option '-S'
Unrecognized argument.
lpunpack - command-line tool for extracting partition images from super

Usage:
  lpunpack [options...] SUPER_IMAGE [OUTPUT_DIR]

Options:
  -p, --partition=NAME     Extract the named partition. This can
                           be specified multiple times.
  -S, --slot=NUM           Slot number (default is 0).

槽点 2:使用 “-s”(小写) 选项,提示不认识的参数

android-13.0.0_r41$ lpunpack -s 1 super_raw.img temp
Unrecognized command-line arguments.
lpunpack - command-line tool for extracting partition images from super

Usage:
  lpunpack [options...] SUPER_IMAGE [OUTPUT_DIR]

Options:
  -p, --partition=NAME     Extract the named partition. This can
                           be specified multiple times.
  -S, --slot=NUM           Slot number (default is 0).

槽点 3: 使用 “–slot 1” 选项提取槽位 1 的分区镜像,但实际上两个槽位的 image 都提取出来了

android-13.0.0_r41$ rm -rf temp/*
android-13.0.0_r41$ lpunpack --slot 1 super_raw.img temp/
android-13.0.0_r41$ ls -lh temp/
total 2.1G
-rw-r--r-- 1 rocky users 351M Aug 31 10:11 product_a.img
-rw-r--r-- 1 rocky users    0 Aug 31 10:11 product_b.img
-rw-r--r-- 1 rocky users 846M Aug 31 10:11 system_a.img
-rw-r--r-- 1 rocky users  27M Aug 31 10:11 system_b.img
-rw-r--r-- 1 rocky users 340K Aug 31 10:11 system_dlkm_a.img
-rw-r--r-- 1 rocky users    0 Aug 31 10:11 system_dlkm_b.img
-rw-r--r-- 1 rocky users 288M Aug 31 10:11 system_ext_a.img
-rw-r--r-- 1 rocky users    0 Aug 31 10:11 system_ext_b.img
-rw-r--r-- 1 rocky users 593M Aug 31 10:11 vendor_a.img
-rw-r--r-- 1 rocky users    0 Aug 31 10:11 vendor_b.img
-rw-r--r-- 1 rocky users  42M Aug 31 10:11 vendor_dlkm_a.img
-rw-r--r-- 1 rocky users    0 Aug 31 10:11 vendor_dlkm_b.img

没想到这个 lpunpack 工具已经提供好几年了,lpunpack 竟然还有问题。

好吧,那就只能去改下代码了。

如果你需要指定槽位操作的话,可能需要修改下代码,以下代码仅供参考:

android-13.0.0_r41$ repo diff system/extras/partition_tools/lpunpack.cc 
project system/extras/
diff --git a/partition_tools/lpunpack.cc b/partition_tools/lpunpack.cc
index 1f870c5d..951572d4 100644
--- a/partition_tools/lpunpack.cc
+++ b/partition_tools/lpunpack.cc
@@ -84,7 +84,7 @@ static int usage(int /* argc */, char* argv[]) {
             "Options:\n"
             "  -p, --partition=NAME     Extract the named partition. This can\n"
             "                           be specified multiple times.\n"
-            "  -S, --slot=NUM           Slot number (default is 0).\n",
+            "  -s, --slot=NUM           Slot number (default is 0).\n",
             argv[0], argv[0]);
     return EX_USAGE;
 }
@@ -93,7 +93,7 @@ int main(int argc, char* argv[]) {
     // clang-format off
     struct option options[] = {
         { "partition",  required_argument,  nullptr, 'p' },
-        { "slot",       required_argument,  nullptr, 'S' },
+        { "slot",       required_argument,  nullptr, 's' },
         { nullptr,      0,                  nullptr, 0 },
     };
     // clang-format on
@@ -102,7 +102,7 @@ int main(int argc, char* argv[]) {
     std::unordered_set<std::string> partitions;
 
     int rv, index;
-    while ((rv = getopt_long_only(argc, argv, "+p:sh", options, &index)) != -1) {
+    while ((rv = getopt_long_only(argc, argv, "+p:s:h", options, &index)) != -1) {
         switch (rv) {
             case 'h':
                 usage(argc, argv);
@@ -110,7 +110,7 @@ int main(int argc, char* argv[]) {
             case '?':
                 std::cerr << "Unrecognized argument.\n";
                 return usage(argc, argv);
-            case 'S':
+            case 's':
                 if (!android::base::ParseUint(optarg, &slot_num)) {
                     std::cerr << "Slot must be a valid unsigned number.\n";
                     return usage(argc, argv);

从代码中可以看到,如果指定了 slot,实际上是从 super 中读取该 slot 对应的 metadata,然后使用这个 metadata 提取分区镜像。

由于读取到的 metadata 实际上还是包含了 a, b 两个槽位的信息,所以看起来即使指定了 “-s” 选项,但没什么作用,除非读取到的 metadata 只有 b 槽位的信息。

关于 metadata 的布局,请参考《Android 动态分区详解(一) 5 张图让你搞懂动态分区原理》中的下图:

lpunpack,Android OTA 工具,Android A/B 系统,动态分区,OTA 工具,lpunpack,Android

好了,说了一大堆废话。

总结起来一句话就是:lpunpack 的 “-S”/“–slot” 选项有问题,没事就少用。使用的话,要慎重。

4. 其它

  • 到目前为止,我写过 Android OTA 升级相关的话题包括:
    • 基础入门:《Android A/B 系统》系列
    • 核心模块:《Android Update Engine 分析》 系列
    • 动态分区:《Android 动态分区》 系列
    • 虚拟 A/B:《Android 虚拟 A/B 分区》系列
    • 升级工具:《Android OTA 相关工具》系列

更多这些关于 Android OTA 升级相关文章的内容,请参考《Android OTA 升级系列专栏文章导读》。

如果您已经订阅了动态分区和虚拟分区付费专栏,请务必加我微信,备注订阅账号,拉您进“动态分区 & 虚拟分区专栏 VIP 答疑群”。我会在方便的时候,回答大家关于 A/B 系统、动态分区、虚拟分区、各种 OTA 升级和签名的问题,此群仅限专栏订阅者参与~

除此之外,我有一个 Android OTA 升级讨论群,里面现在有 400+ 朋友,主要讨论手机,车机,电视,机顶盒,平板等各种设备的 OTA 升级话题,如果您从事 OTA 升级工作,欢迎加群一起交流,请在加我微信时注明“Android OTA 讨论组”。此群仅限 Android OTA 开发者参与~

公众号“洛奇看世界”后台回复“wx”获取个人微信。文章来源地址https://www.toymoban.com/news/detail-785044.html

到了这里,关于Android OTA 相关工具(七) 使用 lpunpack 解包 super.img的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android 9.0 ota升级关于SettingsProvider新增和修改系统数据相关功能实现

      在9.0的系统rom定制化开发中,在进行ota升级的过程中,由于在SettingsProvider中新增了系统属性和修改某项系统属性值,但是在ota升级以后发现没有 更新,需要恢复出厂设置以后才会更改,但是恢复出厂设置 会丢掉一些数据,这是应为系统数据库没更新,所以需要在ota的时候

    2024年01月22日
    浏览(70)
  • Android Spider Frida-Dexdump 脱壳工具下载使用以及相关技术介绍

    本案例使用的App是:引力播.apk,涉及到查壳、脱壳、反编译; 提示:以下是本篇文章正文内容,下面案例可供参考 ApkScan-PKID 查壳工具下载使用:https://blog.csdn.net/EXIxiaozhou/article/details/127196615 JDAX-GUI 反编译工具下载使用:https://blog.csdn.net/EXIxiaozhou/article/details/127207762 Apk下载地

    2024年02月02日
    浏览(58)
  • Android Spider JDAX-GUI 反编译工具下载使用以及相关技术介绍

    反编译工具有很多种,我推荐JADX,后续有更好的反编译工具我会继续补充 jadx 本身就是一个开源项目,源代码已经在 Github 上开源了 官方地址:https://github.com/skylot/jadx zip下载地址:https://github.com/skylot/jadx/releases/tag/v1.4.4 Windows系统我建议走上方的zip下载链接进行下载 Java 1.8

    2023年04月08日
    浏览(43)
  • Android Spider ApkScan-PKID 查壳工具下载使用以及相关技术介绍

    1、壳的功能:壳最本质的功能就是实现加载器,壳是指在一个程序的外面再包裹上另外一段代码,保护里面的代码不被非法修改或反编译的程序。它们一般都是先于程序运行,拿到控制权,然后完成它们保护软件的任务,深入点就是在apk外面再套一层壳,在运行的时候这层壳

    2024年01月15日
    浏览(41)
  • 微信小程序逆向 小程序包使用unveilr工具解包后在开发者工具报[ WXML 文件编译错误] xxx.wxs Unexpected token `}`

    微信小程序逆向 使用解包工具后后在开发者工具报[ WXML 文件编译错误] xxx.wxs Unexpected token } 页面上则报编译.wxml文件错误… 解决方案: 很简单,因为是解包出来的,一般代码都是没有错的,我们只需要微信微信开发者工具中的资源管理器或者其他地方,找到这个文件,然后

    2024年02月08日
    浏览(60)
  • 浅析Android OTA机制

    OTA 全称 Over-the-Air Technology,这种在线升级,无需刷机升级的方式,叫做OTA升级,OTA升级可以借助Wifi无线网络或者手机移动网络完成升级,相当于借助空中无线网络完成升级; 项目中需要OTA的功能,因此有了此文,参考下Android的OTA实现机制,可以看到Android的OTA机制随着版本

    2024年01月25日
    浏览(45)
  • Android OTA差分包制作(RK平台)

    1. 编译两个新旧版本,需要用到两个版本的rk3566_r-target_files-eng.zip文件。 2. 将两个版本的rockdev/Image-rk3566_r/rk3566_r-target_files-eng.zip拷贝到某个制作空间下,建议文件命名带上型号及版本号,方便维护,如: rk3566_r-target_files-XXModel-V3.0.0.zip rk3566_r-target_files-XXModel-V3.0.1.zip 3. 在源码

    2023年04月27日
    浏览(65)
  • 解决高通 Android 12/13 ota升级失败问题

    1、 Android adb push ota全量包 如下图所示 2、当前设备是a分区 如下图所示  3、adb root -adb enable-verity-adb reboot  如下图所示  4、adb ota包升级成功 升级完成之后记得 reboot 重启一下 如下图所示 5、当前设备成功切换b分区 如下图所示  6、到这里基本就结束了, ota 升级相关 Andr

    2024年02月06日
    浏览(79)
  • Linux CentOS安装抓包解包工具Wireshark图形化界面

    Wireshark 是一个开源的网络协议分析工具,它能够捕获和分析网络数据包,提供深入的网络故障排除、网络性能优化和安全审计等功能。它支持跨多个操作系统,包括 Windows、macOS 和 Linux。 捕获数据包:         打开 Wireshark,选择要捕获数据包的网络接口。您可以选择物理

    2024年02月11日
    浏览(35)
  • 【干货】Android系统定制基础篇:第七部分-Android OTA升级(系统、应用)

    项目地址:https://github.com/aystshen/Android-RomUpgrade. 这是一个负责 Android OTA 升级的后台应用,开机后自动运行后台 Service,支持系统升级和应用升级,支持本地升级(tf卡、u盘)和在线升级(百度),支持推荐升级和静默升级。 已知兼容版本: ● Android 5.1 ● Android 6.0 ● Android

    2024年02月09日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包