Linux ptrace实验

Linux ptrace实验

  ptrace是所有调试和跟踪程序所用的基础,包括gdb,strace,ltrace等工具。ptrace也用于反调试,因为对于一个线程ptrace之后便不能再ptrace。ptrace有2种启动方式:

  • 在子进程中ptrace通知父进程调试自己
  • 从一个进程对另一个进程进行ptrace

因此ptrace的结构也分为3种(网上收集):

  • 父进程调试子进程
int pid=fork()
if(pid == -1)
{
}
else if(pid == 0)//子进程
{
    ptrace(PTRACE_TRACEME,0,0,0);                       
}
else//父进程
{
    wait(0);
}
  • 子进程调试父进程
pid_t pid = fork();
assert(pid != -1);
int status;
long readme = 0;
if (pid)
{
    readme = 42;
    printf("parent: child pid is %d\n", pid);
    assert(pid == wait(&status));
    printf("parent: child terminated?\n");
    assert(0 == status);
}
else
{
    pid_t tracee = getppid();
    printf("child: parent pid is %d\n", tracee);
    sleep(1); // give parent time to set readme
    assert(0 == ptrace(PTRACE_ATTACH, tracee));
    assert(tracee == waitpid(tracee, &status, 0));
    printf("child: parent should be stopped\n");
    printf("child: peeking at parent: %ld\n", ptrace(PTRACE_PEEKDATA, tracee, &readme));
}
  • A进程调试B进程

同时,下面2种情况测试失败:

  • ptrace自身
  • 互相ptrace

  反反调试的构思(用户态):由于不存在环回ptrace,因此对于由于已经ptrace而无法调试的程序,找到第一个发出ptrace的进程(/proc/self/status TracerPid),注入并执行ptrace DETACH,之后对下一级同样操作直到最后的子进程