Key fixes applied during Task 6 end-to-end MCP integration testing:
- CONTEXT_ALL (CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS) for Wow64Get/SetThreadContext
so DR0-DR7 are read and written alongside general-purpose registers
- Native x64 SetThreadContext path in _apply_watchpoints_to_thread: Wow64SetThreadContext
updates the WOW64 context save area but does not propagate to hardware DR registers;
the native path is required for hardware watchpoints to actually fire on WOW64 threads
- _REGISTER_NAMES extended to include Dr0-Dr3, Dr6, Dr7 so get_registers returns them
- launch() now terminates and drains the previously attached process before starting a
new one, preventing stale debug events from a hung game from corrupting a new session
- continue_execution filters events by process ID so late-arriving exit events from a
previously terminated game do not trigger a false "exited" status for the new process
- AV exception routing restored: EXCEPTION_ACCESS_VIOLATION stops and reports; callers
skip boot-time AVs in a loop rather than silently continuing them in the agent
- launch_with_breakpoints atomic op in agent server and MCP server
- _DebugWorker dedicated thread: Windows debug API requires all WaitForDebugEvent,
ContinueDebugEvent, and CreateProcessA calls to originate from the same OS thread;
ThreadingTCPServer violated this -- replaced with single worker thread + queue
- Gameplay screenshot captured at watchpoint stop (272 KB real frame)
Acceptance checklist results:
- Item 1 PASS: bp@0x40C8E0, eip/eax confirmed
- Item 2 PASS: conditional breakpoint false-skip and true-fire verified
- Item 3 PASS: watchpoint@slot0 fired at 0x40E998 (MOV [DAT_0047c488], EAX in
player_cooldown_timers_tick -- the DAT write is in the caller, not inside
compute_frame_delta_ticks_60hz_min1_clamp as the spec assumed)
- Item 4 PASS: screenshot PNG captured (gameplay frame 272 KB)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TN4Ytn3gdWRonNmHpisWQv
Adds DebugAgent.screenshot() using Pillow/ImageGrab -- locates the game window
via FindWindowA, grabs its rect, returns PNG bytes. Adds tools/havoc_debug_agent_server.py:
a 127.0.0.1-only ThreadingTCPServer that serializes all ops behind a single lock and
dispatches NDJSON requests to DebugAgent. Covers all debug-agent ops (launch,
breakpoints, watchpoints, continue_execution, read/write_memory, get_registers,
screenshot, get_status). Acceptance test confirmed: get_status returns
{"ok": true, "result": {"status": "not_launched"}} from a fresh server. Adds
tools/requirements-windows.txt (pillow).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TN4Ytn3gdWRonNmHpisWQv
Implements set_watchpoint/remove_watchpoint/list_watchpoints via Wow64SetThreadContext
on DR0-DR3/DR7. Skips 64-bit WOW64 helper threads (Wow64GetThreadContext returns
ERROR_ACCESS_DENIED on those -- found against the real process). Propagates active
watchpoints to new threads as they spawn. Re-armable breakpoints: on breakpoint hit,
restores original byte and sets EFlags trap flag; the resulting single-step re-plants
the 0xCC, making breakpoints persistent across multiple hits. EXCEPTION_SINGLE_STEP
handler distinguishes watchpoint trips (Dr6 bits 0-3 set) from re-arm single-steps
(Dr6 clear). Smoke test confirmed: re-armed breakpoint fires on second continue;
watchpoint on 0x0047C48C set on slot 0 -- full watchpoint trip validation requires
gameplay state==0x47 (deferred to Task 6 end-to-end run).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TN4Ytn3gdWRonNmHpisWQv
Implements DebugAgent class (Task 2) with launch, set/remove breakpoint,
get_registers, read/write_memory, continue_execution, and get_status.
Handles WOW64 WX86 exception codes (0x4000001F/0x4000001E), keeps debuggee
suspended via _pending_event until caller resumes, and tracks stopped thread
for correct register reads. Smoke-tested against live HAVOC_NOCD.EXE: stopped
at breakpoint@0x40C8E0 with eip=0x40c8e0 confirmed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TN4Ytn3gdWRonNmHpisWQv