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
100
101
102
103
104
105
106
107
|
# gdb script: split FUN_00386b90 (ucode image section callback, file
# 0x286b90) - bpz11 showed FUN_00386020 returned 1 from this callback.
#
# FUN_00386b90 has a single epilogue at 0x28712d (mov r15d,eax -> ret).
# Trace every call return, print nonzero values, and report the final
# status + recent history.
#
# Run: sudo gdb -p <cdt-pid> -batch -x /tmp/bpz12.py
import gdb
import time
out = gdb.execute("info proc mappings", to_string=True)
base = None
for line in out.splitlines():
if "libcuda" in line and "r-xp" in line:
f = line.split()
base = int(f[0], 16) - int(f[3], 16)
break
print("BASE=0x%x" % (base or 0))
if base is None:
raise SystemExit
gdb.execute("set pagination off")
gdb.execute("set confirm off")
SITES = [
(0x286b90, "ENTRY"),
(0x286ca8, "c_d0e970"),
(0x286cfa, "c_3ab420"),
(0x286d55, "c_2be020_bool"),
(0x286e77, "c_286250"),
(0x286fe8, "free1"),
(0x286ff4, "free2"),
(0x287000, "free3"),
(0x287009, "free4"),
(0x28701e, "c_2780f0"),
(0x28702a, "c_27b860"),
(0x287069, "c_27cf40"),
(0x287152, "c_d6ba10_a"),
(0x28717c, "free5"),
(0x287188, "free6"),
(0x287194, "free7"),
(0x28719d, "free8"),
(0x28721d, "c_282f50"),
(0x28724a, "c_27baa0"),
(0x287256, "c_27d6c0"),
(0x287269, "c_d6ba10_b"),
(0x287284, "calloc1"),
(0x2872f8, "calloc2"),
(0x28737f, "c_2781e0"),
(0x287433, "qsort"),
(0x28712d, "FRET"),
]
NAMES = dict(SITES)
for off, name in SITES:
gdb.execute("break *0x%x" % (base + off))
t0 = time.time()
hits = 0
hist = []
inv = 0
while hits < 800:
try:
gdb.execute("continue")
except gdb.error as e:
print("CONTINUE_END %s" % e)
break
hits += 1
rip = int(gdb.parse_and_eval("$rip")) & 0xffffffffffffffff
off = rip - base
name = NAMES.get(off, "?")
eax = int(gdb.parse_and_eval("$eax")) & 0xffffffff
r15 = int(gdb.parse_and_eval("$r15d")) & 0xffffffff
if name == "ENTRY":
a1 = int(gdb.parse_and_eval("$rdi")) & 0xffffffffffffffff
q0 = 0
try:
q0 = int(gdb.parse_and_eval("*(unsigned long*)$rdi")) & 0xffffffffffffffff
except Exception:
pass
print("ENTRY inv=%d t=%.3f param_1=0x%x [0]=0x%x" %
(inv + 1, time.time() - t0, a1, q0))
hist = []
continue
if name == "FRET":
inv += 1
print("INV %d FRET r15d=0x%x (eax=0x%x)" % (inv, r15, eax))
print(" tail:", " | ".join("%s=0x%x" % (n, v) for n, v in hist[-12:]))
if r15 != 0:
nz = [x for x in hist if x[1] != 0]
print(" nonzero call returns (last 12):")
for n, v in nz[-12:]:
print(" %s = 0x%x" % (n, v))
try:
print(gdb.execute("bt 6", to_string=True))
except Exception as e:
print("bt_fail %s" % e)
break
else:
hist.append((name, eax))
if eax != 0:
print("HIT %d t=%.3f %-14s eax=0x%x" % (hits, time.time() - t0, name, eax))
try:
gdb.execute("detach")
except Exception:
pass
|