Files
soothe2-re/rtsnap.py
T

44 lines
1.3 KiB
Python

#!/usr/bin/env python3
"""rtsnap.py — differential snapshot of a live process for ctx discovery.
Captures readable regions page-wise (skipping EIO pages), stores: index(file) + regions.raw
Usage: rtsnap.py <pid> <outprefix>
"""
import os, struct, sys
pid = int(sys.argv[1])
pre = sys.argv[2]
mem = os.open(f'/proc/{pid}/mem', os.O_RDONLY)
regs = []
off = 0
for line in open(f'/proc/{pid}/maps'):
p = line.split()[0]
lo, hi = [int(x, 16) for x in p.split('-')]
perm = line.split()[1]
if perm[0] != 'r':
continue
if 'vst3' in line or 'dri' in line or 'shm' in line:
continue
if hi - lo > 0x40000000:
continue
regs.append((lo, hi))
print(f'{len(regs)} regions', flush=True)
idx = []
raw = bytearray()
for lo, hi in regs:
rstart = len(raw)
sz = 0
for pg in range(lo, hi, 0x1000):
try:
b = os.pread(mem, 0x1000, pg)
raw.extend(b)
sz += len(b)
except Exception:
raw.extend(b'\0' * 0x1000)
idx.append((lo, rstart, sz))
with open(pre + '.raw', 'wb') as f:
f.write(bytes(raw))
with open(pre + '.idx', 'wb') as f:
for lo, rstart, sz in idx:
f.write(struct.pack('<QQQ', lo, rstart, sz))
os.close(mem)
print(f'done: raw={len(raw)} bytes', flush=True)