# File format

## strip - Remove symbol table and sections.

Remove a section :

$gcc main.c -o binary$ objdump -s --section .comment ./binary

./binary:     file format elf64-x86-64

Contents of section .comment:
0000 4743433a 2028474e 55292031 312e312e  GCC: (GNU) 11.1.
0010 3000                                 0.
$strip -R .comment binary$ objdump -s --section .comment ./binary

./binary:     file format elf64-x86-64

objdump: section '.comment' mentioned in a -j option, but not found in any input file


## Removing the Section Headers Table

The section headers table is useful for a reverse engineer because it breaks down the binary’s address space into very specific chunks.

The section headers table isn’t actually needed for execution. You can remove it entirely.

There are four variables from the ELF header that are used to find, parse, and display the section headers table:

4. Section header string table index

## Little Endian or Big Endian?

The sixth byte is called EI_DATA and it indicates the endianness of the binary.

This field isn't necessary to execute a binary. A system is either little-endian or big-endian (unless its ARM which can be bi-endian). As such, a loader probably doesn't need to check this byte because it can only execute one or the other.

Little endian :

$gcc test.c -o test$ readelf -a ./test | head
Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class:                             ELF64
Data:                              2's complement, little endian
Version:                           1 (current)
OS/ABI:                            UNIX - System V
ABI Version:                       0
Type:                              DYN (Shared object file)
Version:                           0x1
$./test I'm still working !!!  Let's manually overwrite the EI_DATA field, to fake a big endian binary : $ printf '\x02' | dd conv=notrunc of=./test bs=1 seek=5
1+0 records in
1+0 records out
1 byte copied, 3.3036e-05 s, 30.3 kB/s


Testing readelf :

$readelf -a ./test | head readelf: Warning: The e_shentsize field in the ELF header is larger than the size of an ELF section header readelf: Error: Reading 125829120 bytes extends past end of file for section headers readelf: Error: Section headers are not available! readelf: Error: Too many program headers - 0xd00 - the file is not that big readelf: Error: ELF Header: Too many program headers - 0xd00 - the file is not that big Magic: 7f 45 4c 46 02 02 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, big endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: <unknown>: 300 Machine: <unknown>: 0x3e00 Version: 0x1000000  Testing gdb : $ gdb ./test
GNU gdb (GDB) 11.1
[...]

For help, type "help".
Type "apropos word" to search for commands related to "word"...
"/tmp/./test": not in executable format: file format not recognized
(gdb) Quit


Testing radare2 :

$r2 ./test -- There is no F5 key in radare2 yet [0x4010000000000000]> aaa [af: Cannot find function at 0x4010000000000000try0 (aa) [x] Analyze all flags starting with sym. and entry0 (aa) [x] Analyze function calls (aac) [x] Analyze len bytes of instructions for references (aar) [x] Finding and parsing C++ vtables (avrr) [x] Type matching analysis for all functions (aaft) [x] Propagate noreturn information (aanr) [x] Use -AA or aaaa to perform additional experimental analysis. [0x4010000000000000]> pdf @main Invalid address (main) |ERROR| Invalid command 'pdf @main' (0x70)  Executing the binary : $ ./test
I'm still working !!!


readelf, gdb and radare2 seems to be broken, but the binary is still working.

## Flipping the Executable bit

An important part of the program headers is the flags field. The flag field describes if a segment is executable, writeable, and/or readable.

You can create a fake section headers table that reverses the program headers flag fields.

## .init section

There are two special sections that you’ll often come across in ELF binaries : .init and .fini.

These sections contain code that execute before and after the main() function.

If you include .init and .fini sections in the fake section headers table can you potentially force the disassembler to disassemble at bad locations. It can be harder for a disassembler to find the entrypoint.

## Mixing the Symbols

This section will discuss an anti reverse engineering technique that requires the dynamic symbol table to be present (no static compilation).

In this technique, you’ll append a fake dynamic symbol table to the end of the binary. Then you’ll repoint the offset in the .dynmsym section header to point to the fake symbol table. Finally, you’ll mix all of the symbol name pointers for the FUNC symbols. This will cause the disassemblers that rely on the sections table, instead of the program headers, to display incorrect function names in the disassembly