You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux父进程中Ptrace options工作异常问题求助

核心问题点

你的代码存在3个直接导致ptrace状态值读取异常的逻辑错误:

  • 状态变量作用域错误:wait_for_syscall函数内部定义了同名局部变量status,waitpid写入的状态仅存在于函数栈帧内,main函数中定义的status从未被更新,后续所有事件判断读取的都是第一次wait拿到的初始SIGSTOP状态的旧值,完全拿不到后续ptrace事件的真实返回。
  • 位运算优先级错误:停止事件判断条件WIFSTOPPED(status) && WSTOPSIG(status) | 0x80存在优先级问题,&&运算优先级高于|,实际执行逻辑等价于(WIFSTOPPED(status) && WSTOPSIG(status)) | 0x80,由于0x80恒为真,该判断永远返回成立,无法过滤非目标停止事件。另外你明确禁用了PTRACE_O_SYSGOOD,未开启该选项时系统调用停止事件不会携带0x80标记,这个判断本身就不成立。
  • 事件判断分支位置错误:PTRACE_O_TRACEEXEC、PTRACE_O_TRACESECCOMP触发时的停止信号为普通SIGTRAP,事件码存在于status的高8位,不会携带你判断的0x80标记,当前逻辑仅在匹配到0x80标记后才检查事件位,两类ptrace事件永远无法进入计数分支。
修正方案
  • 移除wait_for_syscall内的局部status变量,通过指针参数将waitpid拿到的状态传回main函数,保证状态值实时更新
  • 修正停止事件判断逻辑:每次wait返回后优先判断ptrace事件位,匹配EXEC、SECCOMP事件时直接处理,无需依赖0x80标记
  • 子进程中PTRACE_TRACEME调用的pid参数无实际作用,按规范传0即可

修正后的可运行代码如下:

#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <signal.h>

int wait_for_ptrace_stop(pid_t child, int *status) {
    while (1) {
        ptrace(PTRACE_CONT, child, 0, 0);
        waitpid(child, status, 0);
        if (WIFEXITED(*status))
            return 1;
        if (WIFSTOPPED(*status))
            return 0;
    }
}

int main(int argc, char *argv[]) {
    int status;
    int counter = 0;
    pid_t pid = fork();
    if (pid < 0)
        exit(1);
    else if (pid == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        raise(SIGSTOP);
        return execve(argv[1], &argv[1], NULL);
    } else {
        wait(&status);
        ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_EXITKILL | PTRACE_O_TRACEEXEC | PTRACE_O_TRACESECCOMP);

        while (1) {
            if (wait_for_ptrace_stop(pid, &status) != 0) break;
            
            if ((status >> 8) == (SIGTRAP | (PTRACE_EVENT_EXEC << 8)))
                counter++;

            if ((status >> 8) == (SIGTRAP | (PTRACE_EVENT_SECCOMP << 8)))
                counter++;
        }
    }
    return 0;
}

测试运行命令:
/bin/bash -c "echo 'first test' | wc -c"

注:如果需要捕获系统调用入口/出口事件,在禁用PTRACE_SYSCALL、SYSGOOD的约束下,只能通过SECCOMP_RET_TRACE规则配置seccomp过滤器触发PTRACE_EVENT_SECCOMP事件,仅靠当前代码中的ptrace选项无法自动捕获所有系统调用的进出。

内容的提问来源于stack exchange,提问作者Olivia22

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 20:48:34