Artificial truth

The more you see, the less you believe.

[archives] [latest] | [homepage] | [atom/rss/twitter]

Detecting gdb with file descriptors
Tue 31 July 2012 — download

I just stumbled upon a funny trick to detect gdb in this crackme (btw, strace lincrack2 and it's done.): using file descriptors. Normally, a programm has 3 file descriptors :

  • 0: stdin
  • 1: stdout
  • 2: stderr

But, if you are running you binary under gdb, you'll notice that it opens 3 more file descriptors, and never closes them.


#include <stdio.h>
#include <unistd.h>

int main(){
    FILE* fd = fopen("/tmp", "r");
    if(fileno(fd) > 3){
        printf("Gdb detected :(\n");
    printf("No gdb detected :)\n");
    return 0;


$ gcc detect_gdb.c && a.out
No gdb detected :)
$ gdb a.out
Reading symbols from /home/jvoisin/a.out...(no debugging symbols
(gdb) r
Starting program: /home/jvoisin/a.out
Gdb detected :(
[Inferior 1 (process 19872) exited with code 01]


Fortunately, this can easily be bypassed :

  1. Break before the check, on __libc_start_main for example.
  2. Closes the file descriptors
  3. Resume


$ gdb a.out
Reading symbols from /home/jvoisin/a.out...(no debugging symbols
(gdb) b __libc_start_main
Breakpoint 1 at 0x400500
(gdb) r
Starting program: /home/jvoisin/a.out
Breakpoint 1, __libc_start_main (main=0x400668 , argc=1, ubp_av=0x7fffffffdfd8, init=0x400690 , fini=0x400720 ,
rtld_fini=0x7ffff7de9740 , stack_end=0x7fffffffdfc8)
(gdb) print close(3)
$1 = 0
(gdb) print close(4)
$2 = 0
(gdb) print close(5)
$3 = 0
(gdb) c
No gdb :)
[Inferior 1 (process 19804) exited normally]

You can also execute your check_gdb() function before the main, using attributes for even more fun ;)

edit This bug is now fixed in GDB 7.11