首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ptrace选项根本不起作用

ptrace选项根本不起作用
EN

Stack Overflow用户
提问于 2013-12-14 04:24:47
回答 1查看 860关注 0票数 1

当我连接到另一个进程时,我无法跟踪叉/ exec事件,从waitpid返回的status总是为零(在右移16次之后)。

我已经成功地附加到bash,但是无论我运行什么命令,状态总是为零,因此我没有捕获任何叉或exec事件:

代码语言:javascript
复制
#define PALL PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE \
    | PTRACE_O_TRACEEXEC | PTRACE_O_TRACEVFORKDONE | PTRACE_O_TRACEEXIT

int main(int argc, char **argv)
{ 
    pid_t child = 0;
    int status = 0;

    if (argc != 2) { ... }
    child = atoi (argv[1]);
    if (ptrace (PTRACE_ATTACH, child, 0, 0) < 0) { ... }

    ptrace(PTRACE_SETOPTIONS, child, NULL, PALL);
    ptrace(PTRACE_SYSCALL, child, NULL, NULL);
    ptrace(PTRACE_CONT, child, NULL, NULL);

    while(1) {
        waitpid(child, &status, 0);
        if(WIFEXITED(status))
            break;

        status >>= 16;
        if (status != 0)
            printf ("Status: %d\n", status >> 16);

        ptrace(PTRACE_SYSCALL, child, NULL, NULL);
    }

    ptrace(PTRACE_DETACH, child, NULL, NULL);
    return 0;
}
EN

回答 1

Stack Overflow用户

发布于 2016-10-13 06:06:26

从等待返回的status总是为零(在右移16次之后)。

您移动的status位不是16,而是32次,首先执行status >>= 16,然后执行printf (…, status >> 16);,所以总是打印0。此外,还有一些不太明显的缺陷:

  • 为了完整起见,我们应该处理这个案例WIFSIGNALED
  • 我们应该把信号传递给孩子,它可能需要它们才能正常工作。
  • 因为我们还跟踪孩子的孩子,所以我们也必须对孩子的孩子进行wait和处理。
  • 紧跟在PTRACE_SYSCALL之前的PTRACE_CONT没有意义。
  • 如果PTRACE_SETOPTIONS尚未完成,PTRACE_ATTACH可能会失败,因此我们必须使用wait

考虑到这一切,这个程序看起来就像

代码语言:javascript
复制
#include <stdio.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#define PALL PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE \
           | PTRACE_O_TRACEEXEC | PTRACE_O_TRACEVFORKDONE | PTRACE_O_TRACEEXIT
int main(int argc, char **argv)
{ 
    pid_t child, pid;
    int status;
    if (argc != 2) { return 2; }
    child = atoi(argv[1]);
    if (ptrace(PTRACE_ATTACH, child, 0, 0) < 0) { return 1; }
    wait(NULL); // PTRACE_SETOPTIONS may work only after this
    ptrace(PTRACE_SETOPTIONS, child, NULL, PALL);
    ptrace(PTRACE_CONT, child, NULL, NULL);
    while (pid = wait(&status), pid > 0)
    {
        if (WIFEXITED(status) || WIFSIGNALED(status))
        {
            if (pid == child) break;
            printf("grandchild %d exited\n", pid);
            continue;
        }
        if (status>>16)
            printf("[%d] Status: %x\n", pid, status);
        int signal = WSTOPSIG(status);
        if (signal == SIGTRAP)
        {   // system call or ptrace event
            signal = 0;
            if (status>>16)
                printf("ptrace event: %d\n", status>>16);
        }
        ptrace(PTRACE_CONT, pid, 0, signal);
    }
    ptrace(PTRACE_DETACH, child, NULL, NULL);
    return 0;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20579656

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档