Initial remote commit
This commit is contained in:
91
misc_tools/offset_check.py
Normal file
91
misc_tools/offset_check.py
Normal file
@@ -0,0 +1,91 @@
|
||||
CHUNK = 128*512 # 64KB
|
||||
LV_START = 5120000*512
|
||||
BSIZE = 4096
|
||||
|
||||
# Block 5251104, virtual byte = 5251104 * 4096 = 21508521984
|
||||
# group=65638, chunk_idx=4, intra=0
|
||||
|
||||
# Physical layout: each group of 5 virtual chunks occupies
|
||||
# 5*CHUNK bytes on the physical disk (md0)
|
||||
# group 65638 starts at:
|
||||
group = 65638
|
||||
group_phys_start = LV_START + group * 5 * CHUNK
|
||||
print(f'Group {group} physical start: {group_phys_start}')
|
||||
print()
|
||||
|
||||
import struct
|
||||
|
||||
with open('/dev/md0','rb') as f:
|
||||
# Read all 5 chunks of this group
|
||||
f.seek(group_phys_start)
|
||||
all_chunks = f.read(5*CHUNK)
|
||||
|
||||
for ci in range(5):
|
||||
chunk = all_chunks[ci*CHUNK:(ci+1)*CHUNK]
|
||||
nonzero = sum(1 for b in chunk if b != 0)
|
||||
# Try first 32 bytes as directory
|
||||
ino = struct.unpack_from('<I', chunk, 0)[0]
|
||||
rec = struct.unpack_from('<H', chunk, 4)[0]
|
||||
nl = chunk[6]
|
||||
ft = chunk[7]
|
||||
print(f'Chunk {ci}: nonzero={nonzero}/{CHUNK}', end='')
|
||||
if 10 < ino < 500_000_000 and 8 <= rec <= 256 and 0 < nl < 32 and ft in (1,2,7):
|
||||
name = chunk[8:8+nl].decode('utf-8',errors='replace')
|
||||
print(f' POSSIBLE DIR: inode={ino} name={name!r}', end='')
|
||||
print()
|
||||
|
||||
# The data chunks (0-3) map to virtual chunks as follows:
|
||||
# Our translation: virtual chunk N -> physical chunk N (for N<4)
|
||||
# So physical chunks 0,1,2,3 = virtual chunks 0,1,2,3
|
||||
# And physical chunk 4 = the metadata chunk we skip
|
||||
|
||||
# But what if our anchor points were right (FAT32 and LV)
|
||||
# yet the internal mapping within the LV is different?
|
||||
# What if the PERC uses a different chunk as metadata inside the LV?
|
||||
|
||||
# Our two anchors:
|
||||
# FAT32 VBR at PERC virtual 2048 -> md0 sector 1664
|
||||
# LV start at PERC virtual 6400000 -> md0 sector 5120000
|
||||
|
||||
# These are BEFORE the LV. Inside the LV, could the chunk order differ?
|
||||
# What if inside the LV the metadata chunk is chunk 0, not chunk 4?
|
||||
|
||||
# Test: read chunk 0 of group 65638 as directory
|
||||
chunk0 = all_chunks[0:CHUNK]
|
||||
print()
|
||||
print('Chunk 0 as directory:')
|
||||
off = 0
|
||||
while off < BSIZE-8:
|
||||
ino = struct.unpack_from('<I', chunk0, off)[0]
|
||||
rec_len = struct.unpack_from('<H', chunk0, off+4)[0]
|
||||
name_len= chunk0[off+6]
|
||||
ftype = chunk0[off+7]
|
||||
if rec_len < 8: break
|
||||
if ino > 0 and name_len > 0:
|
||||
name = chunk0[off+8:off+8+name_len].decode('utf-8',errors='replace')
|
||||
tname = {1:'file',2:'dir',7:'link'}.get(ftype,'?')
|
||||
print(f' {tname} inode={ino} {name!r}')
|
||||
off += rec_len
|
||||
|
||||
# Test each chunk as potential /var directory
|
||||
print()
|
||||
for ci in range(5):
|
||||
chunk = all_chunks[ci*CHUNK:(ci+1)*CHUNK]
|
||||
off = 0
|
||||
entries = []
|
||||
while off < BSIZE-8:
|
||||
ino = struct.unpack_from('<I', chunk, off)[0]
|
||||
rec_len = struct.unpack_from('<H', chunk, off+4)[0]
|
||||
name_len= chunk[off+6]
|
||||
ftype = chunk[off+7]
|
||||
if rec_len < 8: break
|
||||
if 10 < ino < 500_000_000 and name_len > 0 and ftype in (1,2,7):
|
||||
name = chunk[off+8:off+8+name_len].decode('utf-8',errors='replace')
|
||||
if name.isprintable():
|
||||
entries.append((ino, name, ftype))
|
||||
off += rec_len
|
||||
if entries:
|
||||
print(f'Chunk {ci} has {len(entries)} directory entries:')
|
||||
for ino, name, ftype in entries[:5]:
|
||||
tname = {1:'file',2:'dir',7:'link'}.get(ftype,'?')
|
||||
print(f' {tname} inode={ino} {name!r}')
|
||||
Reference in New Issue
Block a user