Files
ext4recovery/misc_tools/search_var.py
2026-04-30 11:04:05 +00:00

71 lines
2.6 KiB
Python

import struct
CHUNK = 128*512
LV_START = 5120000*512
BSIZE = 4096
# Search for /var directory block by looking for its known contents
# /var should contain: lib, log, cache, spool, tmp, www, etc.
# inode 1310721 with links=15 means 15 entries
# The directory block must contain entry for 'lib' pointing to a valid inode
# Let's search all of md0 for a 4KB block containing 'lib' as a dir entry
# where the parent context suggests it's /var
targets = [b'log', b'cache', b'spool', b'backups', b'mail']
print('Searching for /var directory block...')
print('Looking for block containing multiple /var subdirectory names')
chunk_size = 32*1024*1024
offset = LV_START # start from filesystem area
found_blocks = {}
with open('/dev/md0','rb') as f:
f.seek(0,2)
disk_size = f.tell()
f.seek(offset)
pos = offset
while pos < disk_size:
data = f.read(min(chunk_size, disk_size-pos))
if not data: break
# Look for blocks containing multiple target strings
for blk_off in range(0, len(data)-BSIZE, BSIZE):
block = data[blk_off:blk_off+BSIZE]
matches = sum(1 for t in targets if t in block)
if matches >= 2:
abs_byte = pos + blk_off
# Verify as directory block
entries = []
off = 0
while off < BSIZE-8:
ino = struct.unpack_from('<I', block, off)[0]
rec_len = struct.unpack_from('<H', block, off+4)[0]
name_len= block[off+6]
ftype = block[off+7]
if rec_len < 8: break
if (10 < ino < 500_000_000 and
0 < name_len <= rec_len-8 and
ftype in (1,2,7) and
rec_len % 4 == 0):
name = block[off+8:off+8+name_len].decode('utf-8',errors='replace')
if name.isprintable():
entries.append((ino,name,ftype))
off += rec_len
if len(entries) >= 3:
abs_block = (abs_byte - LV_START) // BSIZE
print(f'Candidate at md0 byte {abs_byte} '
f'(block {abs_block}):')
for ino,name,ftype in entries[:10]:
tname={1:\"file\",2:\"dir\",7:\"link\"}.get(ftype,'?')
print(f' {tname} inode={ino} {name!r}')
print()
pos += chunk_size
if pos % (10*1024**3) == 0:
print(f' Scanned {pos//1024**3}GB...', flush=True)