Ptrace-anti-debugging

From aldeid
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.