Files

54 lines
2.4 KiB
Python

#!/usr/bin/env python3
"""Parse and verify DA14585 firmware image header (Dialog SUOTA/multi-image format).
Image header layout (64 bytes):
+0x00 u8[2] magic 0x70 0x51 ('pQ' LE word 0x5170) = IMAGE_VALID
+0x02 u8[2] signature version/application id (here 0xAA 0x01)
+0x04 u32 code_size size of code region (= file_size - 64)
+0x08 u32 crc32 CRC over code region
+0x0C 52B reserved 0xFF
"""
import struct, sys, zlib, binascii
IMG = "/mnt/documents/Works/Eink/qianbian/app/firmware-PP_da14585_4.2_CH.img"
def crc32_mpeg(data, init=0xFFFFFFFF, xorout=0, poly=0x04C11DB7):
crc = init
for b in data:
crc ^= b << 24
for _ in range(8):
crc = ((crc << 1) ^ poly) & 0xFFFFFFFF if (crc & 0x80000000) else (crc << 1) & 0xFFFFFFFF
return crc ^ xorout
def main():
data = open(IMG, "rb").read()
print(f"file size: {len(data)} (0x{len(data):x})")
magic = data[0:2]
sig = data[2:4]
code_size, crc_hdr = struct.unpack_from("<II", data, 4)
reserved = data[12:64]
print(f"magic : {magic.hex()} ({magic!r})")
print(f"signature : {sig.hex()}")
print(f"code_size : {code_size} (0x{code_size:x}) file-64 = {len(data)-64}")
print(f"header CRC : 0x{crc_hdr:08x}")
print(f"reserved : all 0xff = {all(b==0xff for b in reserved)}")
print(f"size match : {code_size == len(data)-64}")
code = data[64:64+code_size]
# try CRC variants
c_zlib = zlib.crc32(code) & 0xFFFFFFFF # CRC-32 (reflected, init/xor FF)
c_bzip2 = crc32_mpeg(code, 0xFFFFFFFF, 0xFFFFFFFF) # CRC-32/BZIP2
c_mpeg = crc32_mpeg(code, 0xFFFFFFFF, 0) # CRC-32/MPEG-2
c_posix = crc32_mpeg(code, 0, 0xFFFFFFFF) # CRC-32/POSIX (cksum-ish)
c_jam = zlib.crc32(code, 0xFFFFFFFF) ^ 0 ^ 0xFFFFFFFF # jamcrc style check
print(f"CRC32 zlib : 0x{c_zlib:08x} match={c_zlib==crc_hdr}")
print(f"CRC32 bzip2 : 0x{c_bzip2:08x} match={c_bzip2==crc_hdr}")
print(f"CRC32 mpeg2 : 0x{c_mpeg:08x} match={c_mpeg==crc_hdr}")
print(f"CRC32 posix : 0x{c_posix:08x} match={c_posix==crc_hdr}")
# also try crc over code with initial vector table included (whole thing)
c_zlib_all = zlib.crc32(data[0:64+code_size]) & 0xFFFFFFFF
print(f"CRC32 zlib(all incl hdr): 0x{c_zlib_all:08x}")
if __name__ == "__main__":
main()