implement hardware watchpoint setup and handler

This commit is contained in:
Gabriel Ionita 2025-10-25 19:30:00 +01:00
parent 50086968a7
commit fc5bc3fda9
Signed by: gabi
SSH Key Fingerprint: SHA256:mrbYmB/SGtDvT3etRoS6pDrMYWxR0/B5GSF6rR3qhhc

55
src/tracer.cpp Normal file
View File

@ -0,0 +1,55 @@
#include "tracer.hpp"
#include <format>
#include <iostream>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <unistd.h>
// 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, &regs);
std::cout << std::format("Variable accessed at RIP: 0x{:x}", regs.rip)
<< std::endl;
}