分析一个ELF文件

在计算机科学中,是一种用于二进制文件、可执行文件、目标代码、共享库和核心转储格式文件。
是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI)而开发和发布的,也是Linux的主要可执行文件格式。
1999年,被86open项目选为x86架构上的类Unix操作系统的二进制文件标准格式,用来取代COFF。因其可扩展性与灵活性,也可应用在其它处理器、计算机系统架构的操作系统上。

用hexdump查看foobar的十六进制形式:

[root@localhost testc]# hexdump -C foobar
00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 03 00 01 00 00 00  a0 80 04 08 34 00 00 00  |............4...|
00000020  68 10 00 00 00 00 00 00  34 00 20 00 03 00 28 00  |h.......4. ...(.|
00000030  07 00 06 00 01 00 00 00  00 00 00 00 00 80 04 08  |................|
00000040  00 80 04 08 68 01 00 00  68 01 00 00 05 00 00 00  |....h...h.......|
00000050  00 10 00 00 01 00 00 00  00 10 00 00 00 a0 04 08  |................|
00000060  00 a0 04 08 08 00 00 00  08 00 00 00 06 00 00 00  |................|
00000070  00 10 00 00 51 e5 74 64  00 00 00 00 00 00 00 00  |....Q.td........|
00000080  00 00 00 00 00 00 00 00  00 00 00 00 07 00 00 00  |................|
00000090  10 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000000a0  ff 35 04 a0 04 08 ff 35  00 a0 04 08 e8 24 00 00  |.5.....5.....$..|
000000b0  00 83 c4 08 bb 00 00 00  00 b8 01 00 00 00 cd 80  |................|
000000c0  8b 54 24 08 8b 4c 24 04  bb 01 00 00 00 b8 04 00  |.T$..L$.........|
000000d0  00 00 cd 80 c3 55 89 e5  83 ec 18 8b 45 08 3b 45  |.....U......E.;E|
000000e0  0c 7c 16 c7 44 24 04 0d  00 00 00 c7 04 24 14 81  |.|..D$.......$..|
000000f0  04 08 e8 c9 ff ff ff eb  14 c7 44 24 04 0d 00 00  |..........D$....|
00000100  00 c7 04 24 21 81 04 08  e8 b3 ff ff ff b8 00 00  |...$!...........|
00000110  00 00 c9 c3 74 68 65 20  31 73 74 20 6f 6e 65 0a  |....the 1st one.|
00000120  00 74 68 65 20 32 6e 64  20 6f 6e 65 0a 00 00 00  |.the 2nd one....|
00000130  14 00 00 00 00 00 00 00  01 7a 52 00 01 7c 08 01  |.........zR..|..|
00000140  1b 0c 04 04 88 01 00 00  1c 00 00 00 1c 00 00 00  |................|
00000150  85 ff ff ff 3f 00 00 00  00 41 0e 08 85 02 42 0d  |....?....A....B.|
00000160  05 7b c5 0c 04 04 00 00  00 00 00 00 00 00 00 00  |.{..............|
00000170  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001000  03 00 00 00 04 00 00 00  47 43 43 3a 20 28 47 4e  |........GCC: (GN|
00001010  55 29 20 34 2e 38 2e 35  20 32 30 31 35 30 36 32  |U) 4.8.5 2015062|
00001020  33 20 28 52 65 64 20 48  61 74 20 34 2e 38 2e 35  |3 (Red Hat 4.8.5|
00001030  2d 32 38 29 00 00 2e 73  68 73 74 72 74 61 62 00  |-28)...shstrtab.|
00001040  2e 74 65 78 74 00 2e 72  6f 64 61 74 61 00 2e 65  |.text..rodata..e|
00001050  68 5f 66 72 61 6d 65 00  2e 64 61 74 61 00 2e 63  |h_frame..data..c|
00001060  6f 6d 6d 65 6e 74 00 00  00 00 00 00 00 00 00 00  |omment..........|
00001070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001090  0b 00 00 00 01 00 00 00  06 00 00 00 a0 80 04 08  |................|
000010a0  a0 00 00 00 74 00 00 00  00 00 00 00 00 00 00 00  |....t...........|
000010b0  10 00 00 00 00 00 00 00  11 00 00 00 01 00 00 00  |................|
000010c0  02 00 00 00 14 81 04 08  14 01 00 00 1a 00 00 00  |................|
000010d0  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|
000010e0  19 00 00 00 01 00 00 00  02 00 00 00 30 81 04 08  |............0...|
000010f0  30 01 00 00 38 00 00 00  00 00 00 00 00 00 00 00  |0...8...........|
00001100  04 00 00 00 00 00 00 00  23 00 00 00 01 00 00 00  |........#.......|
00001110  03 00 00 00 00 a0 04 08  00 10 00 00 08 00 00 00  |................|
00001120  00 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|
00001130  29 00 00 00 01 00 00 00  30 00 00 00 00 00 00 00  |).......0.......|
00001140  08 10 00 00 2d 00 00 00  00 00 00 00 00 00 00 00  |....-...........|
00001150  01 00 00 00 01 00 00 00  01 00 00 00 03 00 00 00  |................|
00001160  00 00 00 00 00 00 00 00  35 10 00 00 32 00 00 00  |........5...2...|
00001170  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|
00001180

这里写图片描述

这里写图片描述

开头是ELFheader:

unsigned char e_ident[16]  //7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00

char[2] e_type //02 00 //文件类型 可执行文件
char[2] e_machine //03 00 //运行该程序需要的体系结构位Intel80386
char[4]  e_version //01 00 00 00 //文件的版本
char[4] e_entry //a0 80 04 08 //程序的入口地址。文件foobar的入口地址位0x080480a0
char[4] e_phoff //34 00 00 00 //Program header table在文件中的偏移量(以字节为单位)。这里是0x34

char[4] e_shoff //68 10 00 00 //Section header table在文件中的偏移量(以字节为单位)。这里是0x1068
char[4] e_flags //00 00 00 00 //对IA32而言,此项为0
char[2] e_ehsize //34 00 //ELFheader大小(以字节为单位)。这里是0x34
char[2] e_phentsize //20 00 //Program header table中每一个条目(一个Programheader)的大小。这里是0x20
char[2] e_phnum //03 00 //Program header table中有多少个条目,这里有3个
char[2] e_shentsize //28 00 //Section header table中每一个条目(一个Sectionheader)的大小。这里值为0x28

char[2] e_shnum //07 00 //Section header table中有多少个条目,这里有7个
char[2] e_shstrndx //06 00 //包含节名称的字符串表是第几个节(从零开始数)。这里值为6,表示第6个节包含节名称 

Program header table 在文件中的偏移量(e_phoff)为0x34,而ELF header大小(e_ehsize)也是0x34,可见ELF header后面紧接着就是Program headertable。

这里写图片描述

Program header:

char[4] p_type // 01 00 00 00 // 段的类型
char[4] p_offset // 00 00 00 00 // 段的第一个字节在文件中的偏移
char[4] p_vaddr // 00 80 04 08 // 段的第一个字节在内存中的偏移,0x08048000
char[4] p_paddr // 00 80 04 08 // 在物理地址定位相关的系统中,此项是为物理地址保留

char[4] p_filesz // 68 01 00 00 // 段在文件中的长度,0x168
char[4] p_memsz // 68 01 00 00 // 段在内存中的长度
char[4] p_flags // 05 00 00 00 // 与段相关的标志
char[4] p_align // 00 10 00 00 // 段在文件以及内存中如何对齐,0x1000

Program header描述的是系统准备程序运行所需要的一个段(Segment)或其他信息。
foobar的Program header共有三项(e_phnum=3),偏移分别为0x34~0x53,0x54~0x73,0x74~0x93。

下面是另外两个段:

char[4] p_type // 01 00 00 00 // 段的类型
char[4] p_offset // 00 10 00 00 // 段的第一个字节在文件中的偏移,0x1000
char[4] p_vaddr // 00 a0 04 08 // 段的第一个字节在内存中的偏移,0x0804a000
char[4] p_paddr // 00 a0 04 08 // 在物理地址定位相关的系统中,此项是为物理地址保留

char[4] p_filesz // 08 00 00 00 // 段在文件中的长度,0x8
char[4] p_memsz // 08 00 00 00 // 段在内存中的长度
char[4] p_flags // 06 00 00 00 // 与段相关的标志
char[4] p_align // 00 10 00 00 // 段在文件以及内存中如何对齐,0x1000
char[4] p_type // 51 e5 74 64 // 段的类型
char[4] p_offset // 00 00 00 00 // 段的第一个字节在文件中的偏移
char[4] p_vaddr // 00 00 00 00 // 段的第一个字节在内存中的偏移
char[4] p_paddr // 00 00 00 00 // 在物理地址定位相关的系统中,此项是为物理地址保留

char[4] p_filesz // 00 00 00 00 // 段在文件中的长度
char[4] p_memsz // 00 00 00 00 // 段在内存中的长度
char[4] p_flags // 07 00 00 00 // 与段相关的标志
char[4] p_align // 10 00 00 00 // 段在文件以及内存中如何对齐

foobar在加载进内存后的情况:
这里写图片描述

参考:
于渊《Orange’s 一个操作系统的实现》5.3节
百度百科

猜你喜欢

转载自blog.csdn.net/familyshizhouna/article/details/81170424
今日推荐