国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

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

這篇具有很好參考價(jià)值的文章主要介紹了Android A/B System OTA分析(六)如何獲取 payload 的 offset 和 size。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

Android A/B 系統(tǒng)基礎(chǔ)入門(mén)系列《Android A/B 系統(tǒng)》已完結(jié),文章列表:

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

Android A/B System OTA分析(二)系統(tǒng)image的生成

Android A/B System OTA分析(三)主系統(tǒng)和bootloader的通信

Android A/B System OTA分析(四)系統(tǒng)的啟動(dòng)和升級(jí)

Android A/B System OTA分析(五)客戶(hù)端參數(shù)

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


更多關(guān)于 Android OTA 升級(jí)相關(guān)文章,請(qǐng)參考《Android OTA 升級(jí)系列專(zhuān)欄文章導(dǎo)讀》。

上一篇《Android A/B System OTA分析(五)客戶(hù)端升級(jí)的參數(shù)》提到升級(jí)時(shí) offset 和 size 參數(shù)分別用于升級(jí)時(shí)設(shè)置遠(yuǎn)程文件中 payload 數(shù)據(jù)的起始地址和長(zhǎng)度,但并沒(méi)有提到如何獲得這個(gè) offset 和 size 值。本篇詳細(xì)說(shuō)明如何計(jì)算和獲取這兩個(gè)參數(shù)。

我寫(xiě)東西通常想把來(lái)龍去脈都寫(xiě)清楚,因此也會(huì)很繁瑣,以下是對(duì)本文快速導(dǎo)航:

*? 如果你只想知道 Android O 開(kāi)始,腳本中是如何計(jì)算 offset 和 size 參數(shù)的,請(qǐng)轉(zhuǎn)到 2.1 節(jié)。
*? 如果你只想知道命令行如何手工獲取 offset 和 size 參數(shù),請(qǐng)轉(zhuǎn)到第 2.2 節(jié)。
*? 如果你想找一個(gè)單獨(dú)的腳本工具計(jì)算 offset 和 size,請(qǐng)轉(zhuǎn)到第 3.3 節(jié)


1. zip 文件的格式

要想知道壓縮包中每個(gè)文件的 offset 和 size 是如何計(jì)算的,就先需要了解下 zip 文件的格式。

對(duì)于這種要了解標(biāo)準(zhǔn)或文件格式的情況,我一般推薦閱讀官方文檔。官方文檔雖然枯燥,但是是第一手信息。再配上網(wǎng)上其它的分析文章,這樣閱讀理解起來(lái)會(huì)比較容易,也不容易出現(xiàn)錯(cuò)誤。

維基百科頁(yè)面《ZIP (file format) 》提供了多個(gè) 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

關(guān)于 zip 文件的歷史,有興趣的也請(qǐng)自行參考維基百科:《ZIP (file format) 》

在 v6.3.2 版文檔的第 V 節(jié)詳細(xì)描述了 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]

總體來(lái)說(shuō),zip 文件由多個(gè)文件組成,每個(gè)文件由 “l(fā)oacal file header”, “file data” 和 “data descriptor” 3 部分組成,多個(gè)文件時(shí)各文件數(shù)據(jù)依次排列。

在文件結(jié)束后有一些其它數(shù)據(jù),由于我們只關(guān)心每個(gè)文件的 offset 和 size,所以可以暫時(shí)不用考慮文件末尾的那些數(shù)據(jù),雖然可能也很重要。

1.2 local file header

zip 文件中,每個(gè)文件的第一部分就是 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 中,前面的是定長(zhǎng)部分的數(shù)據(jù),一共 30 bytes;后面還有兩個(gè)變長(zhǎng)的部分 file name 和 extra field,這兩部分的具體長(zhǎng)度由定長(zhǎng)部分的 file name length 和 extra filed length 指定。

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

1.3 file data

緊挨著 local file header 的是文件數(shù)據(jù) file data,根據(jù)具體的情況,這里的數(shù)據(jù)可能是壓縮的,也可能是沒(méi)有壓縮的,具體長(zhǎng)度由 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

這部分?jǐn)?shù)據(jù)并不是必須的,只有當(dāng) local file header 結(jié)構(gòu)中 general purpose bit flag 的 bit 3 被設(shè)置以后才存在,其內(nèi)容也是用來(lái)指定文件數(shù)據(jù)長(zhǎng)度的。

為什么會(huì)出現(xiàn)這種情況呢? 這是因?yàn)橛行┣闆r下,一開(kāi)始是不知道文件數(shù)據(jù)大小的。例如,用錄像機(jī)錄像時(shí),其數(shù)據(jù)壓縮存儲(chǔ),一開(kāi)始錄制的時(shí)候并不能確定最終文件多大,但這些數(shù)據(jù)又需要不斷寫(xiě)入存儲(chǔ)介質(zhì),所以就在開(kāi)始的時(shí)候設(shè)置一個(gè)標(biāo)志位,表示其大小存儲(chǔ)在數(shù)據(jù)結(jié)束的地方。

1.5 offset 和 size 的計(jì)算

由于我們這里只關(guān)心 offset 和 size 的計(jì)算,所以 zip 文件后面的那些數(shù)據(jù)暫時(shí)不管了。

只需要拿到每個(gè)文件在 zip 包中的 local file header 數(shù)據(jù)就可以計(jì)算得到 offset 和 size 數(shù)值。

文件數(shù)據(jù)的起始位置(offset):

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

文件數(shù)據(jù)的大小(size):

# 壓縮后數(shù)據(jù)大小
size = comressed size

# 原始數(shù)據(jù)大小
size = uncompressed size


最后,一張圖描述 zip 文件的主要結(jié)構(gòu),方便參考:

Android A/B System OTA分析(六)如何獲取 payload 的 offset 和 size,Android OTA A/B System?,gitee
1.6 關(guān)于 encryption header

從 APPNOTE.TXT - .ZIP File Format Specification Version, 6.3.3 開(kāi)始,zip 文件新增了一個(gè) 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 只有在壓縮包的數(shù)據(jù)被加密的情況下才會(huì)出現(xiàn),由于 Android 的 update.zip 包并未加密,不會(huì)出現(xiàn) encryption header,因此接下來(lái)的討論都默認(rèn)沒(méi)有 encryption header 。

2. 獲取 offset 和 size 的三種方式

上一節(jié)介紹了 zip 文件的結(jié)構(gòu),接下來(lái)就可以根據(jù)這個(gè)結(jié)構(gòu)去獲取 offset 和 size 數(shù)據(jù)。

2.1 Android O 開(kāi)始自動(dòng)生成 offset 和 size 數(shù)據(jù)

1. metadata 示例
從 Android 8.0 (O) 開(kāi)始,制作升級(jí)包時(shí),會(huì)自動(dòng)計(jì)算 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 鍵值對(duì)就記錄了多個(gè)文件的 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 數(shù)據(jù)的代碼位于腳本 ota_from_target_files 中,見(jiàn)下面的代碼片段:

*? 計(jì)算多個(gè)文件的 offset 和 size
? ?從第 971 行開(kāi)始,定義了函數(shù) 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.
    """

    #
    # 根據(jù)文件名 name, 獲取對(duì)應(yīng)文件的 offset 和 size 并用這樣的格式輸出: 'filename:offset:size'
    # 如: payload.bin:738:271041806
    #
    def ComputeEntryOffsetSize(name):
      """Compute the zip entry offset and size."""
      # 提取文件名 name 對(duì)應(yīng)的 zipinfo 對(duì)象
      info = zip_file.getinfo(name)
      # 根據(jù) zipinfo 對(duì)象的 header_offset 和 FileHeader 長(zhǎng)度, 得到文件數(shù)據(jù)的 offset
      offset = info.header_offset + len(info.FileHeader())
      # 使用 zipinfo 對(duì)象的 file_size 作為 size (這里的 file_size 是文件壓縮前的大小,壓縮后的大小為 compress_size)
      size = info.file_size
      return '%s:%d:%d' % (os.path.basename(name), offset, size)

    #
    # 獲取以下文件的 offset 和 size 數(shù)據(jù):
    # 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'))

    #
    # 計(jì)算 'META-INF/com/android/metadata' 文件的 offset 和 size 時(shí),預(yù)留了格式: 'metadata:          ' (10個(gè)空格)
    #
    # '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' 數(shù)據(jù)用逗號(hào)連接成一個(gè)字符串返回
    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 寫(xiě)入 metadata 文件
? ?第 1213 行代碼開(kāi)始,計(jì)算輸出的 zip 文件的 offset 和 size 信息寫(xiě)入 metadata 文件的 ota-streaming-property-files 鍵值對(duì)中。但這里 metadata 文件自身的 offset 和 size 并沒(méi)有計(jì)算。

  # 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 手工計(jì)算

linux 命令行工具 zipinfo 可以用來(lái)提取 zip 文件的信息。

1. 安裝 zipinfo
? ?這個(gè)工具默認(rèn)情況下沒(méi)有安裝,ubuntu 上可以通過(guò)以下命令安裝:

sudo apt install unzip

2. 使用 zipinfo 解析 update.zip 文件
? ? *? zipinfo 幫助信息
? ? ? ?可以通過(guò) zipinfo 查看簡(jiǎn)略的幫助信息,或者通過(guò) man zipinfo 查看詳盡的內(nèi)容

$ 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

*? 不帶參數(shù), 列舉 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 選項(xiàng)解析 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.

上面執(zhí)行命令 zipinfo -v update.zip,會(huì)打印了 update.zip 包中所有文件的詳細(xì)信息。

如果只想查看單個(gè)文件的信息,可以在后面添加想查看的文件名,如: 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 文件的詳細(xì)信息。

3. 從 zipinfo 結(jié)果中手工計(jì)算 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 的長(zhǎng)度分別為 11 bytes 和 6 bytes
*? compressed size 和 uncompressed size 大小一樣,都是 271041806 bytes

因此,payload.bin 文件的數(shù)據(jù)在 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 說(shuō)明 payload.bin 文件并沒(méi)有被壓縮,只是打包到了 zip 文件而已,在數(shù)據(jù)被壓縮的情況下,則其在壓縮包中的大小應(yīng)該是 compressed size。

在前面的 python 代碼中,其 zipinfo.file_size 就是這里的 uncompressed size,否則應(yīng)該使用 compressed size 數(shù)據(jù)。

所以,我覺(jué)得腳本中應(yīng)該使用 zipinfo.compress_size 作為 size 大小最為合適,offset ~ compress_size 才是 payload.bin 在 zip 包中的具體數(shù)據(jù)。

2.3 使用 python 腳本計(jì)算

簡(jiǎn)單修改一下 Android O 腳本中的代碼,就可以生成一個(gè)計(jì)算 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)

計(jì)算當(dāng)前目錄下 “update.zip” 壓縮包內(nèi)各文件的 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. 總結(jié)

1. 從 Android 8.0 (O) 開(kāi)始,制作升級(jí)包時(shí)會(huì)同時(shí)將 offset 和 size 信息輸出到 META-INF/com/android/metadata 文件中。

2. 通過(guò) zipinfo 工具,使用命令 zipinfo -v update.zip payload.bin 獲取 payload.bin 文件的詳細(xì)信息,然后通過(guò)下面的方式計(jì)算 offset:

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

? ? ?具體的分析請(qǐng)參考 2.2 節(jié)。

3. 使用這里提供的 python3 工具計(jì)算 update.zip 包內(nèi)各數(shù)據(jù)的 offset 和 size 信息

? ? 具體的代碼和樣例輸出,參考 2.3 節(jié)。

4. 其它

到目前為止,我寫(xiě)過(guò) Android OTA 升級(jí)相關(guān)的話(huà)題包括:

基礎(chǔ)入門(mén):《Android A/B 系統(tǒng)》系列
核心模塊:《Android Update Engine 分析》 系列
動(dòng)態(tài)分區(qū):《Android 動(dòng)態(tài)分區(qū)》 系列
虛擬 A/B:《Android 虛擬 A/B 分區(qū)》系列
升級(jí)工具:《Android OTA 相關(guān)工具》系列
更多這些關(guān)于 Android OTA 升級(jí)相關(guān)文章的內(nèi)容,請(qǐng)參考《Android OTA 升級(jí)系列專(zhuān)欄文章導(dǎo)讀》。
————————————————
版權(quán)聲明:本文為CSDN博主「洛奇看世界」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/guyongqiangx/article/details/122498561文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-814957.html

到了這里,關(guān)于Android A/B System OTA分析(六)如何獲取 payload 的 offset 和 size的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包