#!/usr/bin/env python3 """hunt2.py — enumerate ALL soothe2 module instances during offline render. Chunk-correct full-heap scan (rendersnap-style) collecting EVERY ctx candidate (vtable 0x1824AC210 or m48 marker), not just the first. Per candidate: sens, fir43/fir171 (via ctx+0x540668 ptr), scalar bank snapshot. Goal: find the GUI/DSP pair (24c/24j): visible instance holds shallow kernel while audio is processed by another instance with the deep one. """ import hashlib import os import signal import struct import subprocess import sys import time import numpy as np VT = struct.pack(' 1 else '/tmp/opencode/multi.rpp' subprocess.run("pkill -9 -x reaper; pkill -9 -f '[y]abridge'; " "rm -rf /run/user/1000/yabridge-soothe2_x64-*; sleep 1", shell=True) proc = subprocess.Popen(['/usr/bin/reaper', '-nosplash', '-ignoreerrors', '-renderproject', rpp], stdout=open('/dev/null', 'w'), stderr=subprocess.STDOUT) t0 = time.time() host = None while time.time() - t0 < 30 and not host: host = find_host() time.sleep(0.001) if not host: print('NO HOST') return 1 fd = os.open(f'/proc/{host}/mem', os.O_RDONLY) def rd(a, n): try: return os.pread(fd, n, a) except OSError: return None def scan_all(): found = {} for line in open(f'/proc/{host}/maps'): parts = line.split() if 'rw' not in parts[1]: continue lo, hi = (int(x, 16) for x in parts[0].split('-')) CH = 16 * 1024 * 1024 a = lo while a < hi: d = rd(a, min(CH + 4096, hi - a)) if not d: break for pat, off in ((VT, 0), (M48, -0x24)): j = d.find(pat) while j >= 0: cand = a + j + off if cand not in found: sb = rd(cand + 0x540870, 4) if sb and struct.unpack(' 100: found[cand] = True j = d.find(pat, j + 1) a += CH return list(found) known = {} rounds = 0 while time.time() - t0 < 25: rounds += 1 try: os.kill(host, signal.SIGSTOP) except ProcessLookupError: break try: cands = scan_all() new = [c for c in cands if c not in known] for c in new: known[c] = rounds pb = rd(c + 0x540668, 8) m43 = m171 = -1 if pb: p = struct.unpack(' 0x10000: fb = rd(p, 2049 * 8) if fb: arr = np.frombuffer(fb[:2049 * 8], dtype=' 0x10000: fb = rd(p, 2049 * 8) if fb: arr = np.frombuffer(fb[:2049 * 8], dtype='