ubuntu 에서 ptrace() 했을때
안녕 하세요..
ptrace() 에 대해서 공부 중인데
환경은 windows7 64bit 에 vmware 64bit 설치하고 ubuntu 12.04 64bit 올려서 하고 있습니다.
여기저기서 본 소스로 테스트 중인데 아래 소스중에서
ptrace(PTRACE_GETREGS, child_pid, NULL, ®s);
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, ®s); 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; }
댓글 달기