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:


댓글 달기