76 lines
2.6 KiB
Python
76 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
|
import subprocess, os, glob, sys, time, struct
|
|
|
|
RPP = "/home/m/soothe-bt/render_long.rpp"
|
|
proc = subprocess.Popen(['reaper', '-nosplash', '-renderproject', RPP],
|
|
stdout=open('/tmp/rtdeep2.log', 'w'), stderr=subprocess.STDOUT)
|
|
print('reaper', proc.pid, flush=True)
|
|
|
|
|
|
def find_hosts():
|
|
out = []
|
|
for p in glob.glob('/proc/[0-9]*'):
|
|
try:
|
|
pid = int(os.path.basename(p))
|
|
m = open(f'/proc/{pid}/maps').read()
|
|
c = open(f'/proc/{pid}/cmdline', 'rb').read().decode('utf8', 'replace')
|
|
if 'soothe2' in m and 'yabridge-host.exe' in c:
|
|
out.append(pid)
|
|
except Exception:
|
|
pass
|
|
return out
|
|
|
|
|
|
def scan(pid):
|
|
# strategy: enumerate every readable chunk; build set of img addresses whose content is 0x18052xxxx
|
|
# then find heap words equal to any such address
|
|
mem = os.open(f'/proc/{pid}/mem', os.O_RDONLY)
|
|
img_sp = set() # vtbl-slot candidates: addrs in module image holding 0x18052xxxx
|
|
heap_addrs = [] # (va, chunk) heap chunks
|
|
maps = open(f'/proc/{pid}/maps').read()
|
|
for line in maps.splitlines():
|
|
p = line.split()
|
|
lo, hi = (int(x, 16) for x in p[0].split('-'))
|
|
if 'r' not in p[1]:
|
|
continue
|
|
try:
|
|
d = os.pread(mem, hi - lo, lo)
|
|
except Exception:
|
|
continue
|
|
if lo < 0x180000000 < hi or (0x180000000 <= lo < 0x183000000):
|
|
for off in range(0, len(d) - 7, 8):
|
|
q = struct.unpack_from('<Q', d, off)[0]
|
|
if 0x180520000 <= q < 0x180555000:
|
|
img_sp.add(lo + off)
|
|
else:
|
|
heap_addrs.append((lo, d))
|
|
os.close(mem)
|
|
print('img SP-slot addrs found:', len(img_sp), flush=True)
|
|
# find heap objects pointing into img_sp
|
|
found = []
|
|
for lo, d in heap_addrs:
|
|
for s in img_sp:
|
|
t = struct.pack('<Q', s)
|
|
i = 0
|
|
while True:
|
|
i = d.find(t, i)
|
|
if i < 0:
|
|
break
|
|
found.append((s, lo + i))
|
|
i += 1
|
|
return img_sp, found
|
|
|
|
res = {}
|
|
t0 = time.time()
|
|
while time.time() - t0 < 80:
|
|
for pid in find_hosts():
|
|
if pid in res:
|
|
continue
|
|
img_sp, found = scan(pid)
|
|
res[pid] = (img_sp, found)
|
|
print('PID', pid, 'objects pointing to SP-method vtbl:', len(found), flush=True)
|
|
for s, a in found[:30]:
|
|
print(f' slotslot {s:#x} object@{a:#x}', flush=True)
|
|
time.sleep(0.4)
|
|
proc.kill()
|
|
print('done', flush=True) |