标准方法如下:
if (ptrace(PTRACE_TRACEME, 0, NULL, 0) == -1)
printf("traced!\n");
在这种情况下,如果当前进程被跟踪(例如,使用 GDB 运行它或附加到它),ptrace 会返回一个错误。
但是这样做有一个严重的问题:如果调用成功返回,GDB 以后可能不会附加到它。这是一个问题,因为我没有尝试实现反调试的东西。我的目的是在满足条件(例如,断言失败)并且 GDB 正在运行(否则我得到一个停止应用程序的 SIGTRAP)时发出一个“int 3”。
每次都禁用 SIGTRAP 并发出“int 3”不是一个好的解决方案,因为我正在测试的应用程序可能会将 SIGTRAP 用于其他目的(在这种情况下我仍然搞砸了,所以没关系, 但这是事情的原理:))
最佳答案
在 Windows 上,有一个 API IsDebuggerPresent,用于检查进程是否处于调试状态。在 Linux 上,我们可以用另一种方式检查这一点(效率不高)。
检查“/proc/self/status”的“TracerPid”属性。
示例代码:
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
bool debuggerIsAttached()
{
char buf[4096];
const int status_fd = ::open("/proc/self/status", O_RDONLY);
if (status_fd == -1)
return false;
const ssize_t num_read = ::read(status_fd, buf, sizeof(buf) - 1);
::close(status_fd);
if (num_read <= 0)
return false;
buf[num_read] = '\0';
constexpr char tracerPidString[] = "TracerPid:";
const auto tracer_pid_ptr = ::strstr(buf, tracerPidString);
if (!tracer_pid_ptr)
return false;
for (const char* characterPtr = tracer_pid_ptr + sizeof(tracerPidString) - 1; characterPtr <= buf + num_read; ++characterPtr)
{
if (::isspace(*characterPtr))
continue;
else
return ::isdigit(*characterPtr) != 0 && *characterPtr != '0';
}
return false;
}
https://stackoverflow.com/questions/3596781/