1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
#!/usr/bin/env python3
# Guest-side: read the nv_vm_map_pages vmap areas via /proc/kcore and find the
# GPFIFO entry pattern (entry0 raw 0x0005980004480000 for va=0x4480000 len=1432).
import struct, sys
pat = bytes.fromhex("0000480400980500") # 0x0005980004480000 LE
class Kcore:
def __init__(self):
self.fd = open("/proc/kcore", "rb")
hdr = self.fd.read(64)
e_phoff = struct.unpack_from("<Q", hdr, 32)[0]
e_phentsize, e_phnum = struct.unpack_from("<HH", hdr, 54)
self.segs = []
for i in range(e_phnum):
self.fd.seek(e_phoff + i * e_phentsize)
ph = self.fd.read(56)
p_type, _fl, p_off, p_va, _pa, p_sz = struct.unpack_from("<IIQQQQ", ph, 0)
if p_type == 1:
self.segs.append((p_va, p_va + p_sz, p_off))
def read(self, va, n):
for lo, hi, off in self.segs:
if lo <= va and va + n <= hi:
self.fd.seek(off + (va - lo))
return self.fd.read(n)
return None
kc = Kcore()
areas = []
for line in open("/proc/vmallocinfo"):
p = line.split()
if len(p) < 2: continue
if "nv_vm_map_pages" not in line: continue
lo, hi = p[0].split("-")
areas.append((int(lo, 16), int(hi, 16)))
print("nv_vm_map_pages areas:", len(areas))
for lo, hi in areas:
size = hi - lo
d = kc.read(lo, size)
if not d:
print(" 0x%x-0x%x unreadable" % (lo, hi)); continue
idx = d.find(pat)
print(" 0x%x-0x%x size=0x%x hit=%s" % (lo, hi, size, ("+0x%x -> VA 0x%x" % (idx, lo + idx)) if idx >= 0 else "no"))
if idx >= 0:
# dump the page around the hit
base = lo + (idx & ~0xfff)
page = kc.read(base, 0x100)
print(" page head: %s" % page.hex())
|