#!/usr/bin/env python3 # read_va.py - dump a guest process's memory at a VA (GPU VAs of UVM sysmem # objects are usually also valid CPU VAs in the owning process). # # Usage: # sudo python3 read_va.py [len] [--u32] # # --u32 prints one little-endian u32 per line (method-stream friendly). import os import sys def main(): if len(sys.argv) < 3: print(__doc__) return 1 pid = int(sys.argv[1]) va = int(sys.argv[2], 16) ln = 256 as_u32 = False for a in sys.argv[3:]: if a == '--u32': as_u32 = True else: ln = int(a, 0) found = False with open('/proc/%d/maps' % pid) as f: for line in f: rng = line.split()[0] a, b = rng.split('-') if int(a, 16) <= va < int(b, 16): print('MAP: %s' % line.strip()) found = True break if not found: print('VA 0x%x not in maps' % va) mem = os.open('/proc/%d/mem' % pid, os.O_RDONLY) try: data = os.pread(mem, ln, va) except OSError as e: print('read error: %s' % e) return 1 finally: os.close(mem) if as_u32: for i in range(0, len(data) - 3, 4): print('+0x%03x: 0x%08x' % (i, int.from_bytes(data[i:i + 4], 'little'))) else: for i in range(0, len(data), 16): chunk = data[i:i + 16] hexs = ' '.join('%02x' % b for b in chunk) print('+0x%03x: %s' % (i, hexs)) return 0 if __name__ == '__main__': sys.exit(main())