"""GDB payload for the LIVE-PROVEN engine match-team +0x14 writer. READ-ONLY hardware debug only: 0x147c652ce mov dword [rdx + rcx + 0x44], r8d At the first team-like source value, derives both fixed-stride record fields from live RCX and arms 4-byte WRITE watchpoints on: teamId A = rcx + 0x44 teamId B = rcx + 0x44 + 0x45c The execute breakpoint records the intended source value before every call. The watchpoints then capture both the expected write and any later overwrite, even if the overwrite comes from a different function. No INT3/software breakpoints. No client memory writes. """ from __future__ import annotations import json import os import struct import time import traceback import gdb WRITER_VA = 0x147C652CE POST_WRITER_VA = 0x147C652D3 SIDE_STRIDE = 0x45C TEAM_FIELD_OFF = 0x44 RECORD_FIELD_OFF = 0x14 TEAM_LIKE = {73, 240, 241, 243, 130000, 130001} _STATE = None def _reg(name: str) -> int: return int(gdb.parse_and_eval(f"${name}")) def _thread() -> dict: thread = gdb.selected_thread() if thread is None: return {} return {"name": thread.name, "ptid": list(thread.ptid), "global_num": thread.global_num} def _read(address: int, size: int) -> bytes | None: if not address or address < 0: return None try: return bytes(gdb.selected_inferior().read_memory(address, size)) except gdb.error: return None def _i32(address: int) -> int | None: data = _read(address, 4) return struct.unpack(" dict: names = ( "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "rbp", "rsp", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rip", ) return {name: _reg(name) for name in names} class State: def __init__(self, log_path: str): self.log_path = log_path self.event_index = 0 self.engine_base = None self.watch_a = None self.watch_b = None def log(self, kind: str, **payload): self.event_index += 1 event = { "event": kind, "event_index": self.event_index, "time_unix": time.time(), "thread": _thread(), **payload, } with open(self.log_path, "a", encoding="utf-8") as handle: handle.write(json.dumps(event, sort_keys=True) + "\n") handle.flush() os.fsync(handle.fileno()) def arm_fields(self, engine_base: int): if self.engine_base == engine_base and self.watch_a and self.watch_b: return for watchpoint in (self.watch_a, self.watch_b): if watchpoint is not None: try: watchpoint.delete() except gdb.error: pass self.engine_base = engine_base self.watch_a = TeamFieldWatchpoint(self, 0, engine_base + TEAM_FIELD_OFF) self.watch_b = TeamFieldWatchpoint( self, 1, engine_base + TEAM_FIELD_OFF + SIDE_STRIDE ) self.log( "team_field_watchpoints_armed", engine_base=engine_base, team_id_a_address=self.watch_a.address, team_id_b_address=self.watch_b.address, watchpoint_a=self.watch_a.number, watchpoint_b=self.watch_b.number, ) class TeamFieldWatchpoint(gdb.Breakpoint): def __init__(self, state: State, side: int, address: int): self.state = state self.side = side self.address = address super().__init__( f"*(int*)0x{address:x}", type=gdb.BP_WATCHPOINT, wp_class=gdb.WP_WRITE, internal=False, ) self.silent = True def stop(self): try: pc = _reg("rip") writer = WRITER_VA if pc == POST_WRITER_VA else None record_start = self.address - RECORD_FIELD_OFF record = _read(record_start, 0x7C) self.state.log( "final_team_field_write_post", side=self.side, watch_address=self.address, value=_i32(self.address), stopped_pc=pc, writer_va=writer, record_start=record_start, record_hex=record.hex() if record else None, registers=_registers(), disassembly=gdb.execute("x/12i $pc-32", to_string=True), backtrace=gdb.execute("bt 32", to_string=True), ) except Exception as exc: self.state.log( "trace_error", where="team_field_watchpoint", error=str(exc), traceback=traceback.format_exc(), ) return False class FinalWriterBreakpoint(gdb.Breakpoint): def __init__(self, state: State): self.state = state super().__init__( f"*0x{WRITER_VA:x}", type=gdb.BP_HARDWARE_BREAKPOINT, internal=False ) self.silent = True def stop(self): try: engine_base = _reg("rcx") side_offset = _reg("rdx") source_value = _reg("r8") & 0xFFFFFFFF if source_value in TEAM_LIKE: self.state.arm_fields(engine_base) destination = engine_base + side_offset + TEAM_FIELD_OFF side = side_offset // SIDE_STRIDE if side_offset in (0, SIDE_STRIDE) else None self.state.log( "final_writer_pre", instruction_va=WRITER_VA, engine_base=engine_base, side_offset=side_offset, side=side, destination=destination, record_start=destination - RECORD_FIELD_OFF, source_register="r8d", source_value=source_value, prior_value=_i32(destination), team_id_a_address=engine_base + TEAM_FIELD_OFF, team_id_b_address=engine_base + TEAM_FIELD_OFF + SIDE_STRIDE, team_id_a_before=_i32(engine_base + TEAM_FIELD_OFF), team_id_b_before=_i32(engine_base + TEAM_FIELD_OFF + SIDE_STRIDE), registers=_registers(), disassembly=gdb.execute("x/6i $pc", to_string=True), backtrace=gdb.execute("bt 32", to_string=True), ) except Exception as exc: self.state.log( "trace_error", where="final_writer", error=str(exc), traceback=traceback.format_exc(), ) return False def _on_exit(event): if _STATE is not None: _STATE.log("inferior_exited", detail=str(event)) def start_trace(log_path: str, _cards_base: int): global _STATE open(log_path, "w", encoding="utf-8").close() _STATE = State(log_path) writer = FinalWriterBreakpoint(_STATE) gdb.events.exited.connect(_on_exit) _STATE.log( "trace_armed", breakpoints={ "final_writer": {"number": writer.number, "va": WRITER_VA}, }, side_stride=SIDE_STRIDE, team_field_offset=TEAM_FIELD_OFF, hardware_only=True, client_memory_writes=False, )