实践2.4 ELF文件格式分析
實踐2.4 ELF文件格式分析
1.ELF文件頭
查看/usr/include/elf.h文件:
#define EI_NIDENT (16)typedef struct {unsigned char e_ident[EI_NIDENT]; /* 魔數和其他信息 */Elf32_Half e_type; /* 目標文件類型 */Elf32_Half e_machine; /* 硬件平臺 */Elf32_Word e_version; /* elf頭部版本 */Elf32_Addr e_entry; /* 程序進入點 */Elf32_Off e_phoff; /* 程序頭表偏移量 */Elf32_Off e_shoff; /* 節頭表偏移量 */Elf32_Word e_flags; /* 處理器特定標志 */Elf32_Half e_ehsize; /* elf頭部長度 */Elf32_Half e_phentsize; /* 程序頭表中一個條目的長度 */Elf32_Half e_phnum; /* 程序頭表條目數目 */Elf32_Half e_shentsize; /* 節頭表中一個條目的長度 */Elf32_Half e_shnum; /* 節頭表條目數目 */Elf32_Half e_shstrndx; /* 節頭表字符索引 */ } Elf32_Ehdr;typedef struct {unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */Elf64_Half e_type; /* Object file type */Elf64_Half e_machine; /* Architecture */Elf64_Word e_version; /* Object file version */Elf64_Addr e_entry; /* Entry point virtual address */Elf64_Off e_phoff; /* Program header table file offset */Elf64_Off e_shoff; /* Section header table file offset */Elf64_Word e_flags; /* Processor-specific flags */Elf64_Half e_ehsize; /* ELF header size in bytes */Elf64_Half e_phentsize; /* Program header table entry size */Elf64_Half e_phnum; /* Program header table entry count */Elf64_Half e_shentsize; /* Section header table entry size */Elf64_Half e_shnum; /* Section header table entry count */Elf64_Half e_shstrndx; /* Section header string table index */ } Elf64_Ehdr;2.查看相關信息
以實踐2.3中的passwd.c為例:
gcc -c passwd.c -o passwd.o //生成匯編文件 hexdump -x passwd.o //查看十六進制信息objdump –x passwd.o //查看段信息 readelf -a passwd.o //查看段信息使用objdump命令結果如下:
使用readelf命令結果如下:
文件頭:
段表:
符號表:
3.具體分析
3.1 文件頭分析
32位的elf文件頭大小是52字節,如下:
第一行實際內容為7f45 4c46 0101 0100 0000 0000 0000 0000
前四個字節7f45 4c46(0x45,0x4c,0x46是’e','l','f'對應的ASCII)是個魔數(magic number),表示這是一個ELF對象,接下來的一個字節10表示是一個32位對象(如果是64位的對象是02),再接下來的一個字節01表示采用小端法表示,再接下來的一個字節01表示文件頭版本,剩下的默認都設置為0。
第二行:
e_type 2字節 0x0001 表示重定位文件 e_machine 2字節 0x0003 表示386體系文件 e_version 4字節 0x00000001 表示是當前版本 e_entry 4字節 0x00000000 表示程序入口地址(無)第三行:
e_phoff 4字節 0x00000000 表示程序頭表的偏移地址(無) e_shoff 4字節 0x0000018c 表示段表偏移地址 e_flags 4字節 0x00000000 表示處理器特定標志(未知) e_ehsize 2字節 0x0034 表示elf頭部長度 e_phentsize 2字節 0x0000 表示程序頭表中一個條目的長度 e_phnum 2字節 0x0000 表示程序頭表條目數目(0) e_shentsize 2字節 0x0028 表示每個節頭表條目的大小(0x28) e_shnum 2字節 0x000d 表示節頭表條目數(13) e_shstrndx 2字節 0x000a 表示節頭表字符索引(10)由以上可知,節頭表從0x0000018c處開始,每個節區大小為0x28,一共有13個節區,第0xa是段表索引號。
3.2 節區:
第一節區:0x18c-0x1b3
第二節區:0x1b4-0x1db
第三節區:0x1dc-0x203
第四節區:0x204-0x22b
第五節區:0x22c-0x253
第六節區:0x254-0x27b
第七節區:0x27c-0x2a3
第八節區:0x2a4-0x2cb
第九節區:0x2cc-0x2f3
第十節區:0x2f4-0x31b
第十一節區:0x31c-0x343
第十二節區:0x344-0x36b
第十三節區:0x36c-0x393
3.3 節頭表
typedef struct {Elf32_Word sh_name; /* 節名在字符表中的索引 */Elf32_Word sh_type; /* 小節的類型 */Elf32_Word sh_flags; /* 小節屬性 */Elf32_Addr sh_addr; /* 節在運行時的虛擬地址 */Elf32_Off sh_offset; /* 小節的文件偏移 */Elf32_Word sh_size; /* 小節的大小 */Elf32_Word sh_link; /* 鏈接的另外一小節的索引 */Elf32_Word sh_info; /* 附加的小節信息 */Elf32_Word sh_addralign; /* 小節對齊 */Elf32_Word sh_entsize; /* 固定大小的入口的表 */ } Elf32_Shdr;也就是說,在得出上一步的每一個節區的節頭表內容后 ,就可以按照這個表來查找到具體段的段偏移sh_offset和段大小sh_offset。
查看的命令:
readelf命令
如要查看.text段,因為對應的索引為1,所以輸入:
hexdump命令
查閱得知,.text的偏移量是0x34=52,大小是0x65=101
[enter description here][22]
3.4 理解常見段
.text section
可執行指令的集合,.data和.text都是屬于PROGBITS類型的section,這是將來要運行的程序與代碼。.strtab section
屬于STRTAB類型,可以在文件中看到,儲存著符號的名字。.symtab section
存放所有section中定義的符號名字,比如“data_items”,“start_loop”,是屬于SYMTAB類型,它描述了.strtab中的符號在“內存”中對應的“內存地址”。.rodata section
ro代表read only,即只讀數據(const)。[22]:http://images2015.cnblogs.com/blog/744668/201606/744668-20160602202840649-457861662.png
轉載于:https://www.cnblogs.com/20135202yjx/p/5552814.html
總結
以上是生活随笔為你收集整理的实践2.4 ELF文件格式分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [代码整洁]自我感悟
- 下一篇: 6.3站立会议1