# gdb script: dump param_2[] at FUN_00337e60 entry when called from # FUN_00550ff0 (file 0x450ff0). bpz20 showed FUN_00550ff0 -> FUN_00337e60 # overwrites ds+0xe94 with param_2[0x23]; on the host that is 0x18 (24 TPC). # Launch under gdb (device init runs during cuInit). import gdb import time gdb.execute("set pagination off") gdb.execute("set confirm off") gdb.execute("set environment CDT_PAUSE=60") gdb.execute("set environment CDT_HOLD=900") gdb.execute("catch load libcuda.so") gdb.execute("run") 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 def rd(addr, n=4, fmt="unsigned int"): try: return int(gdb.parse_and_eval("*(%s*)0x%x" % (fmt, addr))) & ((1 << (8 * n)) - 1) except Exception: return None CALL_LO, CALL_HI = base + 0x450ff0, base + 0x451770 gdb.execute("break *0x%x" % (base + 0x237e60)) gdb.execute("break *0x%x" % (base + 0x2e3e80)) CALLER_RET = base + 0xd0eae1 t0 = time.time() for hit in range(400): try: gdb.execute("continue") except gdb.error as e: print("CONTINUE_END %s" % e) break rip = int(gdb.parse_and_eval("$rip")) & 0xffffffffffffffff if rip == base + 0x2e3e80: ret = rd(int(gdb.parse_and_eval("$rsp")), 8, "unsigned long") if ret != CALLER_RET: continue rdi = int(gdb.parse_and_eval("$rdi")) & 0xffffffffffffffff ds = rd(rdi + 0x40, 8, "unsigned long") print("TERMINATOR t=%.3f ds=0x%x e94=0x%x" % (time.time() - t0, ds or 0, rd(ds + 0xe94) or 0)) break ret = rd(int(gdb.parse_and_eval("$rsp")), 8, "unsigned long") if not (CALL_LO <= ret < CALL_HI): continue rsi = int(gdb.parse_and_eval("$rsi")) & 0xffffffffffffffff d = [rd(rsi + 4 * k) for k in range(0x30)] print("FUN_00550ff0->FUN_00337e60 t=%.3f caller=+0x%x p2[0x23]=0x%x" % (time.time() - t0, ret - base, d[0x23] or 0)) print(" dwords[0..0x30]:", [hex(x or 0) for x in d]) break try: gdb.execute("detach") except Exception: pass