0x01 - The Executable Header
Explore the foundational aspects of the ELF binary format in this introductory article. Learn about the Executable Header, its fields, and how it defines essential details such as architecture, endianness, and entry point. Build a clear understanding of the structure that every Linux executable begins with, setting the stage for deeper exploration of ELF internals.
Table of Content
Section titled “Table of Content”ELF stands for Executable and Linkable Format which is the file format used by binary executable on linux system.
Every ELF Binary has following section in it -
- Executable Header
- Sections
- Program Header
- Section Header
In all the binaries position of executable header is fixed (First position). among all tables only executable header table is mandatory.
The type definition of all the sections is included in /usr/include/elf.h
The Executable Header
Section titled “The Executable Header”Here ELF64_Half
and ELF64_Word
are just the typedef for integer types such as uint16_t
.
e_ident
Section titled “e_ident”It is an 16 byte character array which start with 4 byte magic number 0x7f and ASCII encoding of chars ELF. Other bytes of this array are refered to as EI_CLASS, EI_DATA, EI_VERSION, EI_OSABI, EI_ABIVERSION, and EI_PAD.
EI_CLASS :
- Size - 1 byte
- Denotes the binary is for which architecture (32 or 64) - Constant ELFCLASS32 (equals as 1) and ELFCLASS64 (equals to 2) are used as the value.
EI_DATA :
- Size - 1 byte
- Denotes the endianess for storing the data - It can be either constant ELFDATA2LSB (equal to 1) or ELFDATA2MSB (equal to 2).
EI_VERSION :
- Size - 1 byte
- Denotes the version of the ELF Specifiaction during creation of the binary - Constant EV_CURRENT (equal to 1) is the onlt possible value.
EI_OSABI and EI_ABIVERSION :
- Size - Each field is of 1 byte
- ABI is application binary interface which defines rules for the communication between the computer and the program,
- EI_OSABI - If this field contains a non zero value than it means there are some ABI or OS Extensions are used. Default value is zero which means it targets UNIX V System ABI.
- EI_ABIVERSION - It denotes the specific version of the ABI defined in the OSABI. No need to specify any version when using the default value for EI_OSABI.
We can view the Executable Headers of any ELF Binary using -
readelf -h <binary>
e_type , e_version , e_version fields
Section titled “e_type , e_version , e_version fields”All this are multibyte integer fields giving more information about the binary.
e_type :
- Defines the type of the binary
- Size - 2 byte
- Values - ET_REL (Relocation means Object File) ,ET_EXEC (Executable File) ,ET_DYN (Dynamic Library / Shared Library)
e_version :
- Denotes the architecture support
- Size - 2 byte
- Values - EM_X86_64 (64 bit), EM_386 (32 bit), EM_ARM
e_entry :
- Denotes the version of the ELF specification used during creation of binary. (Yes it is similar to EI_VERSION in the e_ident array)
- Size - 4 byte
- Value - EV_CURRENT (equal to 1)
e_entry
Section titled “e_entry”- This stores the virtual address where the actual binary data (instructions and data) is loaded.
- Size - 8 byte
e_phoff and e_shoff
Section titled “e_phoff and e_shoff”As we know the position os the program header table and the section header table is not fixed so we need some fields that tell us about thier positon in the binary and for that purpose e_phoff and e_shoff is used. e_phoff contains the offset for the program header table and e_shoff contains the offset for the section header table.
- Size - 8 bytes each
e_flags
Section titled “e_flags”We can set flags values to add more information to the binary. Flag values are architecture dependent.
- Size - 4 Bytes
e_ehsize
Section titled “e_ehsize”It defines the size of the executable header table.
- Size - 2 Bytes
- Value - 64 Byte for x86_64 bit and x86_32 bit binary
e_entsize and e_num
Section titled “e_entsize and e_num”Here *
is the wild card
e_*entsize (e_phentsize and e_shentsize) :
- It tells the size of the program header table and section header table.
- Size - 2 byte
e_*num (e_phnum and e_shnum)
- It tells the number of header present in program header table and section header table
- Size - 2 byte
e_shstrndx field
Section titled “e_shstrndx field”There is a special table called as string table which contains null terminated ASCII string which are names for all the sections present in the binary. information about the string table is stored in the section header table whose index is stored in the e_shstrndx field.
e_shstrndx -> position in section header table where it’s information is tored -> actual location of hte string table.
Conclusion
Section titled “Conclusion”In this article, we explored the structure and fields of the ELF Executable Header, the foundation of every ELF binary. From the e_ident array to offsets, flags, and the string table index, these fields define how the operating system interprets a binary.
Understanding the Executable Header is the first step toward reading and analyzing ELF files. In the next part of this series, we’ll dive into the Program Header and see how it describes segments that are loaded into memory during execution.