2010年9月13日 星期一

ptrace @ Linux Kernel

在 Parent Process assign to Child Process 的方法有很多種,如 fork, vfork ,clone...但這都還是在比較高層的 assign 方式, 其實 trace code 後,不難發現都是透過 ptrace 這個 func 來做底層的 register assign, 以 x86 為例. 你會看到 eax, ecx, esp, ebp, 的 assign 方式. 有點像是 assembly encode/decode 的方法...,當然我們也可以用 ptrace 的方式來 trace system calls.
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/reg.h>
#include <sys/syscall.h>   /* For SYS_write etc */

#include <stdio.h>
#include <stdlib.h>

int main()
{   pid_t child;
    long orig_eax, eax;
    long params[3];
    int status;
    int insyscall = 0;
    child = fork();
    if(child == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl("/bin/ls", "ls", NULL);
    }
    else {
       while(1) {
          wait(&status);
          if(WIFEXITED(status))
              break;
          orig_eax = ptrace(PTRACE_PEEKUSER,
                     child, 4 * ORIG_EAX, NULL);
          if(orig_eax == SYS_write) {
             if(insyscall == 0) {
                /* Syscall entry */
                insyscall = 1;
                params[0] = ptrace(PTRACE_PEEKUSER,
                                   child, 4 * EBX,
                                   NULL);
                params[1] = ptrace(PTRACE_PEEKUSER,
                                   child, 4 * ECX,
                                   NULL);
                params[2] = ptrace(PTRACE_PEEKUSER,
                                   child, 4 * EDX,
                                   NULL);
                printf("Write called with "
                       "%ld, %ld, %ld\n",
                       params[0], params[1],
                       params[2]);
                }
          else { /* Syscall exit */
                eax = ptrace(PTRACE_PEEKUSER,
                             child, 4 * EAX, NULL);
                    printf("Write returned "
                           "with %ld\n", eax);
                    insyscall = 0;
                }
            }
            ptrace(PTRACE_SYSCALL,
                   child, NULL, NULL);
        }
    }
    return 0;
}

code ref : Playing with ptrace ps : 當然你也可以用 strace 來trace 執行時所呼叫的system call. Refs: ptrace Playing with ptrace

1 則留言:

  1. Jserv's 以 ptrace 系統呼叫來追蹤/修改行程

    http://blog.linux.org.tw/~jserv/archives/002027.html

    回覆刪除