ELF格式简介
ELF是现代linux/unix流行的程序可执行链接格式,它有官方定义文档,具体的资料在Tool Interface Standard Executable and Linking Format Specification version 1.2 有其对应的详细描述。我在这里不会讲述关于这个格式详细描述,如果我叙述的有什么不对的地方,欢迎指正出来。当然一切都以官方的参考文档为标准,建议您在阅读本文的时候,手边最好有一份官方定义文档参考。
ELF由三个头表描述:ELF header,section header,programer (segment) header。
简单的说,ELF格式描述的是编译生成的二进制可链接文件,可共享库文件,以及可执行文件的数据组织形式,或者说内存组织形式。我们知道,程序可以分为从编译生成的静态内存分布和动态链接执行两个方面来理解,ELF格式也是基于此来构成两个基本视图的:section view和 segment view;前者描述了静态的视图,对应的详细描述定义在section header里,后者则描述了动态链接执行的视图,对应的详细描述定义在segment header。可以说ELF确实是一个抽象良好的格式描述形式,因为这样做简化了格式描述的复杂性,也节省了在内核中管理和描述格式的内存开销。这也可以理解到为什么现代unix/linux流行逐渐放弃a.out格式和COEFF格式,而是采用ELF来作为二进制程序文件的描述的原因。
另外不同的计算机体系结构在字长,CPU架构,大小端等方面是有明显的差异。ELF格式的二进制文件为了在不同的体系结构中正确的被内核理解,所以它会在ELF header 中的16字节长的e_indent数组详细描述该二进制文件对应的体系结构,包括对应的字长,CPU架构,大小端等。我们知道系统的字长直接在系统位数反应出来;所以,为了兼容不同位数的系统,我们对于每一个视图的详细描述都定义了两种字长的结构。当然,在ELF header 还详细描述了其它的信息,比如程序的入口点e_entry, 节表(section header)的文件头偏移等等。
从通俗的角度来说,ELF header 是整个文件的总管家,对程序数据组织形式的理解都是从它开始的,通过它再转到其它对应信息的二管家,例如:segment header,section header,然后层层深入,最后到达想要的信息地址。
在这里我只是给出我自己关于ELF header/section header/segment header 的代码,不详细解释定义的结构中各个字段的意思,官方文档里边已经描述的很详细了,请自己去那里仔细的阅读,它可以很好的解释您的疑问。
ELF header
1: typedef struct
2: {
3: unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
4: Elf32_Half e_type; /* Object file type */
5: Elf32_Half e_machine; /* Architecture */
6: Elf32_Word e_version; /* Object file version */
7: Elf32_Addr e_entry; /* Entry point virtual address */
8: Elf32_Off e_phoff; /* Program header table file offset */
9: Elf32_Off e_shoff; /* Section header table file offset */
10: Elf32_Word e_flags; /* Processor-specific flags */
11: Elf32_Half e_ehsize; /* ELF header size in bytes */
12: Elf32_Half e_phentsize; /* Program header table entry size */
13: Elf32_Half e_phnum; /* Program header table entry count */
14: Elf32_Half e_shentsize;
15: Elf32_Half e_shnum;
16: Elf32_Half e_shstrndx;
17: } SEF_ELFHEADER_32;
18:
19: typedef struct
20: {
21: unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
22: Elf64_Half e_type; /* Object file type */
23: Elf64_Half e_machine; /* Architecture */
24: Elf64_Word e_version; /* Object file version */
25: Elf64_Addr e_entry; /* Entry point virtual address */
26: Elf64_Off e_phoff; /* Program header table file offset */
27: Elf64_Off e_shoff; /* Section header table file offset */
28: Elf64_Word e_flags; /* Processor-specific flags */
29: Elf64_Half e_ehsize; /* ELF header size in bytes */
30: Elf64_Half e_phentsize; /* Program header table entry size */
31: Elf64_Half e_phnum; /* Program header table entry count */
32: Elf64_Half e_shentsize; /* Section header table entry size */
33: Elf64_Half e_shnum; /* Section header table entry count */
34: Elf64_Half e_shstrndx; /* Section header string table index */
35: }SEF_ELFHEADER_64;
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
SECTION header
1: /* Section header. */
2:
3: typedef struct
4: {
5: Elf32_Word sh_name; /* Section name (string tbl index) */
6: Elf32_Word sh_type; /* Section type */
7: Elf32_Word sh_flags; /* Section flags */
8: Elf32_Addr sh_addr; /* Section virtual addr at execution */
9: Elf32_Off sh_offset; /* Section file offset */
10: Elf32_Word sh_size; /* Section size in bytes */
11: Elf32_Word sh_link; /* Link to another section */
12: Elf32_Word sh_info; /* Additional section information */
13: Elf32_Word sh_addralign; /* Section alignment */
14: Elf32_Word sh_entsize; /* Entry size if section holds table */
15: } SEF_SECHEADER_32;
16:
17: typedef struct
18: {
19: Elf64_Word sh_name; /* Section name (string tbl index) */
20: Elf64_Word sh_type; /* Section type */
21: Elf64_Xword sh_flags; /* Section flags */
22: Elf64_Addr sh_addr; /* Section virtual addr at execution */
23: Elf64_Off sh_offset; /* Section file offset */
24: Elf64_Xword sh_size; /* Section size in bytes */
25: Elf64_Word sh_link; /* Link to another section */
26: Elf64_Word sh_info; /* Additional section information */
27: Elf64_Xword sh_addralign; /* Section alignment */
28: Elf64_Xword sh_entsize; /* Entry size if section holds table */
29: } SEF_SECHEADER_64;
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
SEGMENT header
1: /* Program segment header. */
2:
3: typedef struct
4: {
5: Elf32_Word p_type; /* Segment type */
6: Elf32_Off p_offset; /* Segment file offset */
7: Elf32_Addr p_vaddr; /* Segment virtual address */
8: Elf32_Addr p_paddr; /* Segment physical address */
9: Elf32_Word p_filesz; /* Segment size in file */
10: Elf32_Word p_memsz; /* Segment size in memory */
11: Elf32_Word p_flags; /* Segment flags */
12: Elf32_Word p_align; /* Segment alignment */
13: } SEF_PROHEADER_32;
14:
15: typedef struct
16: {
17: Elf64_Word p_type; /* Segment type */
18: Elf64_Word p_flags; /* Segment flags */
19: Elf64_Off p_offset; /* Segment file offset */
20: Elf64_Addr p_vaddr; /* Segment virtual address */
21: Elf64_Addr p_paddr; /* Segment physical address */
22: Elf64_Xword p_filesz; /* Segment size in file */
23: Elf64_Xword p_memsz; /* Segment size in memory */
24: Elf64_Xword p_align; /* Segment alignment */
25: } SEF_PROHEADER_64;
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
这里给出我的头文件:elf_type.h
1: #ifndef _ELF_TYPE_H
2: #define _ELF_TYPE_H
3: #include<stdint.h>
4:
5: #define ELFCLASSNONE (0)
6: #define ELFCLASS32 (1)
7: #define ELFCLASS64 (2)
8:
9: #define ELFDATANONE (0)
10: #define ELFDATA2LSB (1)
11: #define ELFDATA2MSB (2)
12:
13: #define ET_NONE (0)
14: #define ET_REL (1)
15: #define ET_EXEC (2)
16: #define ET_DYN (3)
17:
18: #define E_PHNUM (65535)
19: #define NULL ((void *)0)
20:
21: /* Type for a 16-bit quantity. */
22: typedef uint16_t Elf32_Half;
23: typedef uint16_t Elf64_Half;
24:
25: /* Types for signed and unsigned 32-bit quantities. */
26: typedef uint32_t Elf32_Word;
27: typedef int32_t Elf32_Sword;
28: typedef uint32_t Elf64_Word;
29: typedef int32_t Elf64_Sword;
30:
31: /* Types for signed and unsigned 64-bit quantities. */
32: typedef uint64_t Elf32_Xword;
33: typedef int64_t Elf32_Sxword;
34: typedef uint64_t Elf64_Xword;
35: typedef int64_t Elf64_Sxword;
36:
37: /* Type of addresses. */
38: typedef uint32_t Elf32_Addr;
39: typedef uint64_t Elf64_Addr;
40:
41: /* Type of file offsets. */
42: typedef uint32_t Elf32_Off;
43: typedef uint64_t Elf64_Off;
44:
45: /* Type for section indices, which are 16-bit quantities. */
46: typedef uint16_t Elf32_Section;
47: typedef uint16_t Elf64_Section;
48:
49: /* Type for version symbol information. */
50: typedef Elf32_Half Elf32_Versym;
51: typedef Elf64_Half Elf64_Versym;
52:
53: //char *pBuffer;
54: /* The ELF file header. This appears at the start of every ELF file. */
55:
56: #define EI_NIDENT (16)
57:
58: typedef struct
59: {
60: unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
61: Elf32_Half e_type; /* Object file type */
62: Elf32_Half e_machine; /* Architecture */
63: Elf32_Word e_version; /* Object file version */
64: Elf32_Addr e_entry; /* Entry point virtual address */
65: Elf32_Off e_phoff; /* Program header table file offset */
66: Elf32_Off e_shoff; /* Section header table file offset */
67: Elf32_Word e_flags; /* Processor-specific flags */
68: Elf32_Half e_ehsize; /* ELF header size in bytes */
69: Elf32_Half e_phentsize; /* Program header table entry size */
70: Elf32_Half e_phnum; /* Program header table entry count */
71: Elf32_Half e_shentsize;
72: Elf32_Half e_shnum;
73: Elf32_Half e_shstrndx;
74: } SEF_ELFHEADER_32;
75:
76: typedef struct
77: {
78: unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
79: Elf64_Half e_type; /* Object file type */
80: Elf64_Half e_machine; /* Architecture */
81: Elf64_Word e_version; /* Object file version */
82: Elf64_Addr e_entry; /* Entry point virtual address */
83: Elf64_Off e_phoff; /* Program header table file offset */
84: Elf64_Off e_shoff; /* Section header table file offset */
85: Elf64_Word e_flags; /* Processor-specific flags */
86: Elf64_Half e_ehsize; /* ELF header size in bytes */
87: Elf64_Half e_phentsize; /* Program header table entry size */
88: Elf64_Half e_phnum; /* Program header table entry count */
89: Elf64_Half e_shentsize; /* Section header table entry size */
90: Elf64_Half e_shnum; /* Section header table entry count */
91: Elf64_Half e_shstrndx; /* Section header string table index */
92: }SEF_ELFHEADER_64;
93:
94:
95:
96: /* Program segment header. */
97:
98: typedef struct
99: {
100: Elf32_Word p_type; /* Segment type */
101: Elf32_Off p_offset; /* Segment file offset */
102: Elf32_Addr p_vaddr; /* Segment virtual address */
103: Elf32_Addr p_paddr; /* Segment physical address */
104: Elf32_Word p_filesz; /* Segment size in file */
105: Elf32_Word p_memsz; /* Segment size in memory */
106: Elf32_Word p_flags; /* Segment flags */
107: Elf32_Word p_align; /* Segment alignment */
108: } SEF_PROHEADER_32;
109:
110: typedef struct
111: {
112: Elf64_Word p_type; /* Segment type */
113: Elf64_Word p_flags; /* Segment flags */
114: Elf64_Off p_offset; /* Segment file offset */
115: Elf64_Addr p_vaddr; /* Segment virtual address */
116: Elf64_Addr p_paddr; /* Segment physical address */
117: Elf64_Xword p_filesz; /* Segment size in file */
118: Elf64_Xword p_memsz; /* Segment size in memory */
119: Elf64_Xword p_align; /* Segment alignment */
120: } SEF_PROHEADER_64;
121:
122: /* Section header. */
123:
124: typedef struct
125: {
126: Elf32_Word sh_name; /* Section name (string tbl index) */
127: Elf32_Word sh_type; /* Section type */
128: Elf32_Word sh_flags; /* Section flags */
129: Elf32_Addr sh_addr; /* Section virtual addr at execution */
130: Elf32_Off sh_offset; /* Section file offset */
131: Elf32_Word sh_size; /* Section size in bytes */
132: Elf32_Word sh_link; /* Link to another section */
133: Elf32_Word sh_info; /* Additional section information */
134: Elf32_Word sh_addralign; /* Section alignment */
135: Elf32_Word sh_entsize; /* Entry size if section holds table */
136: } SEF_SECHEADER_32;
137:
138: typedef struct
139: {
140: Elf64_Word sh_name; /* Section name (string tbl index) */
141: Elf64_Word sh_type; /* Section type */
142: Elf64_Xword sh_flags; /* Section flags */
143: Elf64_Addr sh_addr; /* Section virtual addr at execution */
144: Elf64_Off sh_offset; /* Section file offset */
145: Elf64_Xword sh_size; /* Section size in bytes */
146: Elf64_Word sh_link; /* Link to another section */
147: Elf64_Word sh_info; /* Additional section information */
148: Elf64_Xword sh_addralign; /* Section alignment */
149: Elf64_Xword sh_entsize; /* Entry size if section holds table */
150: } SEF_SECHEADER_64;
151:
152: #endif
ELF格式解析库之基本数据类型