#!/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, sys import numpy as np import struct RPP = sys.argv[1] if len(sys.argv) > 1 else '/home/m/soothe-bt/dual300.rpp' BEACON = np.uint64(0x182615608) def get_maps(pid): try: return open(f'/proc/{pid}/maps').read() except Exception: return '' def readable_regions(pid): out = [] for line in get_maps(pid).splitlines(): p = line.split()[0] lo, hi = int(p.split('-')[0], 16), int(p.split('-')[1], 16) out.append((lo, hi)) return out def find_beacon(pid): try: mem = os.open(f'/proc/{pid}/mem', os.O_RDONLY) except Exception: return [] res = [] for lo, hi in readable_regions(pid): sz = hi - lo if sz <= 0 or sz > 0x200000000: continue if sz < 65536: continue 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=' 64: break if len(res) > 64: break os.close(mem) return res def main(): proc = subprocess.Popen(['reaper', '-nosplash', '-renderproject', RPP], stdout=open('/tmp/rtdeep2.log', 'w'), stderr=subprocess.STDOUT) t0 = time.time() host = None while time.time() - t0 < 60: for p in glob.glob('/proc/[0-9]*'): pid = int(os.path.basename(p)) if 'soothe2' in (get_maps(pid) or ''): host = pid break if host: break time.sleep(0.01) print(f'host={host}', flush=True) if not host: proc.wait(timeout=10) return mem = os.open(f'/proc/{host}/mem', os.O_RDONLY) t1 = time.time() 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: for d in (0x540548, 0x540550, 0x540598): ctxc = p - d if 0x10000000 < ctxc < 0x7fff00000000: ctxs.add(ctxc) if ctxs: print(f't={time.time()-t1:.1f}s hits={len(hits)} ctx_cands={sorted(hex(c) for c in ctxs)}', flush=True) for ctx in sorted(ctxs): d = os.pread(mem, 4096, ctx + 0x540658) if len(d) < 4096: continue fl = np.frombuffer(d, dtype='= -1 and fl.max() <= 2: print(f' ctx={hex(ctx)} WIN@+0x540658 head={[round(float(x),4) for x in fl[:8]]} mid={[round(float(x),4) for x in fl[1024:1032]]}', flush=True) blk = os.pread(mem, 0x8000, ctx + 0x540000) open(f'/tmp/ctx_{ctx:x}_win.bin', 'wb').write(blk) break time.sleep(0.05) os.close(mem) try: proc.wait(timeout=5) except Exception: proc.kill() print('done', flush=True) if __name__ == '__main__': main()