为何SIG_IGN对PTRACE_TRACEME无效?反调试程序持续停止
解决基于ptrace TRACEME的反调试程序停止问题
这个问题的核心是你没理解PTRACE_TRACEME的底层行为——当进程调用PTRACE_TRACEME成功后,它会自动给自己发送一个SIGSTOP信号,进入停止状态等待调试器附着。如果没有调试器处理这个停止状态,进程就会一直停在那里,这就是你看到[4]+ Stopped ./a.out的原因。
直接忽略SIGSTOP是没用的,因为ptrace会优先拦截这个信号,进程根本没机会触发你的信号处理函数。下面是具体的解决思路和修改后的代码:
关键解决步骤
- 在调用
PTRACE_TRACEME成功后,必须主动让进程恢复运行,用ptrace(PTRACE_CONT, 0, NULL, NULL)命令告诉ptrace继续执行当前进程。 - 补充完善错误处理逻辑,比如动态库加载失败、ptrace调用失败等场景,避免隐性问题。
修改后的完整代码
#include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #include <sys/ptrace.h> #include <sys/types.h> #include <unistd.h> int main(int argc, char **argv) { void *handle; long (*go)(enum __ptrace_request request, pid_t pid, void *addr, void *data); // 加载libc库,注意不同系统可能用libc.so.6而非libc.so handle = dlopen("libc.so.6", RTLD_LAZY); if (!handle) { fprintf(stderr, "dlopen failed: %s\n", dlerror()); exit(1); } // 动态获取ptrace函数指针 go = dlsym(handle, "ptrace"); if (!go) { fprintf(stderr, "dlsym failed: %s\n", dlerror()); dlclose(handle); exit(1); } // 尝试设置TRACEME,失败则说明已被跟踪 if (go(PTRACE_TRACEME, 0, NULL, NULL) < 0) { puts("being traced"); dlclose(handle); exit(1); } // 关键:让进程从SIGSTOP状态恢复运行 if (go(PTRACE_CONT, 0, NULL, NULL) < 0) { fprintf(stderr, "ptrace CONT failed\n"); dlclose(handle); exit(1); } puts("not being traced"); // 清理资源 dlclose(handle); return 0; }
编译与运行
编译时需要链接动态加载库:
gcc -o a.out your_code.c -ldl
运行后就不会再出现停止问题:
./a.out not being traced
额外说明
- 为什么忽略SIGSTOP无效?因为进程设置
PTRACE_TRACEME后,信号处理会被ptrace接管,SIGSTOP会直接让进程进入停止状态,不会触发你注册的SIG_IGN处理逻辑。 - 关于libc路径:如果
dlopen("libc.so.6")失败,可以用ldd /bin/ls查看系统实际的libc动态库路径。
内容的提问来源于stack exchange,提问作者daisy
相关产品推荐
相关产品推荐

