After reading Alex O’Mara’s post about preventing disassembly with Hopper by including the Hopper self-protection signature in the binary, I remembered this trick I discovered a while back to prevent files from being opened by gdb.

Say we have this basic program:;

#include <stdio.h>
int main(void) {
    printf("hello, world\n");
}

Compile it with:

$ gcc main.c -o main

It should run ordinarily:

$ ./main 
hello, world

And it works in gdb:

$ gdb ./main 
GNU gdb (Debian 8.2.1-2+b3) 8.2.1
...
Reading symbols from ./main...(no debugging symbols found)...done.
(gdb) 

But if we change the e_machine field in the ELF header to an invalid value:

printf '\xFF' | dd of=main bs=1 seek=5 count=1 conv=notrunc

The program still runs:

$ ./main 
hello, world

But fails to open in gdb:

GNU gdb (Debian 8.2.1-2+b3) 8.2.1
...
"/home/christopher/./main": not in executable format: file format not recognized
(gdb) 

This even prevents objdump from being able to disassemble it.

$ objdump -d ./main
objdump: ./main: file format not recognized

The reason this works is because Linux parses the ELF header much more generously than these tools. This of course is just as easily circumvented as it is implemented but is probably effective in detering “noob” analysts. Read more about other creative uses of the ELF header at the ELF Kickers page on muppetlabs.com.