I decided to learn more about ELF format to gain better understanding
references: Sys-V ABI, Wikipedia ELF
I tried peeking at the httpd binary using readelf (thanks to the binutils package for making it easier to read):
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x8048060
Start of program headers: 52 (bytes into file)
Start of section headers: 0 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 0
Section header string table index: 0
There are no sections in this file.
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000060 0x08048060 0x08048060 0x00084 0x00084 RWE 0x10
There is no dynamic section in this file.
There are no relocations in this file.
No processor specific unwind information to decode
Dynamic symbol information is not available for displaying symbols.
No version information found in this file.
and the program are only constructed by elf header, program header and the text section
meanwhile, comparing to my hello world program:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x80480bc
Start of program headers: 52 (bytes into file)
Start of section headers: 212 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 3
Size of section headers: 40 (bytes)
Number of section headers: 3
Section header string table index: 2
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 080480bc 000094 00002d 00 WAX 0 0 1
[ 2] .shstrtab STRTAB 00000000 0000c1 000011 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), p (processor specific)
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000094 0x080480bc 0x080480bc 0x0002d 0x0002d RWE 0x4
NOTE 0x000000 0x08048094 0x00000000 0x00000 0x00000 R 0x4
GNU_PROPERTY 0x000000 0x08048094 0x00000000 0x00000 0x00000 R 0x4
Section to Segment mapping:
Segment Sections...
00 .text
01
02
There is no dynamic section in this file.
There are no relocations in this file.
No processor specific unwind information to decode
No version information found in this file.
I can reduce the size by eliminate some part of the binary, but before patching the program, I need to understand how the structure looks like:
00000000: 7f45 4c46 0101 0100 0000 0000 0000 0000 .ELF............
00000010: 0200 0300 0100 0000 bc80 0408 3400 0000 ............4...
00000020: d400 0000 0000 0000 3400 2000 0300 2800 ........4. ...(.
00000030: 0300 0200 0100 0000 9400 0000 bc80 0408 ................
00000040: bc80 0408 2d00 0000 2d00 0000 0700 0000 ....-...-.......
00000050: 0400 0000 0400 0000 0000 0000 9480 0408 ................
00000060: 0000 0000 0000 0000 0000 0000 0400 0000 ................
00000070: 0400 0000 53e5 7464 0000 0000 9480 0408 ....S.td........
00000080: 0000 0000 0000 0000 0000 0000 0400 0000 ................
00000090: 0400 0000 b804 0000 00bb 0100 0000 b9db ................
000000a0: 8004 08ba 0e00 0000 cd80 b801 0000 0031 ...............1
000000b0: dbcd 8068 656c 6c6f 2077 6f72 6c64 210a ...hello world!.
000000c0: 0000 2e73 6873 7472 7461 6200 2e74 6578 ...shstrtab..tex
000000d0: 7400 0000 0000 0000 0000 0000 0000 0000 t...............
000000e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000f0: 0000 0000 0000 0000 0000 0000 0b00 0000 ................
00000100: 0100 0000 0700 0000 bc80 0408 9400 0000 ................
00000110: 2d00 0000 0000 0000 0000 0000 0100 0000 -...............
00000120: 0000 0000 0100 0000 0300 0000 0000 0000 ................
00000130: 0000 0000 c100 0000 1100 0000 0000 0000 ................
00000140: 0000 0000 0100 0000 0000 0000 ............
ELF Header (52 Bytes):
00000000:+0x0 - 00000030:+0x3
Program Header (3 * 32 = 96 Bytes):
00000030:+0x4 - 00000090:+0x3
Segment (64 Bytes):
00000090:+0x4 - 000000d0:+0x3
Section Header (40 * 3 = 120 bytes):
000000d0:+0x4 - 00000140:+0xB
and here's the smol version:
00000000: 7f45 4c46 0101 0100 0000 0000 0000 0000 .ELF............
00000010: 0200 0300 0100 0000 5480 0408 3400 0000 ........T...4...
00000020: 0000 0000 0000 0000 3400 2000 0100 0000 ........4. .....
00000030: 0000 0000 0100 0000 5400 0000 5480 0408 ........T...T...
00000040: 5480 0408 2d00 0000 2d00 0000 0700 0000 T...-...-.......
00000050: 0000 0000 b804 0000 00bb 0100 0000 b973 ...............s
00000060: 8004 08ba 0e00 0000 cd80 b801 0000 0031 ...............1
00000070: dbcd 8068 656c 6c6f 2077 6f72 6c64 210a ...hello world!.
and after manually delete some part of data, I need to adjust item that depends on file like: Entry point address, Load Offset, VirtAddr, PhysAddr, FileSiz, MemSiz, Align and pointer that passed to write syscall
Now my hello wurld program only contain: 52 Bytes ELF header + 32 Bytes Program header + 45 Bytes text section, 128 Bytes in total
I use vim
and xxd
to patch the binary