ptrace에서 open 파일이름 알아내기

songaal의 이미지

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, &regs);
            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;
}

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.