ELF文件格式分析

ELF文件格式分析

基本知识:

1.ELF文件的三种类型:

l 可重定位:

编译器和汇编器创建

运行前需要被链接器处理

l 可执行

完成了所有重定位工作和符号解析

除了运行时解析的共享库符号

l 共享库

链接器需要的符号信息

运行时可以直接执行的代码

2.ELF文件的两个视角:

 

3.可重定位目标文件结构:

 

ELF头部

.text

.rodata

.data

.bss

.sym

.rel.txt

.rel.data

.line

.debug

.strtab

节头部表

分析过程

自编一个简单的程序,并对其进行编译。生成一些elf文件:

 

在终端中键入hexdump  -x  hello,会看到很多16进制编码。

数据均为16进制数据(因为使用了-x选项),并且第一列为偏移地址。

使用下面命令来显示hello中各个段相关信息:objdump  –x  hello

输出结果如下:

 

也可以用下面的命令来查看各个段信息:

readelf -a hello

下面分析hello文件内容

文件头分析:

首先是Elf文件头,其定义为(在/usr/include/elf.h中)64位系统包括两部分:

 

 

2.section header

typedef struct

{

  Elf32_Word sh_name; /* Section name (string tbl index) */

  Elf32_Word sh_type; /* Section type */

  Elf32_Word sh_flags; /* Section flags */

  Elf32_Addr sh_addr; /* Section virtual addr at execution */

  Elf32_Off sh_offset; /* Section file offset */

  Elf32_Word sh_size; /* Section size in bytes */

  Elf32_Word sh_link; /* Link to another section */

  Elf32_Word sh_info; /* Additional section information */

  Elf32_Word sh_addralign; /* Section alignment */

  Elf32_Word sh_entsize; /* Entry size if section holds table */

} Elf32_Shdr;

 

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 */

  Elf64_Off sh_offset; /* Section file offset */

  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 */

  Elf64_Xword sh_entsize; /* Entry size if section holds table */

} Elf64_Shdr;

第二行:e_type(两个字节)值为0x0002,表示是一个可执行文件。
e_machine(两个字节)值为0x003e,表示是X86-64的处理器体系结构。
e_version(四个字节)值为0x00000001,表示是当前版本。
e_entry(八个字节)值为0x0550004000000000,表示入口点

第三行:e_phoff(八个字节)值为0x0000000000000000,表示没有程序头表。
e_shoff(八个字节)值为0x0000000000000420,表示段表的偏移地址。

第四行:e_flags(四个字节)值为0x00000000,表示未知处理器特定标志
e_ehsize(两个字节)值为0x0040,表示elf文件头大小;
e_phentsize(两个字节)值均为0x0000,因为重定位文件没有程序头表。
e_phnum(两个字节)的值为0x0000,因为重定位文件没有程序头表。
e_ehentsize(两个字节)值为0x0040表示段头大小为64个字节(由这里知道section header table里面每个header的大小)。
e_shnum(两个字节)值为0x000d,表示段表入口有13个(由这里知道段表有13个段)。
e_shstrndx(两个字节)值为0x000a,表示段名串表的在段表中的索引号(由这里知道.shstrtab段(符号表)的信息在段表的索引号是10)。

由ELF头可知段表从00000420开始,每个节区大小为0040,共有000d个节区,第000a为段名串表的索引号。

第二节区(461-4a0)

第四节区(4e1-520)

第八节区(5e1-620)

第九节区(621-660)

第十二节区(6e1-720)

posted @ 2016-06-02 12:45  20135302魏静静  阅读(778)  评论(0编辑  收藏  举报