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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
import gdb, sys
inf = gdb.selected_inferior()
pid = inf.pid
base = None
for line in open("/proc/%d/maps" % pid):
if "libnvidia-eglcore.so.570.144" in line:
parts = line.split()
lo, hi = [int(x, 16) for x in parts[0].split('-')]
off = int(parts[2], 16)
if off == 0:
base = lo
break
if base is None:
print("EGLBASE not found"); gdb.execute("detach"); sys.exit(1)
print("EGLBASE 0x%x PID %d" % (base, pid))
maps = []
for line in open("/proc/%d/maps" % pid):
parts = line.split()
try:
lo, hi = [int(x, 16) for x in parts[0].split('-')]
maps.append((lo, hi, parts[1], parts[-1] if len(parts) > 5 else "anon"))
except Exception:
pass
def resolve(addr):
for lo, hi, perm, name in maps:
if lo <= addr < hi:
return "0x%x-0x%x %s %s" % (lo, hi, perm, name)
return "?"
def rd(a, n):
return inf.read_memory(a, n).tobytes()
def u32(a):
return int.from_bytes(rd(a, 4), 'little')
def u64(a):
return int.from_bytes(rd(a, 8), 'little')
state = {"done": False}
class B(gdb.Breakpoint):
def __init__(self, spec, fn, limit=100000):
super().__init__(spec, internal=False)
self.fn = fn; self.limit = limit; self.hits = 0
self.silent = True
def stop(self):
self.hits += 1
try:
stop = bool(self.fn(self))
except Exception as e:
print("ERR@0x%x %s" % (int(gdb.parse_and_eval("$pc")), e))
stop = False
return stop or self.hits >= self.limit
def loophead(bp):
if state["done"]:
return False
state["done"] = True
rbx = int(gdb.parse_and_eval("$rbx"))
sub = u64(rbx+0x70)
print("WAIT rbx=0x%x sub=0x%x" % (rbx, sub))
try:
obj2 = u64(sub+0x58)
off = u32(obj2+0x60)
holder = u64(obj2+0x58)
base2 = u64(holder+0x58)
word_addr = base2 + off
val = u32(word_addr)
print("WAIT obj2=0x%x off=0x%x holder=0x%x base=0x%x word=0x%x val=0x%x" %
(obj2, off, holder, base2, word_addr, val))
print("WAIT word map:", resolve(word_addr))
print("WAIT holder obj2+0x50=0x%x obj2+0x64=0x%x" % (u64(obj2+0x50), u32(obj2+0x64)))
try:
hd = rd(holder, 0x30)
print("WAIT holder dump:", " ".join("%02x" % b for b in hd))
except Exception as e:
print("WAIT holder dump err", e)
except Exception as e:
print("WAIT chain err", e)
# dump the client's nvidiactl rw-s mappings
print("WAIT nvidiactl maps:")
for lo, hi, perm, name in maps:
if "nvidiactl" in name and "rw-s" in perm:
print(" 0x%x-0x%x size=0x%x" % (lo, hi, hi-lo))
return True
B("*0x%x" % (base+0xdcebd9), loophead, 1)
try:
gdb.execute("continue")
except gdb.error as e:
print("CONT-ERR %s" % e)
print("TRACE-END")
try:
gdb.execute("detach")
except gdb.error as e:
print("DETACH-ERR %s" % e)
gdb.execute("quit")
|