gpt4 book ai didi

c - ptrace 选项根本不起作用

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:35:07 27 4
gpt4 key购买 nike

当我附加到另一个进程时,我无法跟踪 fork/exec 事件,从 waitpid 返回的 status 始终为零(在右移 16 次之后)。

我已经成功附加到 bash shell,但是无论我运行什么命令,状态始终为零,所以我没有捕捉到任何 fork 或 exec 事件:

#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;
}

最佳答案

the status returned from waitpid was always zero (after right shift of 16 times).

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

  • 为了完整起见,我们应该处理案例 WIFSIGNALED .
  • 我们应该向 child 传递信号;它可能需要它们才能正常运行。
  • 由于我们还要跟踪 child 的 child ,所以我们也必须等待并处理它们。
  • 紧接在 PTRACE_CONT 之前的
  • PTRACE_SYSCALL 没有意义。
  • 如果 PTRACE_ATTACH 尚未完成,PTRACE_SETOPTIONS 可能会失败,因此我们必须等待

考虑到所有这些,程序可能看起来像

#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;
}

关于c - ptrace 选项根本不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20579656/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com