implement hardware watchpoint setup and handler
This commit is contained in:
parent
50086968a7
commit
fc5bc3fda9
55
src/tracer.cpp
Normal file
55
src/tracer.cpp
Normal 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, ®s);
|
||||
|
||||
std::cout << std::format("Variable accessed at RIP: 0x{:x}", regs.rip)
|
||||
<< std::endl;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user