Skip to content

Commit 4843229

Browse files
committed
version 2
0 parents  commit 4843229

31 files changed

+1637
-0
lines changed

ELF/ELF.md

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# ELF (Executable and Linkable Format)
2+
**Ever thought why even a the smallest possible piece of code you compile results in some thousands of bytes in size?** <br>
3+
4+
A file is made up of 2 things -
5+
* **Metadata** : It is the information describing the data.
6+
* **Data** : It is the Raw/Actual data. <br>
7+
8+
ELF is the content stored at very begining of an executable and is responsible to direct the OS on how to load the executable into memory for execution. ELF's are the replacement to older object file formats used like **COFF** (**C**ommon **O**bject **F**ile **F**ormat) and **a.out** (**A**ssembler **Out**put) formats.
9+
10+
An ELF constitutes of the following components -
11+
12+
1. **ELF HEADER** : It is the first section of the executable. It describes the organisation of the executable.
13+
2. **PROGRAM HEADER TABLE** : A PHT describes the segments of the executable used at runtime.
14+
3. **SECTION HEADER TABLE** : A SHT lists the sections of the executable
15+
4. **SECTIONS** AND **SEGMENTS** : It is the actual content of the executable. Sections are just blocks of binary present in linking view to produce segment. Segments are blocks composed of one or more sections and are produced by linker.
16+
17+
<p align="center">
18+
<img src="./IMAGES/linking_view_and_execution_view.jpg">
19+
</p>
20+
21+
22+
Before the loading and execution stage, the ELF contains code and data arranged in sectons. At the loding and execution stage, those sections are organised and put up into correspoding segments.
23+
Linker scripts can be made which assists linker on how to combine sections to create segments. We'll study more on linker scripts maybe later in the course.
24+
25+
Have a look at the overall detailed structure of the elf - [IMAGE].
26+
Let's move towards starting disection. Next, we're gonna discuss each of these in detail ahead :)
27+
28+
<br>
29+
30+
**[PREV - INTRODUCTION]** <br>
31+
**[NEXT - ELF HEADER]**
32+
33+
[IMAGE]: ./IMAGES/ELF_DISECTION.png
34+
[PREV - INTRODUCTION]: ./../Introduction/Introduction.md
35+
[NEXT - ELF HEADER]: ./ELF_HEADER/ELF_HEADER.md

ELF/ELF_HEADER/ELF_HEADER.md

+323
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
# ELF HEADER
2+
The elf file header is always present at the offset 0 of the executable (Remember FILE OFFSETS from the [Introduction]?). Let's have a look at the ELF header.
3+
4+
5+
6+
7+
## ANALYSIS
8+
The files `hello_32` and `hello_64` are the 32-bit and 64-bit compiled versions of the file [hello.c].<br>
9+
Lets have a look at the ELF header of the 32-bit compiled binary. I have cross compiled the source code for a 32 bit platform. Try viewing the file with cat.
10+
11+
```shell
12+
ELF��4,4 (44�4�  TT�T�����
13+
14+
�
15+
�
16+
����hh�h�DDP�td�����DDQ�tdR�td
17+
18+
�
19+
���/lib/ld-linux.so.2GNUGNU�z�8��u�6�0P#g�G� �K��6 
20+
��libc.so.6_IO_stdi,��__libc_start_mainGLIBC_2.0__gmon_start__ii
21+
�S�����k��������t�&�[��5����%
22+
�h������%��f�1�^�����PTR�#����p���P�����PQV����P�������$�f�f�f�f����f�f�f�f�f�f�f��$�f�f�f�f�f�f���=�t$���tU����h��Ѓ��É���'�Í�&��'��-����������t ���tU����Ph��҃��Ít&�Í��=�uU����l������Ív�Í�&��'U��]��U���
23+
...
24+
problably some more crap
25+
```
26+
We see here, no meaningful data can be scraped out from this output. Therefore, we ought to use a tool to analyse the information provided by the binary, here comes readelf in action.<br>
27+
28+
### READELF
29+
This tool scraps the ELF binary to extract and display some meaningful information from it. The '-h' flag is used to display ELF header of file `hello_64`.
30+
31+
```shell
32+
critical@d3ad:~/COURSE_DISECTING_BINARIES/ELF/ELF_HEADER$ readelf -h hello_64
33+
ELF Header:
34+
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
35+
Class: ELF64
36+
Data: 2's complement, little endian
37+
Version: 1 (current)
38+
OS/ABI: UNIX - System V
39+
ABI Version: 0
40+
Type: EXEC (Executable file)
41+
Machine: Advanced Micro Devices X86-64
42+
Version: 0x1
43+
Entry point address: 0x4003b0
44+
Start of program headers: 64 (bytes into file)
45+
Start of section headers: 6256 (bytes into file)
46+
Flags: 0x0
47+
Size of this header: 64 (bytes)
48+
Size of program headers: 56 (bytes)
49+
Number of program headers: 9
50+
Size of section headers: 64 (bytes)
51+
Number of section headers: 27
52+
Section header string table index: 26
53+
54+
```
55+
56+
ELF header is actually a structure - `Elf64_Ehdr` defined in file - `/usr/include/elf.h`.
57+
58+
```shell
59+
critical@d3ad:~$ cat /usr/include/elf.h | grep -B16 " Elf64_Ehdr;"
60+
typedef struct
61+
{
62+
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
63+
Elf64_Half e_type; /* Object file type */
64+
Elf64_Half e_machine; /* Architecture */
65+
Elf64_Word e_version; /* Object file version */
66+
Elf64_Addr e_entry; /* Entry point virtual address */
67+
Elf64_Off e_phoff; /* Program header table file offset */
68+
Elf64_Off e_shoff; /* Section header table file offset */
69+
Elf64_Word e_flags; /* Processor-specific flags */
70+
Elf64_Half e_ehsize; /* ELF header size in bytes */
71+
Elf64_Half e_phentsize; /* Program header table entry size */
72+
Elf64_Half e_phnum; /* Program header table entry count */
73+
Elf64_Half e_shentsize; /* Section header table entry size */
74+
Elf64_Half e_shnum; /* Section header table entry count */
75+
Elf64_Half e_shstrndx; /* Section header string table index */
76+
} Elf64_Ehdr;
77+
```
78+
79+
80+
81+
### ANALYSING EACH FIELD OF ELF HEADER
82+
83+
#### Magic
84+
Displays 16 hexadecimal bytes in a row. Here the first 4 bytes (7f 45 4c 46) are called magic numbers. Here first byte is fixed (0x7f). These bytes are used to identify an ELF format. Have a look at the ASCII representation of the hex values (type `man ASCII` to open up ASCII table) and see the values of bytes after 0x7f, i.e. 0x45 0x4c 0x46 are 'E', 'L', 'F' respectively.
85+
86+
87+
| BYTES | Description |
88+
|:----------:|:---------------|
89+
| 7f | It is a Fixed byte |
90+
| 45 4c 46 | ELF signature. Look at the ASCII table (with command <br> `man ASCII`), the values corresponding to them are<br> 'E', 'L', 'F'. This indicates that it is an ELF executable.
91+
| 02 | It is the class described bellow. (ELF64) |
92+
| 01 | It is the Data field described bellow (2's complement,<br>little endian)
93+
| 01 | Version field bellow (Version Number 1)|
94+
| 00 | OS/ABI field bellow (UNIX - System V) |
95+
| 00 00 00 00 00 00 00 00 | Padded bytes for allignment, currently unused, kept<br> for future use.
96+
97+
The file `/usr/include/elf.h` includes the MACROS which define values for each byte.
98+
```shell
99+
critical@d3ad:~$ cat /usr/include/elf.h | grep -n -A2 "EI_MAG"
100+
101+
107:#define EI_MAG0 0 /* File identification byte 0 index */
102+
108-#define ELFMAG0 0x7f /* Magic number byte 0 */
103+
109-
104+
110:#define EI_MAG1 1 /* File identification byte 1 index */
105+
111-#define ELFMAG1 'E' /* Magic number byte 1 */
106+
112-
107+
113:#define EI_MAG2 2 /* File identification byte 2 index */
108+
114-#define ELFMAG2 'L' /* Magic number byte 2 */
109+
115-
110+
116:#define EI_MAG3 3 /* File identification byte 3 index */
111+
117-#define ELFMAG3 'F' /* Magic number byte 3 */
112+
118-
113+
```
114+
115+
Verify the magic field by hd (hexdump) tool.
116+
```shell
117+
critical@d3ad:~/COURSE_DISECTING_BINARIES/ELF/ELF_HEADER$ hd -n 16 hello_64
118+
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
119+
00000010
120+
```
121+
122+
123+
#### Class
124+
The value 0x01, Specifies that it is a 64-bit binary, i.e. it contains 64-bit objects. It is the 5th byte in the 'Magic' field.
125+
126+
| Value | Description |
127+
| :---: | :---------: |
128+
| 1 | 32-bit objects|
129+
| 2 | 64-bit ojects |
130+
131+
```shell
132+
critical@d3ad:~$ cat /usr/include/elf.h | grep -n -A5 "EI_CLASS"
133+
123:#define EI_CLASS 4 /* File class byte index */
134+
124-#define ELFCLASSNONE 0 /* Invalid class */
135+
125-#define ELFCLASS32 1 /* 32-bit objects */
136+
126-#define ELFCLASS64 2 /* 64-bit objects */
137+
127-#define ELFCLASSNUM 3
138+
128-
139+
```
140+
141+
142+
#### Data
143+
This field describes the data encoding (little-endian in this case). You can have a look at the `/usr/include/elf.h` to know what each value means.
144+
145+
| Value | Description |
146+
| :---: | :---------: |
147+
| 1 | 2's complement, little endian |
148+
| 2 | 2's complement, big endian |
149+
150+
```shell
151+
critical@d3ad:~$ cat /usr/include/elf.h | grep -n -A5 "EI_DATA"
152+
129:#define EI_DATA 5 /* Data encoding byte index */
153+
130-#define ELFDATANONE 0 /* Invalid data encoding */
154+
131-#define ELFDATA2LSB 1 /* 2's complement, little endian */
155+
132-#define ELFDATA2MSB 2 /* 2's complement, big endian */
156+
133-#define ELFDATANUM 3
157+
134-
158+
```
159+
160+
#### Version
161+
ELF header version number.
162+
163+
164+
```shell
165+
critical@d3ad:~$ cat /usr/include/elf.h | grep -n -A2 "EI_VERSION"
166+
135:#define EI_VERSION 6 /* File version byte index */
167+
136- /* Value must be EV_CURRENT */
168+
137-
169+
```
170+
171+
#### OS/ABI
172+
These are the values for target OS ABI (**A**pplication **B**inary **I**nterface).
173+
```shell
174+
critical@d3ad:~$ cat /usr/include/elf.h | grep -n -A19 "EI_OSABI"
175+
138:#define EI_OSABI 7 /* OS ABI identification */
176+
139-#define ELFOSABI_NONE 0 /* UNIX System V ABI */
177+
140-#define ELFOSABI_SYSV 0 /* Alias. */
178+
141-#define ELFOSABI_HPUX 1 /* HP-UX */
179+
142-#define ELFOSABI_NETBSD 2 /* NetBSD. */
180+
143-#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */
181+
144-#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */
182+
145-#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */
183+
146-#define ELFOSABI_AIX 7 /* IBM AIX. */
184+
147-#define ELFOSABI_IRIX 8 /* SGI Irix. */
185+
148-#define ELFOSABI_FREEBSD 9 /* FreeBSD. */
186+
149-#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */
187+
150-#define ELFOSABI_MODESTO 11 /* Novell Modesto. */
188+
151-#define ELFOSABI_OPENBSD 12 /* OpenBSD. */
189+
152-#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */
190+
153-#define ELFOSABI_ARM 97 /* ARM */
191+
154-#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
192+
155-
193+
156-#define EI_ABIVERSION 8 /* ABI version */
194+
157-
195+
```
196+
197+
#### TYPE
198+
Identifies the object file type.
199+
200+
```shell
201+
critical@d3ad:~/COURSE_DISECTING_BINARIES/Introduction$ cat /usr/include/elf.h | grep -n -A9 "ET_NONE"
202+
162:#define ET_NONE 0 /* No file type */
203+
163-#define ET_REL 1 /* Relocatable file */
204+
164-#define ET_EXEC 2 /* Executable file */
205+
165-#define ET_DYN 3 /* Shared object file */
206+
166-#define ET_CORE 4 /* Core file */
207+
167-#define ET_NUM 5 /* Number of defined types */
208+
168-#define ET_LOOS 0xfe00 /* OS-specific range start */
209+
169-#define ET_HIOS 0xfeff /* OS-specific range end */
210+
170-#define ET_LOPROC 0xff00 /* Processor-specific range start */
211+
171-#define ET_HIPROC 0xffff /* Processor-specific range end */
212+
```
213+
214+
#### MACHINE
215+
It is the machine specification required to properly run this ELF.
216+
```shell
217+
critical@d3ad:~$ cat /usr/include/elf.h | grep -n -A190 "EM_NONE"
218+
175:#define EM_NONE 0 /* No machine */
219+
176-#define EM_M32 1 /* AT&T WE 32100 */
220+
177-#define EM_SPARC 2 /* SUN SPARC */
221+
178-#define EM_386 3 /* Intel 80386 */
222+
179-#define EM_68K 4 /* Motorola m68k family */
223+
180-#define EM_88K 5 /* Motorola m88k family */
224+
181-#define EM_IAMCU 6 /* Intel MCU */
225+
182-#define EM_860 7 /* Intel 80860 */
226+
183-#define EM_MIPS 8 /* MIPS R3000 big-endian */
227+
184-#define EM_S370 9 /* IBM System/370 */
228+
185-#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */
229+
....
230+
And tons of other machine types (nearly 200)
231+
```
232+
233+
#### VERSION
234+
Specifies the version of the file. (not the ELF header's)
235+
236+
```shell
237+
critical@d3ad:~$ cat /usr/include/elf.h | grep -n -A4 "EV_NONE"
238+
378:#define EV_NONE 0 /* Invalid ELF version */
239+
379-#define EV_CURRENT 1 /* Current version */
240+
380-#define EV_NUM 2
241+
381-
242+
```
243+
244+
#### ENTRY POINT ADDRESS
245+
This specifies the address where the execution of the program starts (.text section)(explained later in the course). If you have ever programmed in C language, it is usually the address of the `main()` function and usually address of `_start` (in assembly programming).
246+
247+
#### START OF PROGRAM HEADERS
248+
It is the offset to the **P**rogram **H**eader **T**able (**PHT**) (explained later in the course), from the very first byte in the file (0x7f present at offset 0).
249+
250+
#### START OF SECTION HEADERS
251+
It is the offset to the **S**ection **H**eader **T**able (**SHT**) (explained later in the course), from the very first byte in the file (0x7f present at offset 0).
252+
253+
#### FLAGS
254+
`EFLAGS` register is set to this value when the program is loaded into memory.
255+
256+
#### SIZE OF THIS HEADER
257+
Displays the size of this 'ELF Header'
258+
259+
#### SIZE OF PROGRAM HEADERS
260+
Displays size of each segment in bytes.
261+
262+
#### NUMBER OF PROGRAM HEADERS
263+
Displays the number of Program Headers (Segments) in the file.
264+
265+
#### SIZES OF SECTION HEADERS
266+
Displays size of each section header.
267+
268+
#### NUMBER OF SECTION HEADERS
269+
Specifies the number of section headers (starting from the NULL entry).
270+
271+
#### SECTION HEADER STRING TABLE INDEX
272+
The value is 26. It means the section at index number 26 (in Section Header Table), stores all the section names (which are NULL terminated strings).
273+
274+
275+
```shell
276+
critical@d3ad:~/COURSE_DISECTING_BINARIES/ELF/ELF_HEADER$ readelf -p 26 hello_64
277+
278+
String dump of section '.shstrtab':
279+
[ 1] .symtab
280+
[ 9] .strtab
281+
[ 11] .shstrtab
282+
[ 1b] .interp
283+
[ 23] .note.ABI-tag
284+
[ 31] .note.gnu.build-id
285+
[ 44] .gnu.hash
286+
[ 4e] .dynsym
287+
[ 56] .dynstr
288+
[ 5e] .gnu.version
289+
[ 6b] .gnu.version_r
290+
[ 7a] .rela.dyn
291+
[ 84] .init
292+
[ 8a] .text
293+
[ 90] .fini
294+
[ 96] .rodata
295+
[ 9e] .eh_frame_hdr
296+
[ ac] .eh_frame
297+
[ b6] .init_array
298+
[ c2] .fini_array
299+
[ ce] .dynamic
300+
[ d7] .got
301+
[ dc] .got.plt
302+
[ e5] .data
303+
[ eb] .bss
304+
[ f0] .comment
305+
306+
307+
```
308+
309+
310+
311+
## NOTE
312+
You can't mug up these things. All this will start making sense after getting some hands on disecting and understanding the ELF binaries. We'll now start with the SHT and the PHT. This was designed to give you an entry point in disection of binaries and so that later on after you complete the course it could prove out to be a good review material :)
313+
314+
315+
<br>
316+
317+
**[PREV - ELF]** <br>
318+
**[NEXT - SECTION HEADER TABLE]**
319+
320+
[Introduction]: ./../../Introduction/Introduction.md
321+
[hello.c]: ./hello.c
322+
[PREV - ELF]: ./../ELF.md
323+
[NEXT - SECTION HEADER TABLE]: ./../SECTION_HEADER_TABLE/SHT.md

ELF/ELF_HEADER/Makefile

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
3+
4+
CFLAGS_64= -no-pie
5+
CFLAGS_32= -m32 -no-pie
6+
7+
8+
all: hello_32 hello_64
9+
10+
11+
hello_32: hello.c
12+
gcc $(CFLAGS_32) $< -o $@
13+
14+
hello_64: hello.c
15+
gcc $(CFLAGS_64) $< -o $@
16+
17+
clean:
18+
rm hello_32 hello_64 *.o

ELF/ELF_HEADER/hello.c

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int main() {}

ELF/ELF_HEADER/hello_32

6.96 KB
Binary file not shown.

ELF/ELF_HEADER/hello_64

7.8 KB
Binary file not shown.

ELF/IMAGES/ELF101_ARM_VERSION.png

583 KB
Loading

ELF/IMAGES/ELF_64.png

707 KB
Loading

ELF/IMAGES/ELF_AT&T_SYNTAX.png

577 KB
Loading

ELF/IMAGES/ELF_DISECTION.png

994 KB
Loading

ELF/IMAGES/SECTION_TYPES.png

54 KB
Loading

ELF/IMAGES/image_source

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://code.google.com/archive/p/corkami/wikis/ELF101.wiki
39.3 KB
Loading

ELF/PROGRAM_HEADER_TABLE/Makefile

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
.PHONY= clean
3+
4+
5+
all: pht pht32
6+
7+
pht: pht.c
8+
gcc -no-pie $< -o $@
9+
10+
pht32: pht.c
11+
gcc -m32 -no-pie $< -o $@
12+
13+
clean:
14+
rm pht pht32

0 commit comments

Comments
 (0)