44 lines
1.3 KiB
Python
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) |