ubuntu 에서 ptrace() 했을때

conyii의 이미지

안녕 하세요..

ptrace() 에 대해서 공부 중인데
환경은 windows7 64bit 에 vmware 64bit 설치하고 ubuntu 12.04 64bit 올려서 하고 있습니다.

여기저기서 본 소스로 테스트 중인데 아래 소스중에서

ptrace(PTRACE_GETREGS, child_pid, NULL, &regs);
str = (char *)malloc((params[2]+1) * sizeof(char));
printf("Write called with " "%ld, %ld, %ld, %ld, %s \n", sc_number, regs.rbx, regs.rcx, regs.rdx, str);

다른 부분은 나오는거 같은데 regs.rcx 부분이 -1 로 나옵니다.
소스에서 regs.rcx 부분을 사용해서 str 에 데이터를 가져 오는거 같은데.. 값을 제대로 가지고 오지 못하고 있습니다.

Write called with 14, 4553904, -1, 0,
Write called with 14, 4553904, -1, 0,
Write called with 13, 7261568, -1, 140736404729224, (null)
Write called with 13, 7261568, -1, 140736404729224, (null)
Write called with 14, 4553904, -1, 7261856,
Write called with 14, 4553904, -1, 7261856,

아무리 찾아봐도 찾을수가 없네요..

그리고 bash 를 trace 걸건데 command 를 입력 하면 fork 된 command 도 trace 하고 싶습니다..
하지만 fork 된 command 를 따라 가는 방법을 모르겠네요..
혹시 방법 아시는분 알려 주세요 ^^

감사합니다.

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/user.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <asm/ptrace-abi.h>
#include <sys/reg.h>
#include <sys/syscall.h>
 
#define BUFFER_SIZE 1024
#define SIZEOF_LONG sizeof(long)
 
#ifdef __x86_64__
#define SC_NUMBER  (8 * ORIG_RAX)
#define SC_RETCODE (8 * RAX)
#else
#define SC_NUMBER  (4 * ORIG_EAX)
#define SC_RETCODE (4 * EAX)
#endif
 
const int long_size = sizeof(long);
struct user_regs_struct regs;
 
void getdata(pid_t child, long addr, char *str, int len)
{   char *laddr;
    int i, j;
    union u {
            long val;
            char chars[long_size];
    }data;
    i = 0;
    j = len / long_size;
    laddr = str;
    while(i < j) {
        data.val = ptrace(PTRACE_PEEKDATA, child, addr + i * 8, NULL);
        memcpy(laddr, data.chars, long_size);
        ++i;
        laddr += long_size;
    }
    j = len % long_size;
    if(j != 0) {
        data.val = ptrace(PTRACE_PEEKDATA, child, addr + i * 8, NULL);
        memcpy(laddr, data.chars, j);
    }
    str[len] = '\0';
}
 
static void parent(pid_t child_pid)
{
    int status;
    long sc_number, sc_retcode;
    long sc_bx, sc_dx;
    long params[3];
    char *str, *laddr;
    ptrace(PTRACE_ATTACH, child_pid, 0, 0);
 
    while (1)
    {
        /* Wait for child status to change: */
        wait(&status);
 
        if (WIFEXITED(status)) {
            printf("Child exit with status %d\n", WEXITSTATUS(status));
            exit(0);
        }
        if (WIFSIGNALED(status)) {
            printf("Child exit due to signal %d\n", WTERMSIG(status));
            exit(0);
        }
        if (!WIFSTOPPED(status)) {
            printf("wait() returned unhandled status 0x%x\n", status);
            exit(0);
        }
        if (WSTOPSIG(status) == SIGTRAP) {
            /* Note that there are *three* reasons why the child might stop
             * with SIGTRAP:
             *  1) syscall entry
             *  2) syscall exit
             *  3) child calls exec
             */
            sc_number = ptrace(PTRACE_PEEKUSER, child_pid, SC_NUMBER, NULL);
            //sc_retcode = ptrace(PTRACE_PEEKUSER, child_pid, SC_RETCODE, NULL);
	    //sc_bx = ptrace(PTRACE_PEEKUSER, child_pid, 8 * RBX,NULL);
	    ptrace(PTRACE_GETREGS, child_pid, NULL, &regs);
	    str = (char *)malloc((params[2]+1) * sizeof(char));
	    printf("Write called with " "%ld, %ld, %ld, %ld, %s \n", sc_number, regs.rbx, regs.rcx, regs.rdx, str);
        } else {
            printf("Child stopped due to signal %d\n", WSTOPSIG(status));
        }
        fflush(stdout);
 
        /* Resume child, requesting that it stops again on syscall enter/exit
         * (in addition to any other reason why it might stop):
         */
        ptrace(PTRACE_SYSCALL, child_pid, NULL, NULL);
    }
}
 
int main(int argc, char **argv)
{
 
        if (argc <= 1) {
                fprintf(stderr, "Usage: %s command args -or- %s -p pid\n",
                        argv[0], argv[0]);
                exit(1);
        }
 
        if (argc >= 3 && !strcmp(argv[1], "-p")) {
                pid_t pid = atoi(argv[2]);
		parent(pid);
	}
    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 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • 사용할 수 있는 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>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • You can use Textile markup to format text.
  • 사용할 수 있는 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>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 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>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.