【问题标题】:What's the difference between PTRACE_O_TRACEEXEC and its absence?PTRACE_O_TRACEEXEC 和它的缺席有什么区别?
【发布时间】:2014-08-18 20:40:53
【问题描述】:

根据 ptrace 手册页,

如果 PTRACE_O_TRACEEXEC 选项无效,则被跟踪进程对 execve(2) 的所有成功调用都将导致向其发送 SIGTRAP 信号,从而使父进程有机会在新程序开始执行之前获得控制权。

如果选项有效,

在下一个 execve(2) 处停止被跟踪者。跟踪器的 waitpid(2) 将返回一个状态值,例如 status>>8 == (SIGTRAP | (PTRACE_EVENT_EXEC<<8))。如果执行线程不是线程组组长,则线程 ID 在此停止之前重置为线程组组长的 ID。从 Linux 3.0 开始,可以使用 PTRACE_GETEVENTMSG 检索以前的线程 ID。

因此,如果未设置该选项,则被跟踪者获取 SIGTRAP 并停止,以便跟踪者获得控制权。如果设置了选项 ,则被跟踪者获取 SIGTRAP 并停止。有什么区别(除了最后关于线程的部分)?

【问题讨论】:

    标签: linux ptrace


    【解决方案1】:

    区别不在tracee端,而在tracer端。如果没有该选项,跟踪器将无法区分PTRACE_EVENT 停止关注execve 和传入SIGTRAP;它不能使用PTRACE_GETEVENTMSG;另外,交付方式不同:如果我没记错的话,如果SIGTRAP 已经挂起,则没有选项。它不会重新入队(与通常的非实时信号一样)。

    【讨论】:

      【解决方案2】:

      我将提供一个具体示例来说明其中一个区别。

      #include <sys/ptrace.h>
      #include <sys/types.h>
      #include <sys/wait.h>
      #include <unistd.h>
      #include <sys/reg.h>
      #include <stdio.h>
      #include <pthread.h>
      
      int main() {
        pid_t child;
        int status = 0;
        child = fork();
        if(child == 0) {
          ptrace(PTRACE_TRACEME, 0, NULL, NULL);
          raise(SIGSTOP);
          execl("/bin/ls", "ls", NULL);
        } else {
          wait(&status);
          // ptrace(PTRACE_SETOPTIONS, child, NULL, PTRACE_O_TRACEEXEC);
          printf("%d\n", status >> 8);
          ptrace(PTRACE_CONT, child, NULL, NULL);
          wait(&status);
          printf("%d\n", status >> 8);
          printf("%d\n", (SIGTRAP | PTRACE_EVENT_EXEC << 8));
        }
        return 0;
      }
      

      我们会收到19(SIGSTOP)和5(SIGTRAP)。取消注释PTRACE_O_TRACEEXEC 行后,我们将得到191029,这与(SIGTRAP | PTRACE_EVENT_EXEC &lt;&lt; 8) 相同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-21
        • 2014-03-20
        • 2010-10-02
        • 2011-12-12
        相关资源
        最近更新 更多