#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <sys/ptrace.h> #include <sys/user.h> #include <signal.h> #include <wait.h> typedef enum { BREAK_ON_EXEC = 0x00, BREAK_ON_WRITE = 0x01, BREAK_ON_RW = 0x03, } BreakFlags; typedef enum { LEN_1 = 0x00, LEN_2 = 0x01, LEN_4 = 0x03, } DataLength; typedef struct { int dr0_local:1; int dr0_global:1; int dr1_local:1; int dr1_global:1; int dr2_local:1; int dr2_global:1; int dr3_local:1; int dr3_global:1; int exact_local:1; int exact_global:1; int reserved:6; BreakFlags dr0_break:2; DataLength dr0_len:2; BreakFlags dr1_break:2; DataLength dr1_len:2; BreakFlags dr2_break:2; DataLength dr2_len:2; BreakFlags dr3_break:2; DataLength dr3_len:2; } DR7; #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) int set_bp(int pid, uint32_t addr) { uintptr_t dr0 = (uintptr_t)addr; DR7 dr7 = {0}; dr7.dr0_local = 1; dr7.dr0_break = BREAK_ON_EXEC; dr7.dr0_len = 0; return ptrace(PTRACE_POKEUSER, pid, offsetof(struct user, u_debugreg[0]), dr0) || ptrace(PTRACE_POKEUSER, pid, offsetof(struct user, u_debugreg[6]), 0) || ptrace(PTRACE_POKEUSER, pid, offsetof(struct user, u_debugreg[7]), dr7); } void action(void) { printf("Let's rock!\n"); } void tracer(void) { int pid, status; struct user_regs_struct regs; if ((pid = fork()) == -1) return; if (pid == 0) { ptrace(PTRACE_TRACEME, 0, 0, 0); kill(getpid(), SIGINT); } else { int first = 0; uint32_t next_bp = (uint32_t)action; for (;;) { wait(&status); if (WIFEXITED(status)) break; ptrace(PTRACE_GETREGS, pid, 0, ®s); if (regs.eip != next_bp) { puts("Setting BP"); set_bp(pid, next_bp); } else { printf("Reached BP @ %08x\n", regs.eip); set_bp(pid, 0); } ptrace(PTRACE_CONT, pid, 0, 0); } exit(0); } } int main(int argc, char **argv) { tracer(); action(); }
Wednesday, September 21, 2011
Hardware breakpoints
In addition to. Spent some time trying to recollect how to set the hw breakpoints.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment