Ptrace-anti-debugging
Jump to navigation
Jump to search
Description
The general idea is that debuggers, such as gdb, utilize the ptrace() function to attach to a process at runtime. Because only one process is allowed to do this at a time, having a call to ptrace() in your code can be used as an anti-debugging technique.
#include <stdio.h>
#include <sys/ptrace.h>
int main()
{
if (ptrace(PTRACE_TRACEME, 0, 1, 0) == -1)
{
printf("don't trace me !!\n");
return 1;
}
// normal execution
return 0;
}
ptrace() can be detected by the fact that an executable can only call ptrace() once. if ptrace() was already called by the strace executable, we can detect it in runtime:
$ strace -i ./e7bc5d2c0cf4480348f5504196561297 1 2 [00007fb6d7559ae7] execve("./e7bc5d2c0cf4480348f5504196561297", ["./e7bc5d2c0cf4480348f55041965612"..., "1", "2"], [/* 18 vars */]) = 0 [00000000004a9297] uname({sys="Linux", node="debian", ...}) = 0 [00000000004aa78a] brk(0) = 0x148d000 [00000000004aa78a] brk(0x148e1c0) = 0x148e1c0 [000000000045e3f5] arch_prctl(ARCH_SET_FS, 0x148d880) = 0 [00000000004aa78a] brk(0x14af1c0) = 0x14af1c0 [00000000004aa78a] brk(0x14b0000) = 0x14b0000 [000000000047431b] ptrace(PTRACE_TRACEME, 0, 0x1, 0) = -1 EPERM (Operation not permitted) [0000000000473e44] fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 [000000000047509a] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0554e1e000 [0000000000473f50] write(1, "Program received signal SIGSEGV,"..., 52Program received signal SIGSEGV, Segmentation fault ) = 52 [0000000000473dd8] exit_group(9001) = ? [????????????????] +++ exited with 41 +++
Bypass the ptrace anti-debug
The best way to bypass the ptrace anti-debug trick is to patch the code with NOP's.