Linux课程实践四:ELF文件格式分析
2016-05-28 15:22
573 查看
一、ELF文件格式概述
1. ELF文件
ELF:Executable and Linking Format,是一种对象文件的格式,用于定义不同类型的对象文件(Object files)中都放了什么东西、以及都以什么样的格式去放这些东西。2. 三种类型
(1)可重定位文件
编译器和汇编器创建运行前需要被链接器处理
(2)可执行文件
完成了所有重定位工作和符号解析除了运行时解析的共享库符号
(3)共享库文件
链接器需要的符号信息运行时可以直接执行的代码
二、分析一个ELF文件
以一个最简单的helloworld程序为例1. ELF文件头
使用工具查看ELF文件头:readelf -h obj
在
/usr/include/elf.h中可以找到文件头结构定义:
大小总共为64字节,换算成十六进制为0x40。在十六进制代码中找到前0x40字节,即为文件头信息部分(阅读时注意反序问题):
(1)identification
魔数部分:第一部分:占四个字节。
7f 45 4c 46,应读为
4c 46 45 7f,对应ASCII码
ELF.,表示这是一个ELF对象。
第二部分:占一个字节。
02表示是一个64位对象。
第三部分:占一个字节。
01表示是小端表示法。
第四部分:占一个字节。
01表示文件头版本。
其余默认为
0。
(2)information
信息部分:e_type:两个字节
01 00表示是一个重定位文件。
e_machine:两个字节
3e 00表示是intel80386处理器体系结构。
e_version:四个字节
01 00 00 00表示是当前版本。
e_entry:八个字节。
00 00 00 00 00 00 00 00表示当前程序没有入口点。
e_phoff:八个字节
00 00 00 00 00 00 00 00表示没有程序头表。
e_shoff:八个字节
90 02 00 00 00 00 00 00表示段表的偏移地址在
00 00 00 00 00 00 02 90处。
e_flags:四个字节
00 00 00 00表示未知处理器特定标志
#define EF_SH_UNKNOWN 0x0。
e_ehsize:两个字节
40 00表示elf文件头大小为
00 40(64个字节)。
e_phentsize:两个字节
00 00表示重定位文件没有程序头表。
e_phnum:两个字节
00 00表示重定位文件没有程序头表。
e_ehentsize:两个字节
40 00表示段头大小为
00 40(64字节),section header table中每个header的大小。
e_shnum:两个字节
0d 00表示段表入口有13个,即段表有13段。
e_shstrndx:两个字节
0a 00表示段表字符串在段表中的索引号,.shstrab段的段表索引号为
00 0a,即10.
2. 通过文件头找到各个节
使用工具查看段表信息readelf -S obj
(1)找到段表
在文件头中e_shoff可以找到段表偏移地址
00 00 00 00 00 00 02 90,从这个地址去查找段表。
段表长度由
e_ehentsize为
00 40(64字节)。
段表个数由
e_shnum可知有13个。
/usr/include/elf.h中可以找到段表结构:
(2)分析一个段表
第一个段:全为零,不表示任何段。第二个段:
sh_name:四个字节
20 00 00 00表示该段名称在.shstrtab中偏移量,为.test节。
sh_type:四个字节
01 00 00 00表示这个段拥有程序所定义的信息,其格式和含义完全由该程序确定,这里表示PROGBITS。
sh_flags:八个字节
06 00 00 00 00 00 00 00表示alloc和execute。
sh_addr:八个字节
00 00 00 00 00 00 00 00表示是section在内存中的虚拟地址,.o文件不需要执行,这里都是0。
sh_offset:八个字节
40 00 00 00 00 00 00 00表示是section与文件头之间的偏移。
sh_size:八个字节
11 00 00 00 00 00 00 00表示文件里面section占用的大小。
sh_link:四个字节
00 00 00 00表示没有链接信息。
sh_info:四个字节
00 00 00 00表示没有辅助信息。
sh_addralign:八个字节
01 00 00 00 00 00 00 00表示字节对齐长度。
sh_entsize:八个字节
00 00 00 00 00 00 00 00表示没有入口。
(3)所有段表
第三个段:段名:.rel.text
类型:RELA
标志:info
相对文件头偏移:0x1e0
占用大小:0x30
第四个段
段名:.data
类型:PROGBITS
标志:write、alloc
相对文件头偏移:0x51
占用大小:0
第五个段
段名:.bss
类型:NOBITS
标志:write、alloc
相对文件头偏移:0x51
占用大小:0
第六个段
段名:.rodata
类型:PROGBITS
标志:alloc
相对文件头偏移:0x51
占用大小:0x0b
第七个段
段名:.comment
类型:PROGBITS
标志:merge、strings
相对文件头偏移:0x5c
占用大小:0x26
第八个段
段名:.note.GNU-stack
类型:PROGBITS
标志:无
相对文件头偏移:0x82
占用大小:0
第九个段
段名:.eh_frame
类型:PROGBITS
标志:alloc
相对文件头偏移:0x88
占用大小:0x38
第十个段
段名:.rela.eh_frame
类型:RELA
标志:info
相对文件头偏移:0x210
占用大小:0x18
第十一段
段名:.shstrtab
类型:STRTAB
标志:无
相对文件头偏移:0x228
占用大小:0x61
第十二段
段名:.symtab
类型:STRTAB
标志:无
相对文件头偏移:0xc0
占用大小:0x0108
第十三段
段名:.strtab
类型:STRTAB
标志:无
相对文件头偏移:0x1c8
占用大小:0x11
三、理解常见节
1. .text节
本节中是可执行指令的集合
通过刚才的信息,我们可以从文件中偏移0x40处找到大小为0x11的 .text节:
可以通过反汇编该程序来查看:
2. .rodata
本节是只读数据,ro代表read only
从偏移0x51处找到大小为0x0b的 .rodata节:
使用ASCII码对照表翻译数据为
hello 5317,即.c文件中的字符串:
2. .comment
本节用来存放编译器版本信息
从偏移0x5c处找到大小为0x26的 .comment节:
使用ASCII码对照表翻译出来数据为
GCC:(Debian 5.3.1-8) 5.3.1 20160205
3. .symtab
本节存放所有section中定义的符号名字,一般是变量、函数shstrtab及symtab经常引用strtab中的字符串
从偏移0xc0处找到大小为0x0108的 .symtab节:
4. .strtab
本节是段表的字符串表
从偏移0x1c8处找到大小为0x11的 .strtab节:
数据用“0”分隔出了三部分,用ASCII码翻译:
65 6c 66 2e 63:
elf.c
6d 61 69 6e:
main
70 75 74 73:
puts
相关文章推荐
- linux netstat命令详解
- 3.1 Linux内核的发展与演变
- linux rsync介绍(八)
- linux中的ctags与make命令
- linux - less命令
- CentOS 6 安装 APC(Alternative PHP Cache)
- 从U盘安装Centos 7错误记
- linux服务器维护常用命令
- linux vim 详解
- mprotect()函数 Unix/Linux
- Linux定时任务Crontab使用 提示no crontab for root
- Linux中常用的查询指令(which、whereis、find、locatae)
- Centos 6.4 iptables防火墙关闭启动详解
- linux的操作和配置 (centos 6.7)
- Centos 开放80端口
- 脚本之家--关于linux的资源
- Linux/Unix 桌面趣事:文字模式下的 ASCII 艺术与注释绘画
- Linux套接字实现服务器和客户端通信
- mpi4py在MPICH2上的安装
- 远程连接腾讯云Centos系统的MySQL数据库