#include #include #include #include #include #include #include #include #include #include static siginfo_t wait_trap(pid_t chld) { siginfo_t si; if (waitid(P_PID, chld, &si, WEXITED|WSTOPPED) != 0) err(1, "waitid"); if (si.si_pid != chld) errx(1, "got unexpected pid in event\n"); if (si.si_code != CLD_TRAPPED) errx(1, "got unexpected event type %d\n", si.si_code); return si; } int main() { unsigned long tmp; pid_t chld = fork(); if (chld < 0) err(1, "fork"); if (chld == 0) { if (ptrace(PTRACE_TRACEME, 0, 0, 0) != 0) err(1, "PTRACE_TRACEME"); raise(SIGSTOP); fork(); return 0; } int status; /* Wait for SIGSTOP and enable seccomp tracing. */ if (waitpid(chld, &status, 0) != chld || !WIFSTOPPED(status)) err(1, "waitpid"); if (ptrace(PTRACE_SETOPTIONS, chld, 0, PTRACE_O_TRACEFORK) != 0) err(1, "PTRACE_O_TRACEFORK"); if (ptrace(PTRACE_CONT, chld, 0, 0) != 0) err(1, "PTRACE_CONT"); wait_trap(chld); errno = 0; tmp = ptrace(PTRACE_PEEKUSER, chld, offsetof(struct user_regs_struct, rip), NULL); if (errno) err(1, "PTRACE_PEEKUSER"); printf("child RIP = 0x%lx\n", tmp); if (ptrace(PTRACE_POKEUSER, chld, offsetof(struct user_regs_struct, rip), (void *)(1ULL << 48)) != 0) err(1, "PTRACE_POKEUSER"); errno = 0; tmp = ptrace(PTRACE_PEEKUSER, chld, offsetof(struct user_regs_struct, rip), NULL); if (errno) err(1, "PTRACE_PEEKUSER"); printf("child RIP = 0x%lx\n", tmp); if (ptrace(PTRACE_CONT, chld, 0, 0) != 0) err(1, "PTRACE_CONT"); ptrace(PTRACE_DETACH, chld, 0, 0); return 0; }