Android A/B System OTA分析(六)如何获取 payload 的 offset 和 size

这篇具有很好参考价值的文章主要介绍了Android A/B System OTA分析(六)如何获取 payload 的 offset 和 size。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Android A/B 系统基础入门系列《Android A/B 系统》已完结,文章列表:

Android A/B System OTA分析(一)概览

Android A/B System OTA分析(二)系统image的生成

Android A/B System OTA分析(三)主系统和bootloader的通信

Android A/B System OTA分析(四)系统的启动和升级

Android A/B System OTA分析(五)客户端参数

Android A/B System OTA分析(六)如何获取 payload 的 offset 和 size


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

上一篇《Android A/B System OTA分析(五)客户端升级的参数》提到升级时 offset 和 size 参数分别用于升级时设置远程文件中 payload 数据的起始地址和长度,但并没有提到如何获得这个 offset 和 size 值。本篇详细说明如何计算和获取这两个参数。

我写东西通常想把来龙去脉都写清楚,因此也会很繁琐,以下是对本文快速导航:

*  如果你只想知道 Android O 开始,脚本中是如何计算 offset 和 size 参数的,请转到 2.1 节。
*  如果你只想知道命令行如何手工获取 offset 和 size 参数,请转到第 2.2 节。
*  如果你想找一个单独的脚本工具计算 offset 和 size,请转到第 3.3 节


1. zip 文件的格式

要想知道压缩包中每个文件的 offset 和 size 是如何计算的,就先需要了解下 zip 文件的格式。

对于这种要了解标准或文件格式的情况,我一般推荐阅读官方文档。官方文档虽然枯燥,但是是第一手信息。再配上网上其它的分析文章,这样阅读理解起来会比较容易,也不容易出现错误。

维基百科页面《ZIP (file format) 》提供了多个 zip 文件格式的历史版本链接, 目前最新的版本是 v6.3.9(文档日期 2020/07/15),这里使用 v6.3.2 版本的文档作为参考(文档日期 2007/09/28):

《APPNOTE.TXT - .ZIP File Format Specification》: https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.2.TXT

关于 zip 文件的历史,有兴趣的也请自行参考维基百科:《ZIP (file format) 》

在 v6.3.2 版文档的第 V 节详细描述了 zip 文件的格式。

1.1 zip 文件的总体格式
Overall .ZIP file format:

[local file header 1]
[file data 1]
[data descriptor 1]
. 
.
.
[local file header n]
[file data n]
[data descriptor n]
[archive decryption header] 
[archive extra data record] 
[central directory]
[zip64 end of central directory record]
[zip64 end of central directory locator] 
[end of central directory record]

总体来说,zip 文件由多个文件组成,每个文件由 “loacal file header”, “file data” 和 “data descriptor” 3 部分组成,多个文件时各文件数据依次排列。

在文件结束后有一些其它数据,由于我们只关心每个文件的 offset 和 size,所以可以暂时不用考虑文件末尾的那些数据,虽然可能也很重要。

1.2 local file header

zip 文件中,每个文件的第一部分就是 local file header,用于描述文件的各种属性。

Local file header:

local file header signature     4 bytes  (0x04034b50)
version needed to extract       2 bytes
general purpose bit flag        2 bytes
compression method              2 bytes
last mod file time              2 bytes
last mod file date              2 bytes
crc-32                          4 bytes
compressed size                 4 bytes
uncompressed size               4 bytes
file name length                2 bytes
extra field length              2 bytes

file name (variable size)
extra field (variable size)

在 local file header 中,前面的是定长部分的数据,一共 30 bytes;后面还有两个变长的部分 file name 和 extra field,这两部分的具体长度由定长部分的 file name length 和 extra filed length 指定。

因此 len(local file header) = 30 + len(file name) + len(extra filed)

1.3 file data

紧挨着 local file header 的是文件数据 file data,根据具体的情况,这里的数据可能是压缩的,也可能是没有压缩的,具体长度由 local file header 中的 compressed size 指定。

1.4 data descriptor

file data 之后是 data descriptor:

Data descriptor:

crc-32                          4 bytes
compressed size                 4 bytes
uncompressed size               4 bytes

这部分数据并不是必须的,只有当 local file header 结构中 general purpose bit flag 的 bit 3 被设置以后才存在,其内容也是用来指定文件数据长度的。

为什么会出现这种情况呢? 这是因为有些情况下,一开始是不知道文件数据大小的。例如,用录像机录像时,其数据压缩存储,一开始录制的时候并不能确定最终文件多大,但这些数据又需要不断写入存储介质,所以就在开始的时候设置一个标志位,表示其大小存储在数据结束的地方。

1.5 offset 和 size 的计算

由于我们这里只关心 offset 和 size 的计算,所以 zip 文件后面的那些数据暂时不管了。

只需要拿到每个文件在 zip 包中的 local file header 数据就可以计算得到 offset 和 size 数值。

文件数据的起始位置(offset):

offset(data) = offset(local file header) + size(local file header) 
             = offset(local file header) + 30 + len(file name) + len(extra filed)

文件数据的大小(size):

# 压缩后数据大小
size = comressed size

# 原始数据大小
size = uncompressed size


最后,一张图描述 zip 文件的主要结构,方便参考:

Android A/B System OTA分析(六)如何获取 payload 的 offset 和 size,Android OTA A/B System ,gitee
1.6 关于 encryption header

从 APPNOTE.TXT - .ZIP File Format Specification Version, 6.3.3 开始,zip 文件新增了一个 encryption header,位于 local file header 之后, file data 之前,如下所示:

Overall .ZIP file format:

[local file header 1]
[encryption header 1]
[file data 1]
[data descriptor 1]
. 
.
.
[local file header n]
[encryption header n]
[file data n]
[data descriptor n]
[archive decryption header] 
[archive extra data record] 
[central directory header 1]
.
.
.
[central directory header n]
[zip64 end of central directory record]
[zip64 end of central directory locator] 
[end of central directory record]

这里的 encryption header 只有在压缩包的数据被加密的情况下才会出现,由于 Android 的 update.zip 包并未加密,不会出现 encryption header,因此接下来的讨论都默认没有 encryption header 。

2. 获取 offset 和 size 的三种方式

上一节介绍了 zip 文件的结构,接下来就可以根据这个结构去获取 offset 和 size 数据。

2.1 Android O 开始自动生成 offset 和 size 数据

1. metadata 示例
从 Android 8.0 (O) 开始,制作升级包时,会自动计算 payload 的 offset 和 size 并输出到 zip 包的 META-INF/com/android/metadata 文件中,像下面这样:

$ cat META-INF/com/android/metadata
ota-required-cache=0
ota-streaming-property-files=payload.bin:738:271041806,payload_properties.txt:271042602:154,care_map.txt:474:217,metadata:69:357
ota-type=AB
post-build=bcm/b604usff/b604usff:8.0.0/OPR6.170623.021/rg935701131615:userdebug/test-keys
post-build-incremental=eng.rg9357.20220113.161532
post-timestamp=1642061732
pre-device=b604usff

这里的 ota-streaming-property-files 键值对就记录了多个文件的 offset 和 size 值,包括:

*  payload.bin, offset: 738, size: 271041806
*  payload_propterites.txt, offset: 271042602, size: 154
*  care_map.txt, offset: 474, size: 217
*  metadata, offset: 6957, size: 357

2. metadata 生成的代码分析


这里涉及的Android代码:android-8.0.0_r12(BUILD_ID=OPR6.170623.021)

生成 offset 和 size 数据的代码位于脚本 ota_from_target_files 中,见下面的代码片段:

*  计算多个文件的 offset 和 size
   从第 971 行开始,定义了函数 ComputeStreamingMetadata 用于提取指定压缩包的 offset 和 size 信息

  def ComputeStreamingMetadata(zip_file, reserve_space=False,
                               expected_length=None):
    """Compute the streaming metadata for a given zip.

    When 'reserve_space' is True, we reserve extra space for the offset and
    length of the metadata entry itself, although we don't know the final
    values until the package gets signed. This function will be called again
    after signing. We then write the actual values and pad the string to the
    length we set earlier. Note that we can't use the actual length of the
    metadata entry in the second run. Otherwise the offsets for other entries
    will be changing again.
    """

    #
    # 根据文件名 name, 获取对应文件的 offset 和 size 并用这样的格式输出: 'filename:offset:size'
    # 如: payload.bin:738:271041806
    #
    def ComputeEntryOffsetSize(name):
      """Compute the zip entry offset and size."""
      # 提取文件名 name 对应的 zipinfo 对象
      info = zip_file.getinfo(name)
      # 根据 zipinfo 对象的 header_offset 和 FileHeader 长度, 得到文件数据的 offset
      offset = info.header_offset + len(info.FileHeader())
      # 使用 zipinfo 对象的 file_size 作为 size (这里的 file_size 是文件压缩前的大小,压缩后的大小为 compress_size)
      size = info.file_size
      return '%s:%d:%d' % (os.path.basename(name), offset, size)

    #
    # 获取以下文件的 offset 和 size 数据:
    # 1. payload.bin
    # 2. payload_properties.txt
    # 3. care_map.txt
    # 4. compatibility.zip
    # 5. metadata
    #
    # payload.bin and payload_properties.txt must exist.
    offsets = [ComputeEntryOffsetSize('payload.bin'),
               ComputeEntryOffsetSize('payload_properties.txt')]

    # care_map.txt is available only if dm-verity is enabled.
    if 'care_map.txt' in zip_file.namelist():
      offsets.append(ComputeEntryOffsetSize('care_map.txt'))

    if 'compatibility.zip' in zip_file.namelist():
      offsets.append(ComputeEntryOffsetSize('compatibility.zip'))

    #
    # 计算 'META-INF/com/android/metadata' 文件的 offset 和 size 时,预留了格式: 'metadata:          ' (10个空格)
    #
    # 'META-INF/com/android/metadata' is required. We don't know its actual
    # offset and length (as well as the values for other entries). So we
    # reserve 10-byte as a placeholder, which is to cover the space for metadata
    # entry ('xx:xxx', since it's ZIP_STORED which should appear at the
    # beginning of the zip), as well as the possible value changes in other
    # entries.
    if reserve_space:
      offsets.append('metadata:' + ' ' * 10)
    else:
      offsets.append(ComputeEntryOffsetSize(METADATA_NAME))

    # 将所有文件的 'name:offset:size' 数据用逗号连接成一个字符串返回
    value = ','.join(offsets)
    if expected_length is not None:
      assert len(value) <= expected_length, \
          'Insufficient reserved space: reserved=%d, actual=%d' % (
              expected_length, len(value))
      value += ' ' * (expected_length - len(value))
    return value

* 将获取的 offset 和 size 写入 metadata 文件
   第 1213 行代码开始,计算输出的 zip 文件的 offset 和 size 信息写入 metadata 文件的 ota-streaming-property-files 键值对中。但这里 metadata 文件自身的 offset 和 size 并没有计算。

  # Open the signed zip. Compute the final metadata that's needed for streaming.
  prelim_zip = zipfile.ZipFile(prelim_signing, "r",
                               compression=zipfile.ZIP_DEFLATED)
  expected_length = len(metadata['ota-streaming-property-files'])
  metadata['ota-streaming-property-files'] = ComputeStreamingMetadata(
      prelim_zip, reserve_space=False, expected_length=expected_length)

  ...

  # Now write the final metadata entry.
  WriteMetadata(metadata, output_zip)
2.2 使用 zipinfo 手工计算

linux 命令行工具 zipinfo 可以用来提取 zip 文件的信息。

1. 安装 zipinfo
   这个工具默认情况下没有安装,ubuntu 上可以通过以下命令安装:

sudo apt install unzip

2. 使用 zipinfo 解析 update.zip 文件
    *  zipinfo 帮助信息
       可以通过 zipinfo 查看简略的帮助信息,或者通过 man zipinfo 查看详尽的内容

$ zipinfo
ZipInfo 3.00 of 20 April 2009, by Greg Roelofs and the Info-ZIP group.

List name, date/time, attribute, size, compression method, etc., about files
in list (excluding those in xlist) contained in the specified .zip archive(s).
"file[.zip]" may be a wildcard name containing *, ?, [] (e.g., "[a-j]*.zip").

   usage:  zipinfo [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]
      or:  unzip -Z [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]

main listing-format options:             -s  short Unix "ls -l" format (def.)
  -1  filenames ONLY, one per line       -m  medium Unix "ls -l" format
  -2  just filenames but allow -h/-t/-z  -l  long Unix "ls -l" format
                                         -v  verbose, multi-page format
miscellaneous options:
  -h  print header line       -t  print totals for listed files or for all
  -z  print zipfile comment  ⚌-T⚌ print file times in sortable decimal format
 ⚌-C⚌ be case-insensitive   zipinfo  -x  exclude filenames that follow from listing
  -O CHARSET  specify a character encoding for DOS, Windows and OS/2 archives
  -I CHARSET  specify a character encoding for UNIX and other archives

$ man zipinfo

*  不带参数, 列举 update.zip 中的文件

$ zipinfo
ZipInfo 3.00 of 20 April 2009, by Greg Roelofs and the Info-ZIP group.

List name, date/time, attribute, size, compression method, etc., about files
in list (excluding those in xlist) contained in the specified .zip archive(s).
"file[.zip]" may be a wildcard name containing *, ?, [] (e.g., "[a-j]*.zip").

   usage:  zipinfo [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]
      or:  unzip -Z [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]

main listing-format options:             -s  short Unix "ls -l" format (def.)
  -1  filenames ONLY, one per line       -m  medium Unix "ls -l" format
  -2  just filenames but allow -h/-t/-z  -l  long Unix "ls -l" format
                                         -v  verbose, multi-page format
miscellaneous options:
  -h  print header line       -t  print totals for listed files or for all
  -z  print zipfile comment  ⚌-T⚌ print file times in sortable decimal format
 ⚌-C⚌ be case-insensitive   zipinfo  -x  exclude filenames that follow from listing
  -O CHARSET  specify a character encoding for DOS, Windows and OS/2 archives
  -I CHARSET  specify a character encoding for UNIX and other archives

$ man zipinfo

*  -v 选项解析 zip 文件详信息

$ zipinfo -v update.zip
Archive:  update.zip
The zipfile comment is 1738 bytes long and contains the following text:
======================== zipfile comment begins ==========================
signed by SignApk
========================= zipfile comment ends ===========================

End-of-central-directory record:
-------------------------------

  Zip archive file size:                 271045893 (000000001027D505h)
  Actual end-cent-dir record offset:     271044133 (000000001027CE25h)
  Expected end-cent-dir record offset:   271044133 (000000001027CE25h)
  (based on the length of the central directory and its expected offset)

  This zipfile constitutes the sole disk of a single-part archive; its
  central directory contains 5 entries.
  The central directory is 360 (0000000000000168h) bytes long,
  and its (expected) offset in bytes from the beginning of the zipfile
  is 271043773 (000000001027CCBDh).


Central directory entry #1:
---------------------------

  META-INF/com/android/metadata

  offset of local header from start of archive:   0
                                                  (0000000000000000h) bytes
  file system or operating system of origin:      MS-DOS, OS/2 or NT FAT
  version of encoding software:                   1.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   1.0
  compression method:                             none (stored)
  file security status:                           not encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2009 Jan 1 00:00:00
  32-bit CRC value (hex):                         982fa5b5
  compressed size:                                357 bytes
  uncompressed size:                              357 bytes
  length of filename:                             29 characters
  length of extra field:                          10 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             binary
  non-MSDOS external file attributes:             000000 hex
  MS-DOS file attributes (00 hex):                none

  The central-directory extra field contains:
  - A subfield with ID 0xcafe (unknown) and 0 data bytes.
  - A subfield with ID 0xd935 (unknown) and 2 data bytes:
    00 00.

  There is no file comment.

Central directory entry #2:
---------------------------

  care_map.txt

  offset of local header from start of archive:   426
                                                  (00000000000001AAh) bytes
  file system or operating system of origin:      MS-DOS, OS/2 or NT FAT
  version of encoding software:                   1.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   1.0
  compression method:                             none (stored)
  file security status:                           not encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2009 Jan 1 00:00:00
  32-bit CRC value (hex):                         03053f05
  compressed size:                                217 bytes
  uncompressed size:                              217 bytes
  length of filename:                             12 characters
  length of extra field:                          6 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             binary
  non-MSDOS external file attributes:             000000 hex
  MS-DOS file attributes (00 hex):                none

  The central-directory extra field contains:
  - A subfield with ID 0xd935 (unknown) and 2 data bytes:
    00 00.

  There is no file comment.

Central directory entry #3:
---------------------------

  payload.bin

  offset of local header from start of archive:   691
                                                  (00000000000002B3h) bytes
  file system or operating system of origin:      MS-DOS, OS/2 or NT FAT
  version of encoding software:                   1.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   1.0
  compression method:                             none (stored)
  file security status:                           not encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2009 Jan 1 00:00:00
  32-bit CRC value (hex):                         eba210d4
  compressed size:                                271041806 bytes
  uncompressed size:                              271041806 bytes
  length of filename:                             11 characters
  length of extra field:                          6 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             binary
  non-MSDOS external file attributes:             000000 hex
  MS-DOS file attributes (00 hex):                none

  The central-directory extra field contains:
  - A subfield with ID 0xd935 (unknown) and 2 data bytes:
    00 00.

  There is no file comment.

Central directory entry #4:
---------------------------

  payload_properties.txt

  offset of local header from start of archive:   271042544
                                                  (000000001027C7F0h) bytes
  file system or operating system of origin:      MS-DOS, OS/2 or NT FAT
  version of encoding software:                   1.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   1.0
  compression method:                             none (stored)
  file security status:                           not encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2009 Jan 1 00:00:00
  32-bit CRC value (hex):                         21aa275c
  compressed size:                                154 bytes
  uncompressed size:                              154 bytes
  length of filename:                             22 characters
  length of extra field:                          6 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             binary
  non-MSDOS external file attributes:             000000 hex
  MS-DOS file attributes (00 hex):                none

  The central-directory extra field contains:
  - A subfield with ID 0xd935 (unknown) and 2 data bytes:
    00 00.

  There is no file comment.

Central directory entry #5:
---------------------------

  META-INF/com/android/otacert

  offset of local header from start of archive:   271042756
                                                  (000000001027C8C4h) bytes
  file system or operating system of origin:      MS-DOS, OS/2 or NT FAT
  version of encoding software:                   2.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   2.0
  compression method:                             deflated
  compression sub-type (deflation):               normal
  file security status:                           not encrypted
  extended local header:                          yes
  file last modified on (DOS date/time):          2009 Jan 1 00:00:00
  32-bit CRC value (hex):                         c3fc0954
  compressed size:                                943 bytes
  uncompressed size:                              1675 bytes
  length of filename:                             28 characters
  length of extra field:                          0 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             binary
  non-MSDOS external file attributes:             000000 hex
  MS-DOS file attributes (00 hex):                none

  There is no file comment.

上面执行命令 zipinfo -v update.zip,会打印了 update.zip 包中所有文件的详细信息。

如果只想查看单个文件的信息,可以在后面添加想查看的文件名,如: zipinfo -v update.zip payload.bin:

$ zipinfo -v update.zip payload.bin
Archive:  update.zip
The zipfile comment is 1738 bytes long and contains the following text:
======================== zipfile comment begins ==========================
signed by SignApk
========================= zipfile comment ends ===========================

End-of-central-directory record:
-------------------------------

  Zip archive file size:                 271045893 (000000001027D505h)
  Actual end-cent-dir record offset:     271044133 (000000001027CE25h)
  Expected end-cent-dir record offset:   271044133 (000000001027CE25h)
  (based on the length of the central directory and its expected offset)

  This zipfile constitutes the sole disk of a single-part archive; its
  central directory contains 5 entries.
  The central directory is 360 (0000000000000168h) bytes long,
  and its (expected) offset in bytes from the beginning of the zipfile
  is 271043773 (000000001027CCBDh).


Central directory entry #3:
---------------------------

  payload.bin

  offset of local header from start of archive:   691
                                                  (00000000000002B3h) bytes
  file system or operating system of origin:      MS-DOS, OS/2 or NT FAT
  version of encoding software:                   1.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   1.0
  compression method:                             none (stored)
  file security status:                           not encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2009 Jan 1 00:00:00
  32-bit CRC value (hex):                         eba210d4
  compressed size:                                271041806 bytes
  uncompressed size:                              271041806 bytes
  length of filename:                             11 characters
  length of extra field:                          6 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             binary
  non-MSDOS external file attributes:             000000 hex
  MS-DOS file attributes (00 hex):                none

  The central-directory extra field contains:
  - A subfield with ID 0xd935 (unknown) and 2 data bytes:
    00 00.

  There is no file comment.

这里就只显示了 payload.bin 文件的详细信息。

3. 从 zipinfo 结果中手工计算 offset 和 size

Android A/B System OTA分析(六)如何获取 payload 的 offset 和 size,Android OTA A/B System ,gitee

从上面的解析可以得到以下的信息:

*  payload.bin 文件的 local file header 的偏移为 691 bytes
*  filename 和 extra field 的长度分别为 11 bytes 和 6 bytes
*  compressed size 和 uncompressed size 大小一样,都是 271041806 bytes

因此,payload.bin 文件的数据在 update.zip 包中的偏移量:

offset(data) = offset(local file header) + size(local file header) 
             = offset(local file header) + 30 + len(file name) + len(extra filed)
             = 691 + 30 + 11 + 6
             = 738

另外,这里compressed size 和 uncompressed size 大小一样,都是 271041806 bytes 说明 payload.bin 文件并没有被压缩,只是打包到了 zip 文件而已,在数据被压缩的情况下,则其在压缩包中的大小应该是 compressed size。

在前面的 python 代码中,其 zipinfo.file_size 就是这里的 uncompressed size,否则应该使用 compressed size 数据。

所以,我觉得脚本中应该使用 zipinfo.compress_size 作为 size 大小最为合适,offset ~ compress_size 才是 payload.bin 在 zip 包中的具体数据。

2.3 使用 python 脚本计算

简单修改一下 Android O 脚本中的代码,就可以生成一个计算 offset 和 size 的工具 zip_info.py:

#!/usr/bin/env python3

import os
import zipfile


def show_zipfile(filename):
    zf = zipfile.ZipFile(filename, 'r')
    print('{}:\n'.format(filename))
    print('{:>25s}  {:>15s}  {:>15s}  {:>15s}'.format("name", "offset", "size", "compress_size"))
    print('{:>25s}  {:>15s}  {:>15s}  {:>15s}'.format('-' * 25, '-' * 15, '-' * 15, '-' * 15))
    for x in zf.namelist():
        info = zf.getinfo(x)
        offset = info.header_offset + len(info.FileHeader())
        size = info.file_size
        compress_size = info.compress_size
        print('{:>25s}  {:>15d}  {:>15d}  {:>15d}'.format(os.path.basename(x), offset, size, compress_size))
    zf.close()


if __name__ == "__main__":
    filename = 'update.zip'
    show_zipfile(filename)

计算当前目录下 “update.zip” 压缩包内各文件的 offset 和 size:

$ python3 zip_info.py
update.zip:

                     name           offset             size    compress_size
-------------------------  ---------------  ---------------  ---------------
                 metadata               69              357              357
             care_map.txt              474              217              217
              payload.bin              738        271041806        271041806
   payload_properties.txt        271042602              154              154
                  otacert        271042814             1675              943

3. 总结

1. 从 Android 8.0 (O) 开始,制作升级包时会同时将 offset 和 size 信息输出到 META-INF/com/android/metadata 文件中。

2. 通过 zipinfo 工具,使用命令 zipinfo -v update.zip payload.bin 获取 payload.bin 文件的详细信息,然后通过下面的方式计算 offset:

offset(data) = offset(local file header) + size(local file header) 
             = offset(local file header) + 30 + len(file name) + len(extra filed)

     具体的分析请参考 2.2 节。

3. 使用这里提供的 python3 工具计算 update.zip 包内各数据的 offset 和 size 信息

    具体的代码和样例输出,参考 2.3 节。

4. 其它

到目前为止,我写过 Android OTA 升级相关的话题包括:

基础入门:《Android A/B 系统》系列
核心模块:《Android Update Engine 分析》 系列
动态分区:《Android 动态分区》 系列
虚拟 A/B:《Android 虚拟 A/B 分区》系列
升级工具:《Android OTA 相关工具》系列
更多这些关于 Android OTA 升级相关文章的内容,请参考《Android OTA 升级系列专栏文章导读》。
————————————————
版权声明:本文为CSDN博主「洛奇看世界」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/guyongqiangx/article/details/122498561文章来源地址https://www.toymoban.com/news/detail-814957.html

到了这里,关于Android A/B System OTA分析(六)如何获取 payload 的 offset 和 size的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【干货】Android系统定制基础篇:第七部分-Android OTA升级(系统、应用)

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

    2024年02月09日
    浏览(57)
  • Android 系统级APP 升级方案 OTA全流程

    支持原创,请关注专栏: 高质量文章导航 一.Android ota固件编译 OTA 介绍 OTA ( over the air )升级是 Android 系统提供的标准软件升级方式。它功能强大,提供了 完全升级(完整包)、增量升级模式(差异包),可以通过本地升级,也可以通过网络升级 1.完整包 完整包所包含内容

    2024年02月02日
    浏览(79)
  • Android OTA 相关工具(七) 使用 lpunpack 解包 super.img

    从 Android 10(Q) 开始,引入了动态分区,伴随的就是一组动态分区内容数据增删改查相关的操作,以及这些操作所需要的工具,包括 lpdump, lpmake, lpunpack, lpadd, lpflash。 工具名称前缀 lp 表示是 logic partition,即逻辑分区。 所谓逻辑分区,是相对于物理分区而言,因为动态分区内部

    2024年02月02日
    浏览(76)
  • Android查看签名信息系列 · 使用逆向分析工具JadxGUI获取签名

    前言 Android查看签名信息系列之使用逆向分析工具JadxGUI获取签名,通过这种方式,可以获取到的签名信息包括:MD5、SHA1、SHA-256、公钥(模数)等信息 实现方法 1、进入JadxGUI目录下的lib文件夹内,找到jadx-gui-1.4.7.jar文件 2、双击jadx-gui-1.4.7.jar进入图形界面,或者cmd进入lib所在路径

    2024年02月03日
    浏览(44)
  • Android 9.0 ota升级关于SettingsProvider新增和修改系统数据相关功能实现

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

    2024年01月22日
    浏览(63)
  • Android 10.0 ota升级关于SettingsProvider新增和修改系统数据相关功能实现

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

    2024年02月10日
    浏览(46)
  • Android 如何获取有效的DeviceId

    从 Android 10 开始,应用必须具有 READ_PRIVILEGED_PHONE_STATE 特许权限才能访问设备的不可重置标识符(包含 IMEI 和序列号)。 而这个权限是系统权限,也就是说一般应用将无法再获取IMEI 和序列号 受影响的方法包括: Build getSerial() TelephonyManager getImei() getDeviceId() getMeid() getSimSeria

    2024年02月16日
    浏览(33)
  • 第二章 FPGA OTA升级方案的分析及简单用例测试

    FPGA程序运行的方式有两种方式: (1)加载到本地RAM(掉电不保存) (2)将程序固化到FLASH中(掉电保存),FPGA上电后自动从地址0加载固件 Xilinx 7系列有Multiboot设计,这种设计允许在应用现场支持FPGA在线加载多种不同应用,并可支持回退。但是需要说明的一点,Virtex®-7

    2024年02月08日
    浏览(42)
  • Android端恶意代码检测学习之路——(2)静态分析(apk数据集的获取)

    上次只是搞了一个apk进行测试,那必是不得行啊!那不得需要良性以及恶意数据集吗? 在网上找了很久,没有找到合适的,况且就算找到了,不能确定到底是不是良性,所以!我决定!写一个爬虫爬取豌豆荚apk(按照排行榜来顺序下载)。 可是我不会写爬虫啊!怎么办,学

    2023年04月11日
    浏览(56)
  • Android Compose 如何获取位置和大小。

      boxRect.value = coordinates.boundsInParent() 是针对当前父布局。如果想针对整个手机可以用

    2024年02月08日
    浏览(33)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包