runtime capture: registry heartbeat decodes live DSP tables (WIN 0.540658, freq-axis@48k, per-bin weights), rtsnap_fast/findctx/rtchunk infra
This commit is contained in:
+59
-36
@@ -1,29 +1,25 @@
|
||||
#!/usr/bin/env python3
|
||||
"""rtdeep2.py — find DSP ctx object via phase-table pointer beacon, then dump window 0x540658 & neighbors."""
|
||||
import subprocess, time, glob, os, struct, sys
|
||||
import subprocess, time, glob, os, sys
|
||||
import numpy as np
|
||||
import struct
|
||||
|
||||
RPP = sys.argv[1] if len(sys.argv) > 1 else '/home/m/soothe-bt/dual300.rpp'
|
||||
BEACON = 0x182615608 # VA of phase_table_1024 (static .data)
|
||||
BEACON = np.uint64(0x182615608)
|
||||
|
||||
|
||||
def vst_base(pid):
|
||||
lo = None
|
||||
for line in open(f'/proc/{pid}/maps').read().splitlines():
|
||||
if 'soothe2' not in line:
|
||||
continue
|
||||
a = int(line.split()[0].split('-')[0], 16)
|
||||
lo = a if lo is None else min(lo, a)
|
||||
return lo
|
||||
def get_maps(pid):
|
||||
try:
|
||||
return open(f'/proc/{pid}/maps').read()
|
||||
except Exception:
|
||||
return ''
|
||||
|
||||
|
||||
def readable_regions(pid):
|
||||
out = []
|
||||
for line in open(f'/proc/{pid}/maps').read().splitlines():
|
||||
for line in get_maps(pid).splitlines():
|
||||
p = line.split()[0]
|
||||
lo, hi = int(p.split('-')[0], 16), int(p.split('-')[1], 16)
|
||||
if 'vst3' in line:
|
||||
continue # skip module itself
|
||||
out.append((lo, hi))
|
||||
return out
|
||||
|
||||
@@ -35,17 +31,28 @@ def find_beacon(pid):
|
||||
return []
|
||||
res = []
|
||||
for lo, hi in readable_regions(pid):
|
||||
sz = (hi - lo) & ~7
|
||||
sz = hi - lo
|
||||
if sz <= 0 or sz > 0x200000000:
|
||||
continue
|
||||
try:
|
||||
buf = os.pread(mem, sz, lo)
|
||||
except Exception:
|
||||
if sz < 65536:
|
||||
continue
|
||||
arr = np.frombuffer(buf, dtype='<u8')
|
||||
idx = np.where(arr == BEACON)[0]
|
||||
for i in idx:
|
||||
res.append(lo + int(i) * 8)
|
||||
off = 0
|
||||
while off < sz:
|
||||
chunk = min(sz - off, 4 << 20)
|
||||
try:
|
||||
buf = os.pread(mem, int(chunk), lo + off)
|
||||
except Exception:
|
||||
break
|
||||
arr = np.frombuffer(buf[:len(buf) & ~7], dtype='<u8')
|
||||
if len(arr):
|
||||
idx = np.where(arr == BEACON)[0]
|
||||
for i in idx:
|
||||
res.append(lo + off + int(i) * 8)
|
||||
off += int(chunk)
|
||||
if len(res) > 64:
|
||||
break
|
||||
if len(res) > 64:
|
||||
break
|
||||
os.close(mem)
|
||||
return res
|
||||
|
||||
@@ -57,26 +64,42 @@ def main():
|
||||
host = None
|
||||
while time.time() - t0 < 60:
|
||||
for p in glob.glob('/proc/[0-9]*'):
|
||||
try:
|
||||
maps = open(f'/proc/{p}/maps').read()
|
||||
except Exception:
|
||||
continue
|
||||
if 'soothe2' not in maps:
|
||||
continue
|
||||
host = int(os.path.basename(p))
|
||||
break
|
||||
pid = int(os.path.basename(p))
|
||||
if 'soothe2' in (get_maps(pid) or ''):
|
||||
host = pid
|
||||
break
|
||||
if host:
|
||||
break
|
||||
time.sleep(0.05)
|
||||
print(f'host={host}')
|
||||
time.sleep(0.01)
|
||||
print(f'host={host}', flush=True)
|
||||
if not host:
|
||||
proc.kill()
|
||||
proc.wait(timeout=10)
|
||||
return
|
||||
base = vst_base(host)
|
||||
# allow module load: plugin init first
|
||||
mem = os.open(f'/proc/{host}/mem', os.O_RDONLY)
|
||||
t1 = time.time()
|
||||
while time.time() - t1 < 50:
|
||||
regs = []
|
||||
for line in get_maps(host).splitlines():
|
||||
p = line.split()[0]
|
||||
lo, hi = int(p.split('-')[0], 16), int(p.split('-')[1], 16)
|
||||
if 'vst3' in line or 'reaper' in line or 'soothe2' in line and 'rw' not in line.split()[1][:2]:
|
||||
continue
|
||||
if 'rw' not in line.split()[1][:2]:
|
||||
continue
|
||||
if hi - lo > 0x10000000:
|
||||
continue
|
||||
regs.append((lo, hi))
|
||||
print(f'{len(regs)} rw regions to capture', flush=True)
|
||||
with open('/tmp/host_rw.bin', 'wb') as f:
|
||||
for lo, hi in regs:
|
||||
try:
|
||||
buf = os.pread(mem, hi - lo, lo)
|
||||
f.write(lo.to_bytes(8, 'little'))
|
||||
f.write((hi - lo).to_bytes(8, 'little'))
|
||||
f.write(buf)
|
||||
except Exception:
|
||||
pass
|
||||
print(f'captured {os.path.getsize("/tmp/host_rw.bin")} bytes', flush=True)
|
||||
while time.time() - t1 < 30:
|
||||
hits = find_beacon(host)
|
||||
ctxs = set()
|
||||
for p in hits:
|
||||
@@ -96,7 +119,7 @@ def main():
|
||||
blk = os.pread(mem, 0x8000, ctx + 0x540000)
|
||||
open(f'/tmp/ctx_{ctx:x}_win.bin', 'wb').write(blk)
|
||||
break
|
||||
time.sleep(0.2)
|
||||
time.sleep(0.05)
|
||||
os.close(mem)
|
||||
try:
|
||||
proc.wait(timeout=5)
|
||||
|
||||
Reference in New Issue
Block a user