Evasion of Anti-Debugging
Automatic Evasion of Anti-Debugging Techniques
A common anti-debugging technique for Linux ELF binaries is to invoke the ptrace
syscall with the PTRACE_TRACEME
argument. The syscall will fail if the binary is currently being traced by a debugger, as the kernel forbids a process from being traced by multiple debuggers.
Bypassing this technique involves intercepting such syscalls and altering the return value to make the binary believe that it is not being traced. While this can absolutely be performed manually, libdebug comes with a pre-made implementation that can save you precious time.
To enable this feature, set the escape_antidebug
property to True
when creating the debugger object. The debugger will take care of the rest.
Example
> C source code
#include <stdio.h>
#include <stdlib.h>
#include <sys/ptrace.h>
int main()
{
if (ptrace(PTRACE_TRACEME, 0, NULL, 0) == -1) // (1)
{
puts("No cheating! Debugger detected.\n"); // (2)
exit(1);
}
puts("Congrats! Here's your flag:\n"); // (3)
puts("flag{y0u_sn3aky_guy_y0u_tr1ck3d_m3}\n");
return 0;
}
- Call ptrace with
PTRACE_TRACEME
to detect if we are being debugged - If the call fails, it means the program is being debugged
- If the program is not being debugged, print the flag
> libdebug script
from libdebug import debugger
d = debugger("evasive_binary",
escape_antidebug=True)
pipe = d.run()
d.cont()
out = pipe.recvline(numlines=2)
d.wait()
print(out.decode())
Execution of the script will print the flag, even if the binary is being debugged.