如果程序使用ptrace
检测它是否在调试器中运行,我发现了以下技巧:
catch syscall ptrace
commands 1
set ($eax) = 0
continue
end
有人可以解释一下它是如何工作的吗?我试图在
i r eax
之后插入commands 1
,但是我不明白我得到的负值:Catchpoint 1 (call to syscall ptrace), 0x00007ffff778af1e in ptrace (request=PTRACE_TRACEME) at ../sysdeps/unix/sysv/linux/ptrace.c:45
45 ../sysdeps/unix/sysv/linux/ptrace.c: No such file or directory.
eax 0xffffffda -38
Catchpoint 1 (returned from syscall ptrace), 0x00007ffff778af1e in ptrace (request=PTRACE_TRACEME) at ../sysdeps/unix/sysv/linux/ptrace.c:45
45 in ../sysdeps/unix/sysv/linux/ptrace.c
eax 0xffffffff -1
最佳答案
ptrace
系统调用允许一个进程跟踪另一个进程。我的猜测是您的应用程序(试图检测调试器)产生一个子进程(或线程),然后像调试器一样使用ptrace
附加到该子进程。
问题在于,只有一个进程可以跟踪另一个进程,如果第二个进程尝试使用ptrace
进行附加,则第二个ptrace
将失败,返回-1
并将errno
设置为EPERM
。如果您在调试器下运行,则调试器将首先进入并附带ptrace
,因此,当应用程序本身尝试使用ptrace
进行附加时,此调用将失败。
因此,在您的示例中,当捕捉点在从syscall ptrace返回时触发时,您可以看到eax
设置为-1,这表明syscall失败(寄存器eax将返回值保存在x86-64上)。
现在,如果您要调试的应用程序中的代码不是很好,它只会检查ptrace
是否返回成功,然后强制eax
的值为0(其中0表示ptrace
成功) )可能足以使应用程序误以为它未在调试器下运行。
显然,有可能在应用程序中编写更复杂的代码,从而更广泛地使用ptrace
,这样就很难(尽管并非不可能)解决此检测问题。
关于c - 在gdb中绕过ptrace,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33646927/