#!/usr/bin/env python3 """Hunt for specific wire instance ids anywhere in the client's writable memory. Answers whether a served item was materialised into a record at all, versus materialised but not attached to a collection. A record is recognised by its established layout: id at +0x08, resourceId at +0x18, cardtype at +0x4c. Read-only. Never writes. usage: probe_hunt.py PID id [id ...] """ import re, struct, sys PID = int(sys.argv[1]) IDS = [int(a) for a in sys.argv[2:]] if not IDS: sys.exit("give at least one wire id") mem = open(f"/proc/{PID}/mem", "rb", buffering=0) regions = [] for ln in open(f"/proc/{PID}/maps"): m = re.match(r"([0-9a-f]+)-([0-9a-f]+) (\S{4}) \S+ \S+ \S+\s*(.*)", ln) if not m: continue lo, hi, perms, path = int(m.group(1), 16), int(m.group(2), 16), m.group(3), m.group(4).strip() if "w" not in perms: continue if path.startswith("/") and not path.endswith(".dll") and not path.endswith(".exe"): continue regions.append((lo, hi, perms, path)) total = sum(hi - lo for lo, hi, _, _ in regions) print(f" {len(regions)} writable regions, {total/2**20:.0f} MiB to scan") needles = {struct.pack(" 1000 hits[wid].append((va, rec, ct, sub, cat, res, looks)) a += n print(f" scanned {scanned/2**20:.0f} MiB\n") for wid in IDS: hs = hits[wid] recs = [h for h in hs if h[6]] print(f" id {wid}: {len(hs)} raw occurrence(s), {len(recs)} record-shaped") for va, rec, ct, sub, cat, res, _ in recs[:6]: print(f" record {rec:#x}: cardtype={ct} subtype={sub} category={cat} resourceId={res}") if not recs: print(" NOT MATERIALISED as a record anywhere in writable memory")