Using ptrace()'s GETREGSET on x86
The following program shows how to obtain a snapshot of register values on x86 machine using ptrace()'s GETREGSET command.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <elf.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/ptrace.h> #include <sys/user.h> #include <linux/ptrace.h> const char *str = "linux is awesome\n"; struct iovec { void *iov_base; unsigned int iov_len; }; struct user_regs_struct32 { __u32 ebx, ecx, edx, esi, edi, ebp, eax; unsigned short ds, __ds, es, __es; unsigned short fs, __fs, gs, __gs; __u32 orig_eax, eip; unsigned short cs, __cs; __u32 eflags, esp; unsigned short ss, __ss; }; int main(void) { struct user_regs_struct32 uregs; struct iovec iov; pid_t c_pid, w_pid; int status; long ret; switch (c_pid = fork()) { case -1: perror("fork"); exit(1); break; case 0: ret = ptrace(PTRACE_TRACEME, 0, NULL, NULL); if (ret == -1) { perror("ptrace"); exit(1); } raise(SIGUSR1); write(1, str, strlen(str)); printf("Child process exiting.\n"); exit(0); break; default: break; } /* Parent's code */ w_pid = wait(&status); if (w_pid == -1) { perror("wait"); goto out1; } ret = ptrace(PTRACE_SYSCALL, c_pid, NULL, NULL); if (ret == -1) { perror("ptrace"); goto out1; } w_pid = wait(&status); if (w_pid == -1) { perror("wait"); goto out1; } memset(&uregs, 0, sizeof(uregs)); iov.iov_len = sizeof(uregs); iov.iov_base = &uregs; ret = ptrace(PTRACE_GETREGSET, c_pid, NT_PRSTATUS, &iov); if (ret == -1) { perror("ret"); goto out1; } printf("uregs.orig_eax = %u.\n", uregs.orig_eax); exit(0); out1: exit(1); }
HTML generated by org-mode 7.3 in emacs 23