Compiler options
Hide debugging information and symbols. Use optimization and generates complicated code. Disable dynamic linking.
-g
Enable debugging information.
Debugging informations are stored in .debug_*
sections.
Show all sections : readelf -S ./binary
-s
Strip the binary (remove all symbol table and relocation information from the executable).
.dynsym & .symtab :
.dynsym
: will be loaded into memory when the program is started..symtab
: will not be loaded into memory and is therefore not necessary to execute the program.- The section
.symtab
is removed by the-s
flag.
Show symbols : readelf --syms ./binary
-fvisibility=hidden
Hide all possible symbols.
-O3
Optimization flag.
- -O1 : With -O, the compiler tries to reduce code size and execution time, without performing any optimizations that take a great deal of compilation time.
- -O2 : Optimize even more. GCC performs nearly all supported optimizations that do not involve a space-speed tradeoff.
- -O3 : All optimizations in -O2 plus a handful of others.
- -Os : All -O2 optimizations that do not typically increase code size. It also performs further optimizations designed to reduce code size.
-funroll-loops
Unroll or undo the looping structure of any loop whose iterations can be determined at compile time.
This will produce increasingly long and complicated code.
-static
Prevents linking with the shared libraries.
glibc
, the libc
version shipped with many major Linux distros, is really not meant to be statically linked. When we do statically link it, some libc
functionality gets broken and it makes our binary significantlly larger.
There are other versions of libc
that are intended to be statically linked :
- diet libc
- uClibc
- musl libc
$ gcc -static reverse.c -o reverse
$ du -h reverse
780K reverse
$ musl-gcc -static reverse.c -o reverse
$ du -h reverse
24K reverse
Show dynamic section : readelf -d <binary>
Show external dependencies : ldd <binary>
If the binary doesn't have any dynamic dependencies, you cannot use LD_PRELOAD
or ltrace
to hook functions.
Conclusion
Combining all the options will result into the following command :
musl-gcc -Wall -Wextra -Wshadow -s -fvisibility=hidden -O3 -funroll-loops -static main.c -o main