The types of elf files under Linux are divided into the following categories:
1, can relocate files, such as SIMPLESECTION.O;
2, executable files, such as/bin/bash;
3, share the target file, such as/lib/libc.so.
In the Linux relocatable file elf structure article, we have analyzed the relocatable file elf structure. This article analyzes the ELF structure of executable files.
First, attach the source code:
Sectionmapping.c
#include <stdlib.h>int main () {while (1) {sleep (1000);} return 0;}
Use the command gcc-static sectionmapping.c-o sectionmapping.elf, a static link to an executable file.
Then use the command readelf-s sectionmapping.elf to get section Table. As follows:
There is headers, starting at offset 0xc3878:section headers: [Nr] Name Type Address Offset Size entsize Flags Link Info Align [0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [1]. Note. Abi-tag NOTE 0000000000400190 00000190 0000000000000020 0000000000000000 A 0 0 4 [2]. note.gnu.build-i Note 00000000004001b0 000001b0 0000000000000024 0000000000000000 A 0 0 4 [3]. rela.plt rela 00000000004001d8 000001d8 0000000000000120 0000000000000018 A 0 5 8 [4]. init progbits 00000000004002f8 000002f8 0000000000000018 000000000 0000000 AX 0 0 4 [5]. PLT progbits 0000000000400310 00000310 00000000000000c0 0000000000000000 AX 0 0 [6]. Text progbits 00000000004003d0 000003d0 0000000000094988 0000000000000000 AX 0 0 [7] __libc_thread_fre progbits 0000000000494d60 00094d60 00000000000000a8 0000000000000 Microsoft Dynamics AX 0 0 [8] __libc_freeres_fn progbits 0000000000494e10 00094e10 000000000000181c 0 000000000000000 AX 0 0 [9]. Fini progbits 000000000049662c 0009662c 0000000 00000000e 0000000000000000 AX 0 0 4 [ten]. Rodata progbits 0000000000496640 00096640 000000000001d344 0000000000000000 A 0 0 [one] __libc_thread_sub progbits 00000000004b3988 000b3988 0000000000000008 0000000000000000 A 0 0 8 [] __libc_subfreeres progbits 000000 00004b3990 000b3990 0000000000000058 0000000000000000 A 0 0 8 [] __libc_atexit progbits 00000000004b39e8 000b39e8 0000000000000008 0000000000000000 A 0 0 8 [+]. Eh_frame Progbits 00000000 004b39f0 000b39f0 000000000000d4c4 0000000000000000 A 0 0 8 []. gcc_except_table progbits 00000000004C0EB4 000c0eb4 0000000000000172 0000000000000000 A 0 0 1 [+]. Tdata PRO Gbits 00000000006c1ef0 000c1ef0 0000000000000020 0000000000000000 WAT 0 0 [+]. TBSS Nobits 00000000006c1f10 000c1f10 0000000000000038 0000000000000000 WAT 0 0 16 [1 8]. Init_array init_array 00000000006c1f10 000c1f10 0000000000000008 0000000000000000 WA 0 0 8 [+]. Fini_array fini_array 00000000006c1f18 000c1f18 0000000000000008 0000000000000000 WA 0 0 8 []. ctors progbits 00000000006c1f20 000c1f20 0000000000000010 00000000000 00000 WA 0 0 8 []. dtors progbits 00000000006c1f30 000c1f30 0000000000000010 0000000000000000 WA 0 0 8 []. JCR progbits 00000000006c1f40 000c1f40 0000000000000008 0000000000000 WA 0 0 8 []. data.rel.ro progbits 00000000006C1F50 000c1f50 0000000000000080 00 00000000000000 WA 0 0 [+]. Got progbits 00000000006c1fd0 000c1fd0 00000000 00000010 0000000000000008 WA 0 0 8 [+]. GOT.PLT progbits 00000000006c1fe8 000c1fe8 0000000000000078 0000000000000008 WA 0 0 8 [+]. Data progbits 00000000006c2060 0 00c2060 0000000000001690 0000000000000000 WA 0 0 [+]. BSS nobits 0000000 0006c3700 000c36f0 0000000000002ba8 0000000000000000 WA 0 0 [] __libc_freeres_pt nobits 00000000006c62b0 000c36f0 0000000000000048 0000000000000000 WA 0 0 []. Comment Progbits 0000000 000000000 000c36f0 000000000000002a 0000000000000001 MS 0 0 1 [in]. Shstrtab strtab 0000000000000000 000c371a 000000000000015b 0000000000000000 0 0 1 []. Symtab SY MTAB 0000000000000000 000c40b8 000000000000c168 0000000000000018 8 870 [+]. Strtab Strtab 0000000000000000 000d0220 0000000000007a26 0000000000000000 0 0 1
Table 1
This executable has a total of 33 sections.
We then use readelf-h sectionmapping.elfto read the elf executable header information. Such as:
Figure 1
Can be compared, the Linux relocatable file elf structure, here is more program header.
Entry Point Address: The program's entry addresses are 0x401058, using objdump-d sectionmapping.elf |Less, you can see the entry address of the program is <_ Start>. such as:
Figure 2
Start of program Headers:program headers is offset, because the header file size is 64, so program headers is stored next to the header file.
Size of program Headers:program headers. is 56 bytes.
Number of section Headers:program headers. is 6.
In table 1, the first section in the file is offset by 0x190, the header file size is * + Program header size is 6 * Program Header number = x = 0x190.
Then we use the command readelf-l sectionmapping.elfand we get the program header section. such as:
Figure 3
Visible, divided into 6 Segment. Note that each segment in table 1 is called section.
Offset: This segment is offset in the file.
VIRTADDR: This segment is offset from the virtual address.
Filesiz: The length of the elf file.
Memsiz: The length of the virtual space occupied by the process.
We found a second segment,memsiz > Filesiz, which indicates that the amount of space allocated in memory exceeds the actual size of the file. The portion of the excess is all initialized to 0 as a BSS segment. Because the only difference between a data segment and a BSS segment is that the data segment initializes the content from the file, and the BSS section contents are all initialized to 0.
We are primarily concerned with the first two segment, which is the code snippet, the virtual address from 0x00400000 to 0x004c1026. File offset from 0x00000000 to 0x000c1026.
The second is the data segment, where the virtual address is from 0x006c1ef0 to 0x006c1ef0+0x4408=0x6c62f8. file offsets from 0X000C1EF0 to 0x000c1ef0+0x1800=0x000c36f0.
Combining the file offsets of table 1 and two segment, you can conclude that:
The first segment from the No. 0 section to the 15th section. (0x00000000-0x000c1026)
[Nr] Name Type Address Offset Size entsize Flags Link Info Al IGN [0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [1]. Note. Abi-tag NOTE 0000000000400190 00000190 0000000000000020 0000000000000000 A 0 0 4 [2]. note.gnu.build-i Note 00000000004001b0 000001b0 0000000000000024 0000000000000000 A 0 0 4 [3]. rela.plt rela 00000000004001d8 000001d8 0000000000000120 0000000000000018 A 0 5 8 [4]. init progbits 00000000004002f8 000002f8 0000000000000018 000000000 0000000 AX 0 0 4 [5]. PLT progbits 0000000000400310 00000310 00000000000000c0 0000000000000000 AX 0 0 [6]. Text Progbits 00000000004003d0 000003d0 0000000000094988 0000000000000000 AX 0 0 [7] __libc_thread_fre progbits 0000000000494D6 0 00094d60 00000000000000a8 0000000000000000 AX 0 0 [8] __LIBC_FREERES_FN Progbits 000 0000000494e10 00094e10 000000000000181c 0000000000000000 AX 0 0 [9]. Fini progbits 000000000049662c 0009662c 000000000000000e 0000000000000000 AX 0 0 4 [ten]. Rodata Progbits 0000000000496640 00096640 000000000001d344 0000000000000000 A 0 0 [one] __l Ibc_thread_sub progbits 00000000004b3988 000b3988 0000000000000008 0000000000000000 A 0 0 8 [__libc_subfreeres] progbits 00000000004b3990 000b3990 0000000000000058 0000000000000000 A 0 0 8 [] __libc_atexit progbits 00000000004b39e8 000b39e8 0000000000000008 0000000000000000 A 0 0 8 Eh_frame progbits 00000000004b39f0 000b39f0 000000000000d4c4 0000000000000000 A 0 0 8 []. gcc_except_table progbits 00000000004c0eb4 000c0eb4 0000000000000172 0000000000000000 A 0 0 1
The second segment from the 16th section to 26 sections. (0x000c1ef0-0x000c36f0 )
[+]. Tdata progbits 00000000006c1ef0 000c1ef0 0000000000000020 0000000000000000 WAT 0 0 [+]. TBSS nobits 00000000006c1f10 000c1f10 0000000000000038 0000000000000000 WAT 0 0 [+]. Init_array init_array 00000000006c1f10 000c1f10 0000000000000008 00000 00000000000 WA 0 0 8 [+]. Fini_array fini_array 00000000006c1f18 000c1f18 000000000000 0008 0000000000000000 WA 0 0 8 []. ctors progbits 00000000006c1f20 000c1f20 0 000000000000010 0000000000000000 WA 0 0 8 [+]. dtors progbits 00000000006C1F30 000C1 F30 0000000000000010 0000000000000000 WA 0 0 8 []. JCR progbits 00000000006c 1f40 000c1f40 0000000000000008 0000000000000000 WA 0 0 8 []. data.rel.ro progbits 0 0000000006C1F50 000c1f50 0000000000000080 0000000000000000 WA 0 0 [+]. Got Progbits 00000000006c1 Fd0 000c1fd0 0000000000000010 0000000000000008 WA 0 0 8 [+]. GOT.PLT progbits 00 000000006c1fe8 000c1fe8 0000000000000078 0000000000000008 WA 0 0 8 [+]. Data progbits 00000000006c2060 000c2060 0000000000001690 0000000000000000 WA 0 0 32
The above analysis is the static state of the program, below we look at the dynamic process of how the space is allocated.
First use the command, ./sectionmapping.elf &, Output is as follows:
Then use the command:cat/proc/2184/maps, the output is as follows:
Figure 4
At rest, we calculate the offsets for the virtual spaces of the two segment:
The first is the code snippet, the virtual address from 0x00400000 to 0x004c1026. In Figure 4, because the page is aligned, 0x400000 to 0x4c2000 are assigned.
The second is the data segment, where the virtual address is a 0X006C1EF0 to 0x006c1ef0+0x4408=0x 6c62f8. In Figure 4, because the page is aligned, 0x6c1000 to 0x6c4000 are assigned. Note that 0x6c62f8 is greater than 0x6c4000, the specific reason for further analysis.
The third is followed by a heap. Used to dynamically allocate memory.
The fourth one is the stack. Used to store local variables.
The overall structure is as follows:
Program run Process: Establish virtual space (allocation of a page directory), create virtual space and executable mapping (page directory entry to disk program), skip to the program portal, page fault exception, look for free pages in memory, and the corresponding pages into the mapping- > Start execution.
Linux executable ELF structure and program load run