xorl %eax, %eax

Quick Anti-Debugging Trick for GDB

with 4 comments

Right now, I’m listening to Sepultura’s Bestial Devastation and thinking about an interesting post not related to any public bugs, so here is the most common anti-debugging method for the GNU Debugger (aka. GDB).

GDB as you most likely already know is just a nice front end to ptrace(2). When it debugs a binary it uses exec* family system call first, and when attaching to an already running process it uses ptrace() directly.

With this in mind you can just use a simple function that will try to ptrace() your code. If ptrace() fails with -1 then it’s really likely that you’re running into GDB since ptrace() failed because your code is already being debugged using ptrace() :P. Also, since ELF provides us with .ctors and .dtors we can perform this test even before main() at __do_global_ctors_aux() simply like this:

#include <sys/ptrace.h>
#include <unistd.h>
#include <stdio.h>

void check(void) __attribute__((constructor));

void
check(void)
{
   if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1) {
       printf("lulz!\n");
       _exit(-1);
   }
}
int
main(void)
{
  printf("do stuff outside GDB\n");
  return 0;
}

This simple check() function can be really helpful when you really want to know when you are in a debugger. Here is the result of this little example program:

sh-3.2$ gcc an.c -std=c99 -pedantic -Wall -o an -ggdb
sh-3.2$ ./an
do stuff outside GDB
sh-3.2$ gdb -q ./an
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) run
Starting program: /home/xorl/an
lulz!

Program exited with code 0377.
(gdb)

I know there are more better ways to perform GDB anti-debugging but this is just to fill some space. This is known.. I know :p In the future I’ll probably post some more info on this subject.

Written by xorl

January 1, 2009 at 08:22

4 Responses

Subscribe to comments with RSS.

  1. Well i checked and is easy to bypass , but nice try.

    [0]beck@dedekind tmp]$ gdb -q ./an
    (gdb) br 1
    Breakpoint 1 at 0x40056c: file an.c, line 1.
    (gdb) r
    Starting program: /tmp/an

    Breakpoint 1, check () at an.c:9
    9 {
    (gdb) jump 14
    Continuing at 0x4005a8.
    do stuff outside GDB

    Program exited normally.
    (gdb)

    Eduardo Ruiz Duarte

    September 14, 2010 at 00:26

  2. Hehe, I’ve used this trick in a couple of crackmes I’ve published recently (mixed with other techniques).

    For Eduardo, seeing the code is as simple as you showed, but if you don’t know where the check is done it’s quite a pain in the ass. Anyway, there are simple methods to bypass this, like LD_PRELOAD on ptrace or patching the return value if it’s statically linked. Moreover, you can catch signals to make the child look like he’s not being debugged, etc.

    Is the oldest trick, the simplest, but is useful and a must-know :)

    Adrián

    November 18, 2010 at 13:30

  3. Uhm, sorry to raise such old posts, but its like the change of the page style has sent me old posts to the rss reader (I’ve just noticed how old this was).

    Adrián

    November 18, 2010 at 13:32

  4. Thanks for the reply, nice blog :)

    Eduardo

    November 18, 2010 at 17:29


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s