Files
ext4recovery/test/patch4.py
2026-04-30 11:04:05 +00:00

42 lines
1.1 KiB
Python

import struct, binascii
# We need to recompute the GDT checksum for group 0
# after modifying its flags
#
# ext4 GDT checksum = crc32c(uuid + group_num_le16 + gdt_entry_with_csum_zeroed)
# The checksum seed is stored in the superblock at offset 408
with open('/dev/nbd0','rb') as f:
f.seek(1024)
sb = f.read(1024)
uuid = sb[104:120]
csum_seed = struct.unpack_from('<I', sb, 408)[0]
print(f'UUID: {uuid.hex()}')
print(f'csum_seed: 0x{csum_seed:08x}')
# Install crcmod for crc32c
import crcmod
crc32c_fn = crcmod.predefined.mkCrcFun('crc-32c')
data = bytearray(open('/tmp/merged_gdt.bin','rb').read())
def compute_gdt_csum(g, entry):
e = bytearray(entry)
struct.pack_into('<H', e, 30, 0) # zero checksum field
grp_le = struct.pack('<H', g)
csum_data = uuid + grp_le + bytes(e)
csum = crc32c_fn(csum_data, csum_seed)
return csum & 0xFFFF
# Recompute checksum for group 0 only
g = 0
entry = data[0:64]
csum = compute_gdt_csum(g, entry)
struct.pack_into('<H', data, 30, csum)
print(f'Group 0 new checksum: 0x{csum:04x}')
with open('/tmp/merged_gdt.bin','wb') as f:
f.write(data)
print('Saved')