ptrace
是 Linux 提供的一组系统调用接口,用于实现父进程对子进程的调试和控制。PTRACE_TRACEME
是 ptrace
的一个请求,通常在子进程中调用,以告知内核该进程将被其父进程调试。关键:一个进程仅能被一个进程调试,不能再多了!
编写一个demo:
#include <sys/ptrace.h>
#include <unistd.h>
#include <stdio.h>
int main() {
int a = 1;
a += 999;
// 调用 PTRACE_TRACEME
if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) {
printf("Debugger detected!\n");
return 1;
}
// 其他程序逻辑
printf("No debugger detected.\n");
sleep(3);
return 0;
}
在main函数中,调用 ptrace(PTRACE_TRACEME, 0, NULL, NULL)
,告诉内核该进程将被其父进程调试。
在进行该调用时,有两种情况:
- 该程序已被调试器进程所调试:那么该调用会失败,返回-1,从而执行
return 1
退出程序。 - 该程序还没被调试:那么在调用后,父进程将占据仅有的调试位,其他调试器无法再对程序调试。
因此,起到反调试的目的!
gdb进行演示:
大概可以看出在执行ptrace(PTRACE_TRACEME, 0, NULL, NULL)
时,断开了gdb调试。