From fc5bc3fda96e6058927b11265aee008f6d20ba6b Mon Sep 17 00:00:00 2001 From: Gabriel Ionita Date: Sat, 25 Oct 2025 19:30:00 +0100 Subject: [PATCH] implement hardware watchpoint setup and handler --- src/tracer.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/tracer.cpp diff --git a/src/tracer.cpp b/src/tracer.cpp new file mode 100644 index 0000000..e73cecc --- /dev/null +++ b/src/tracer.cpp @@ -0,0 +1,55 @@ +#include "tracer.hpp" +#include +#include +#include +#include +#include +#include + +// Hardware watchpoint condition codes +#define DR7_BREAK_ON_WRITE 0x1 +#define DR7_BREAK_ON_RW 0x3 + +// Hardware watchpoint size codes +#define DR7_LEN_1 0x0 +#define DR7_LEN_2 0x1 +#define DR7_LEN_4 0x3 +#define DR7_LEN_8 0x2 + +void Tracer::setup_hardware_watchpoint(pid_t pid, uint64_t address, size_t size) { + struct user_regs_struct regs; + + // Read debug registers + uint64_t dr7 = ptrace(PTRACE_PEEKUSER, pid, + offsetof(struct user, u_debugreg[7]), 0); + + // Use DR0 for our watchpoint + ptrace(PTRACE_POKEUSER, pid, offsetof(struct user, u_debugreg[0]), address); + + // Configure DR7 for DR0 + // Set local enable bit for DR0 (bit 0) + dr7 |= (1 << 0); + + // Set condition to break on read/write (bits 16-17) + dr7 |= (DR7_BREAK_ON_RW << 16); + + // Set length based on size (bits 18-19) + uint64_t len_code; + if (size == 1) len_code = DR7_LEN_1; + else if (size == 2) len_code = DR7_LEN_2; + else if (size == 4) len_code = DR7_LEN_4; + else len_code = DR7_LEN_8; + + dr7 |= (len_code << 18); + + // Write back DR7 + ptrace(PTRACE_POKEUSER, pid, offsetof(struct user, u_debugreg[7]), dr7); +} + +void Tracer::handle_watchpoint_hit(pid_t pid, uint64_t address) { + struct user_regs_struct regs; + ptrace(PTRACE_GETREGS, pid, 0, ®s); + + std::cout << std::format("Variable accessed at RIP: 0x{:x}", regs.rip) + << std::endl; +}