ptrace에서 open 파일이름 알아내기
글쓴이: songaal / 작성시간: 일, 2009/11/01 - 10:53오후
x86_64환경에서 개발하고 있는데요.
ptrace로 child 프로세스가 파일오픈시 그 파일이름을 알아내는 프로그램을 짜고 있습니다.
이것을 실행시키면 segment fault가 나는데요 아무래도 PTRACE_GETREGS로 읽어온 레지스터값을 잘못읽은것 같은데, 이쪽 지식이 짧아서 잘 모르겠네요.
어디서 잘못된 것인지 알려주시면 감사하겠습니다.
#include <assert.h> #include <sys/ptrace.h> #include <linux/ptrace.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <linux/user.h> #include <sys/syscall.h> #include <syscall.h> #include <sys/reg.h> #include <stdio.h> #include <stdlib.h> #ifdef __x86_64__ #define SYSCALL_OFF (ORIG_RAX * 8) #else #define SYSCALL_OFF (ORIG_EAX * 4) #endif void checked (char const * const s, int const r) { if (r == -1) { perror(s); abort(); } } int main() { struct user_regs_struct regs; pid_t const child = fork(); checked("fork", child); if(child == 0) { checked("ptrace", ptrace(PTRACE_TRACEME, 0, NULL, NULL)); checked("execl", execl("/usr/bin/whoami", "whoami", NULL)); } int status; checked("wait", wait(&status)); assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP); // No way to know whether this SIGTRAP was caused by entry/exit, because we couldn't set PTRACE_O_TRACESYSGOOD until now (see ptracetest2.c). printf("opaque trap passed\n"); checked("ptrace", ptrace(PTRACE_SETOPTIONS, child, NULL, PTRACE_O_TRACESYSGOOD)); long orig_eax; for(;;) { checked("ptrace", ptrace(PTRACE_SYSCALL, child, NULL, NULL)); checked("wait", wait(&status)); if (WIFEXITED(status)) break; if (WSTOPSIG(status) == (SIGTRAP | 0x80)) { orig_eax = ptrace(PTRACE_PEEKUSER, child, SYSCALL_OFF, NULL); if(orig_eax == SYS_open){ ptrace(PTRACE_GETREGS, child, NULL, ®s); printf("syscall_%3d\n", regs.orig_rax); switch(regs.orig_rax){ case __NR_open: printf("open %s \n", (char *)regs.rbx); break; case __NR_exit: goto exit; break; default: printf("%#08x, %#08x, %#08x\n",regs.rbx, regs.rcx, regs.rdx); break; } } } else { assert(WSTOPSIG(status) == SIGTRAP); printf("non-syscall trap\n"); } } exit: return 0; }
Forums:
댓글 달기