We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
通用的ELF文件,我们可以分为四大类:
---------------------------------------- ELF Header(描述基本属性) ---------------------------------------- .text (段1) ---------------------------------------- .data (段2) ---------------------------------------- .bss (段3) ---------------------------------------- ...other sections... ---------------------------------------- Section header tables (段表) ---------------------------------------- String Tables (字符串表) Symbol Tables (符号表) ----------------------------------------
aarch64-none-linux-gnu-gcc main.c -o main
readelf -h main
➜ readelf -h main ELF Header: // e_ident members Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 // ELF 魔数 Class: ELF64 // 有ELF32 / ELF64 Data: 2's complement, little endian Version: 1 (current) // always 1 OS/ABI: UNIX - System V ABI Version: 0 // e_type members Type: EXEC (Executable file) // e_machine members Machine: AArch64 // e_version members Version: 0x1 // e_entry members: 规定ELF程序的入口的虚拟地址,操作系统在加载完程序后从这个地址开始执行进程指令 Entry point address: 0x4004c0 // e_phoff members:ELF链接视图和执行视图相关 Start of program headers: 64 (bytes into file) // e_shoff member:段表在文件中的偏移,从13521字节开始 Start of section headers: 13520 (bytes into file) // e_word Flags: 0x0 // e_ehsize: ELF文件头的大小 Size of this header: 64 (bytes) // e_phentsize: ELF链接视图和执行视图相关 Size of program headers: 56 (bytes) // e_phnum: ELF链接视图和执行视图相关 Number of program headers: 9 // e_shentsize: 段表描述符的大小 一般为sizeof(Elf32_Shdr) Size of section headers: 64 (bytes) // e_shnum: 段表描述符的数量。 Number of section headers: 38 // e_shstrndx: 段表字符串表所在的段在段表中的下标 Section header string table index: 37
ELF的类型可以参考:elf(5) - Linux manual page (man7.org)
段表的作用是,在ELF中记录每个段的基本属性(段名、段的长度、在文件中的偏移、读写权限及段的其他属性)。编译器和链接器还有装载器都需要依靠段表来定位和访问各个段的属性。在elf文件头中e_shoff 决定段表的存储位置。
e_shoff
readelf -S main
➜ work-temp readelf -S main There are 38 section headers, starting at offset 0x34d0: Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [ 1] .interp PROGBITS 0000000000400238 00000238 000000000000001b 0000000000000000 A 0 0 1 [ 2] .note.ABI-tag NOTE 0000000000400254 00000254 0000000000000020 0000000000000000 A 0 0 4 [ 3] .hash HASH 0000000000400278 00000278 0000000000000028 0000000000000004 A 5 0 8 [ 4] .gnu.hash GNU_HASH 00000000004002a0 000002a0 000000000000001c 0000000000000000 A 5 0 8 [ 5] .dynsym DYNSYM 00000000004002c0 000002c0 0000000000000078 0000000000000018 A 6 1 8 [ 6] .dynstr STRTAB 0000000000400338 00000338 0000000000000044 0000000000000000 A 0 0 1 [ 7] .gnu.version VERSYM 000000000040037c 0000037c 000000000000000a 0000000000000002 A 5 0 2 [ 8] .gnu.version_r VERNEED 0000000000400388 00000388 0000000000000020 0000000000000000 A 6 1 8 [ 9] .rela.dyn RELA 00000000004003a8 000003a8 0000000000000018 0000000000000018 A 5 0 8 [10] .rela.plt RELA 00000000004003c0 000003c0 0000000000000060 0000000000000018 AI 5 23 8 [11] .init PROGBITS 0000000000400420 00000420 0000000000000018 0000000000000000 AX 0 0 4 [12] .plt PROGBITS 0000000000400440 00000440 0000000000000060 0000000000000000 AX 0 0 16 [13] .text PROGBITS 00000000004004c0 000004c0 0000000000000214 0000000000000000 AX 0 0 64 [14] CARLOS_FUNC PROGBITS 00000000004006d4 000006d4 0000000000000030 0000000000000000 AX 0 0 4 [15] .fini PROGBITS 0000000000400704 00000704 0000000000000014 0000000000000000 AX 0 0 4 [16] .rodata PROGBITS 0000000000400718 00000718 000000000000002f 0000000000000000 A 0 0 8 [17] .eh_frame_hdr PROGBITS 0000000000400748 00000748 000000000000005c 0000000000000000 A 0 0 4 [18] .eh_frame PROGBITS 00000000004007a8 000007a8 000000000000012c 0000000000000000 A 0 0 8 [19] .init_array INIT_ARRAY 0000000000410de8 00000de8 0000000000000008 0000000000000008 WA 0 0 8 [20] .fini_array FINI_ARRAY 0000000000410df0 00000df0 0000000000000008 0000000000000008 WA 0 0 8 [21] .dynamic DYNAMIC 0000000000410df8 00000df8 00000000000001e0 0000000000000010 WA 6 0 8 [22] .got PROGBITS 0000000000410fd8 00000fd8 0000000000000010 0000000000000008 WA 0 0 8 [23] .got.plt PROGBITS 0000000000410fe8 00000fe8 0000000000000038 0000000000000008 WA 0 0 8 [24] .data PROGBITS 0000000000411020 00001020 0000000000000018 0000000000000000 WA 0 0 8 [25] CARLOS_DATA PROGBITS 0000000000411038 00001038 0000000000000004 0000000000000000 WA 0 0 4 [26] .bss NOBITS 000000000041103c 0000103c 000000000000000c 0000000000000000 WA 0 0 4 [27] .comment PROGBITS 0000000000000000 0000103c 000000000000005d 0000000000000001 MS 0 0 1 [28] .debug_aranges PROGBITS 0000000000000000 000010a0 0000000000000130 0000000000000000 0 0 16 [29] .debug_info PROGBITS 0000000000000000 000011d0 0000000000000715 0000000000000000 0 0 1 [30] .debug_abbrev PROGBITS 0000000000000000 000018e5 00000000000002a1 0000000000000000 0 0 1 [31] .debug_line PROGBITS 0000000000000000 00001b86 000000000000037d 0000000000000000 0 0 1 [32] .debug_str PROGBITS 0000000000000000 00001f03 00000000000004ea 0000000000000001 MS 0 0 1 [33] .debug_loc PROGBITS 0000000000000000 000023ed 0000000000000182 0000000000000000 0 0 1 [34] .debug_ranges PROGBITS 0000000000000000 00002570 0000000000000090 0000000000000000 0 0 16 [35] .symtab SYMTAB 0000000000000000 00002600 0000000000000b10 0000000000000018 36 90 8 [36] .strtab STRTAB 0000000000000000 00003110 0000000000000258 0000000000000000 0 0 1 [37] .shstrtab STRTAB 0000000000000000 00003368 0000000000000161 0000000000000000 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), p (processor specific)
以上表为下列结构体的数组
typedef struct { Elf64_Word sh_name; /* Section name (string tbl index) */ Elf64_Word sh_type; /* Section type */ Elf64_Xword sh_flags; /* Section flags */ Elf64_Addr sh_addr; /* Section virtual addr at execution 如果该段可以被加载,显示为进程空间的虚拟地址,否则为0 */ Elf64_Off sh_offset; /* Section file offset 这段对.bbs没有意义 */ Elf64_Xword sh_size; /* Section size in bytes */ Elf64_Word sh_link; /* Link to another section */ Elf64_Word sh_info; /* Additional section information */ Elf64_Xword sh_addralign; /* Section alignment 有的段有对齐要求,0/1表示没有对其要求 */ Elf64_Xword sh_entsize; /* Entry size if section holds table */ } Elf64_Shdr;
在其他段里面引用了一些段的地址,这些地址单独存成一个重定位表,例如printf("hello world"), 里面的字符串就要被重定位到一个单独的区域。
段名、变量名长度不固定,单独放在一个连续的区域里面,使用偏移来索引字符串。.strtab,.shstrtab字符串表, 在header里面 e_shstrndx: 段表字符串表所在的段在段表中的下标 表示
.strtab
.shstrtab
// main.c #include <stdio.h> int a = 84; int b; const int g = 0xAA; void func(int i) { printf("helloworld!%d\n", i); } __attribute((section("CARLOS_DATA"))) int name = 4; __attribute((section("CARLOS_FUNC"))) int func2 (void){ int m = 9, n = 10; int q; q = m+n; return q; } int main(void) { static int var_1 = 85; static int var_2; int c = 6; int d; func(var_1 + var_2 + c + d); return c; }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
ELF文件结构
1. 文件结构
1.1. Scope
通用的ELF文件,我们可以分为四大类:
1.2. Header
aarch64-none-linux-gnu-gcc main.c -o main
readelf -h main
ELF的类型可以参考:elf(5) - Linux manual page (man7.org)
1.3. Section Header Table(段表)
段表的作用是,在ELF中记录每个段的基本属性(段名、段的长度、在文件中的偏移、读写权限及段的其他属性)。编译器和链接器还有装载器都需要依靠段表来定位和访问各个段的属性。在elf文件头中
e_shoff
决定段表的存储位置。readelf -S main
以上表为下列结构体的数组
重定位表 Relocation Table
在其他段里面引用了一些段的地址,这些地址单独存成一个重定位表,例如printf("hello world"), 里面的字符串就要被重定位到一个单独的区域。
字符串表 String Table
段名、变量名长度不固定,单独放在一个连续的区域里面,使用偏移来索引字符串。
.strtab
,.shstrtab
字符串表, 在header里面 e_shstrndx: 段表字符串表所在的段在段表中的下标 表示附录 I: 原始C文件
The text was updated successfully, but these errors were encountered: