""" inspect_regions.py [N] Print the first 0x80 bytes of N sample 256-512 KB private RW regions. Useful for eyeballing what the leaked allocations contain. """ import sys, os from minidump.minidumpfile import MinidumpFile def _enum_int(v): if v is None: return 0 if hasattr(v, 'value'): return int(v.value) return int(v) def hexdump(buf, base): lines = [] for i in range(0, len(buf), 16): chunk = buf[i:i+16] hexs = " ".join(f"{b:02x}" for b in chunk) ascii = "".join(chr(b) if 32 <= b < 127 else "." for b in chunk) lines.append(f" {base+i:08x} {hexs:<47} {ascii}") return "\n".join(lines) def main(): dump = sys.argv[1] n = int(sys.argv[2]) if len(sys.argv) > 2 else 12 md = MinidumpFile.parse(dump) reader = md.get_reader().get_buffered_reader() cands = [] for r in md.memory_info.infos: st = _enum_int(r.State) ty = _enum_int(r.Type) pr = _enum_int(r.Protect) & 0xFF sz = r.RegionSize if st == 0x1000 and ty == 0x20000 and pr in (0x04, 0x40) \ and 256*1024 <= sz < 512*1024: cands.append((r.BaseAddress, sz)) print(f"=== {os.path.basename(dump)} : {len(cands)} candidate 256-512KB regions ===") # Sample evenly across all candidates step = max(1, len(cands) // n) samples = cands[::step][:n] for base, size in samples: print(f"\n--- region 0x{base:08x} size={size} ({size/1024:.1f} KB) ---") try: reader.move(base) buf = reader.read(0x80) except Exception as e: print(f" read failed: {e}"); continue print(hexdump(buf, base)) if __name__ == "__main__": main()