linux实践之ELF文件分析
linux实践之ELF文件分析

下面开始elf文件的分析。
我们首先编写一个简单的C代码。

编译链接生成可执行文件。

首先,查看scn15elf.o文件的详细信息。

以16进制形式查看scn15elf.o文件。

查看scn15elf.o中各个段和符号表的信息。
各个段的详细信息如下。

符号表的信息如下:

使用readelf命令查看各个段的详细信息:

段表信息如下:

符号表信息如下:

下面让我们开始分析文件头吧!
由于我的虚拟机是32位的,我下面就主要以32位的系统进行分析,就不比较32位机和64位机的区别了。
32位系统elf头文件的定义。

从上图中,我们可知,elf文件头在32位系统中,占52个字节。(16+2+2+4+4+4+4+4+2+2+2+2+2+2=52)转换为16进制表示为0x34个字节。

由于该虚拟机处理器使用小端法表示数据。

分析elf文件头:
第一行:
e_ident用16个字节表示为“7f45 4c46 0101 0100 0000 0000 0000 0000”,其中“7f45 4c46”表示“ELF”的ASCII码表。“0101”中前一个“01”表示是32位的机器,后一个“01”表示使用的是小端法。“0100”中的“01”表示的是版本号是01。剩下的0为默认填充。
第二行:
e_type用2个字节表示,为“0001”,表示是一个重定向文件。
e_machine用2个字节表示,为“0003”,表示Inter 80386的处理器体系结构(32位)
e_version用4个字节表示,为“0000 0001”,表示的是当前版本。
e_entry用4个字节表示,为“0000 0000 ”表示没有入口点。
e_phoff用4个字节表示,为“0000 0000”表示没有程序头表。
第三行:
e_shoff用4个字节表示,为“0000 0228”表示段表的偏移地址。
e_flags用4个字节表示,为“0000 0000”表示未知处理器特定标志。
e_ehsize用2个字节表示,为“0034”表示elf文件头大小。
e_phentsize用2个字节表示,为“0000”,因为重定位文件没有程序头表。
e_phnum用2个字节表示,为“0000”,因为重定位文件没有程序头表。
e_shentsize用2个字节表示,为“0028”,表示段头大小为“0x28”字节,即为40个字节(由此知道section header table里面每一个table的大小为40个字节)。
第四行:
e_shnum用2个字节表示,为“000d”,表示段表入口有13个,这里可以知道,段有13个。
e_shstrndx用2个字节表示,为“000a”,表示段名串表在段表中的索引,(符号表的信息在段表的索引号是10)。
自己手工分析完后,可以和“readelf”指令读出的数据进行比较。

分析段表:

首先我们根据刚刚在elf文件头中读到的段表偏移,找到段表的起始,我们可以看到偏移为“0x228”。从上图中段表的数据结构中可以看出,段表占40个字节(4*10=40字节即“0x28个字节”),这个结果和我们从elf文件头中读到的结果一致。

由于第一个段中有一部分数据没有读出来,所以我们以第二个段(偏移为0x0000268~0x00002a7)为例分析:
sh_name用4个字节表示,为“0000 001f”,该值代表section header string table中的索引。
sh_type 用4个字节表示,为“0000 0001”,表示该段的类型是“SHT_PROGBITS”。
sh_flags 用4个字节表示,为“0000 0006”,指示该section在进程执行时的特性。其中最低位如果为1 表示此节在进程执行过程中可写,次低位为1表示此节的内容加载时要读到内存中去,第三低位为1表示这个节中的数据是可执行的机器指令。这里表明该节在进程执行过程中不可写,在内容加载时要读到内存中去,该节数据是可执行的机器指令。
sh_addr 用4个字节表示,为“0000 0000”,表示该节在进程中的起始地址为“0x0000 0000”。
sh_offset用4个字节表示,为“0000 0034”表示该节在整个文件中的起始偏移量为“0x34”。
sh_size用4个字节表示,为“0000 002e”,表示该节的字节大小为2e。
sh_link用4个字节表示,为“0000 0000”,表示没有和该节相关联的节。
sh_info用4个字节表示,为“0000 0000”表示没有文件信息
sh_addralign用4个字节表示,为“0000 0001”,该值用于表示地址对齐信息,值为1时表示不用地址对齐。
sh_entsize用4个字节表示,为“0000 0000”,对特定节(动态符号)才有意义,这里没有意义。
总结:从section header table找到各个section头的信息,还是很简单的。
只要知道其序列号(第几个节)。寻找偏移“0x228+第i个节*0x28”即可。
通过从section header table中读到的信息,我们来找一找这个字段的内容。
经分析知,该节内容起始,距文件头0x34的位置,内容大小为0x2e个字节。

如图所示,该节的内容即为图中高亮的部分。我们反汇编一下scn15elf.o文件,结果为

对比发现两个结果是一致的。
分析各个section。(.text .strtab .symtab .rodata)

①.text节
分析见上一步的例子,已经分析完了。
②.strtab节
.strtab中存放的是符号的名字(符号表示一个固定的内存地址)。
计算该节的偏移=0x228+12*0x28=0x408。

sh_name用4个字节表示,为“0000 0009”,该值代表section header string table中的索引。即.strtab节。
sh_type 用4个字节表示,为“0000 0003”,表示该段的类型是“SHT_STRTAB”。
sh_flags 用4个字节表示,为“0000 0000”,指示该section在进程执行时的特性。表明该节在进程执行过程中不可写,在内容加载时不需要读到内存中去,该节数据不是可执行的机器指令。
sh_addr 用4个字节表示,为“0000 0000”,表示该节在进程中的起始地址为“0x0000 0000”。
sh_offset用4个字节表示,为“0000 00198”表示该节在整个文件中的起始偏移量为“0x198”。
sh_size用4个字节表示,为“0000 0016”,表示该节的字节大小为16。
sh_link用4个字节表示,为“0000 0000”,表示没有和该节相关联的节。
sh_info用4个字节表示,为“0000 0000”表示没有文件信息
sh_addralign用4个字节表示,为“0000 0001”,该值用于表示地址对齐信息,值为1时表示不用地址对齐。
sh_entsize用4个字节表示,为“0000 0000”,对特定节(动态符号)才有意义,这里没有意义。
总结上面的分析是,该节距离文件头偏移为0x198,内容大小为0x16。

③.symtab节
该节中存放着所有section中定义的符号名字。描述了.strtab节中的符号在“内存”中对应的“内存地址”。这里的“内存地址”指的是偏移量,不是真的内存地址。
计算该节的偏移=0x228+11*0x28=0x3E0。

sh_name用4个字节表示,为“0000 0001”,该值代表section header string table中的索引。即.symtab节。
sh_type 用4个字节表示,为“0000 0002”,表示该段的类型是“SHT_STRTAB”。
sh_flags 用4个字节表示,为“0000 0000”,指示该section在进程执行时的特性。表明该节在进程执行过程中不可写,在内容加载时不需要读到内存中去,该节数据不是可执行的机器指令。
sh_addr 用4个字节表示,为“0000 0000”,表示该节在进程中的起始地址为“0x0000 0000”。
sh_offset用4个字节表示,为“0000 00e8”表示该节在整个文件中的起始偏移量为“0xe8”。
sh_size用4个字节表示,为“0000 00b0”,表示该节的字节大小为16。
sh_link用4个字节表示,为“0000 000c”,表示没有和该节相关联的节。
sh_info用4个字节表示,为“0000 0009”表示没有文件信息
sh_addralign用4个字节表示,为“0000 0004”,该值用于表示地址对齐信息,值为4时表示需要地址对齐。
sh_entsize用4个字节表示,为“0000 0010”,表示字节大小。
总结上面的分析是,该节距离文件头偏移为0xe8,内容大小为0xb0。

对比符号表里的内容。

④.rodata节
rodata的意义同样明显,ro代表read only,即只读数据(const)。关于rodata类型的数据,要注意以下几点:
1、常量不一定就放在rodata里,有的立即数直接编码在指令里,存放在代码段(.text)中。
对于字符串常量,编译器会自动去掉重复的字符串,保证一个字符串在一个可执行文件(EXE/SO)中只存在一份拷贝。
2、rodata是在多个进程间是共享的,这可以提高空间利用率。
3、有的嵌入式系统中,rodata放在ROM(如norflash)里,运行时直接读取ROM内存,无需要加载到RAM内存中。
4、在嵌入式linux系统中,通过一种叫作XIP(就地执行)的技术,也可以直接读取,而无需要加载到RAM内存中。
计算该节的偏移=0x228+5*0x28=0x2F0。

sh_name用4个字节表示,为“0000 030”,该值代表section header string table中的索引。即.rodata节。
sh_type 用4个字节表示,为“0000 0001”,表示该段的类型是“SHT_STRTAB”。
sh_flags 用4个字节表示,为“0000 0002”,指示该section在进程执行时的特性。表明该节在进程执行过程中不可写,在内容加载时不需要读到内存中去,该节数据不是可执行的机器指令。
sh_addr 用4个字节表示,为“0000 0000”,表示该节在进程中的起始地址为“0x0000 0000”。
sh_offset用4个字节表示,为“0000 0062”表示该节在整个文件中的起始偏移量为“0x62”。
sh_size用4个字节表示,为“0000 0013”,表示该节的字节大小为13。
sh_link用4个字节表示,为“0000 0000”,表示没有和该节相关联的节。
sh_info用4个字节表示,为“0000 0000”表示没有文件信息
sh_addralign用4个字节表示,为“0000 0001”,该值用于表示地址对齐信息,值为1时表示不用地址对齐。
sh_entsize用4个字节表示,为“0000 0000”,对特定节(动态符号)才有意义,这里没有意义。
总结上面的分析是,该节距离文件头偏移为0x62,内容大小为0x13。

参考资料
http://blog.chinaunix.net/uid-9068997-id-2010376.html
linux实践之ELF文件分析的更多相关文章
- Linux实践:ELF文件格式分析
标签(空格分隔): 20135321余佳源 一.基础知识 ELF全称Executable and Linkable Format,可执行连接格式,ELF格式的文件用于存储Linux程序.ELF文件(目 ...
- linux第三次实践:ELF文件格式分析
linux第三次实践:ELF文件格式分析 标签(空格分隔): 20135328陈都 一.概述 1.ELF全称Executable and Linkable Format,可执行连接格式,ELF格式的文 ...
- Linux及安全实践四——ELF文件格式分析
Linux及安全实践四——ELF文件格式分析 一.ELF文件格式概述 1. ELF:是一种对象文件的格式,用于定义不同类型的对象文件中都放了什么东西.以及都以什么样的格式去放这些东西. 二.分析一个E ...
- Linux课题实践四——ELF文件格式分析
2.4 ELF文件格式分析 20135318 刘浩晨 ELF全称Executable and Linkable Format,可执行连接格式,ELF格式的文件用于存储Linux程序.ELF文件(目 ...
- 20135218 实践四 ELF文件格式分析
一 :概述 ELF全称Executable and Linkable Format,可执行连接格式,ELF格式的文件用于存储Linux程序.ELF文件(目标文件)格式主要三种: (1)可重定向文件:文 ...
- linux内核分析ELF文件分析实践报告
- ELF文件分析
(1)文件ELF.c (2)编译: gcc -c ELF_1.c -o ELF_1.o (3)显示文件类型: (4)查看大小: (5)转换为16进制 (6)显示各段信息 (7)分析
- linux源码“.config”文件分析
一..config文件概述 .config文件是linux内核配置文件,当执行#make uImage编译生成内核时,顶层的Makefile会读取.config文件的内容,根据这个配置文件来编译所定制 ...
- ELF格式文件分析以及运用
基于本文的一个实践<使用Python分析ELF文件优化Flash和Sram空间的案例>. 1.背景 ELF是Executable and Linkable Format缩写,其官方规范在& ...
随机推荐
- js实现四舍六入 奇进偶舍
function PointFloat(src, pos) { return Math.round(src * Math.pow(10, pos)) / Math.pow(10, pos); } // ...
- 解决IE8 内置JSON.stringify,中文变unicode的问题
转自:http://my.oschina.net/u/919074/blog/191131 项目中出现在IE下出现把json对象转为json串中文变成unicode的问题,最后经过排查,发现是IE8内 ...
- 与你相遇好幸运,Postgresql和postgis安装
笔者开发环境: windows 7 x86_64 一开始安装的是官网最新版 PostgreSQL 9.6 ,安装成功 之后安装PostGIS Bundle 2.2 for PostgreSQL x64 ...
- CSC321 神经网络语言模型 RNN-LSTM
主要两个方面 Probabilistic modeling 概率建模,神经网络模型尝试去预测一个概率分布 Cross-entropy作为误差函数使得我们可以对于观测到的数据 给予较高的概率值 同时可以 ...
- rhel5.8安装oracle 10g ASM
1.所有的配置和文件系统一样 2.规划: 加了8块小盘,ASM为了实验使用asmlib驱动(rhel6不再支持asmlib驱动),裸设备的2种方法(rowdevice和udev) 三块盘使用asmli ...
- vue
vue.js 插件 setting--> plugins 搜索vue,下载安装如果想要高亮显示*.vue文件,可以在File Types 选项里找到HTML,然后在下方手动添加*.vue,这样就 ...
- [Unity3D]Unity+Android交互教程——让手机"动"起来
想要用Unity实现一个二维码扫描的功能,然后网上找插件,找到一个貌似叫EasyCodeScanner,但下载下来用用,真不好使,一导入运行就报错,调好错了再运行发现点按钮没反应,反复试了几遍发现还是 ...
- Python学习笔记(三)——类型与变量
一.输入与输出 print("string"); print("string1","string2","string3" ...
- Android onActivityResult没响应
原因: 1.当MainActivity2的启动模式为SingleTask时, 系统为自动返回setResult(Activity.RESULT_CANCELED). 2.当为MainActivity2 ...
- PDA 收银系统PDA手持打印扫描枪 销售开单 收银 扫描打印一体机
在零售方面也有很好的应用.如在一些高端品牌零售店,营业员可以随身导购,一站式完成了商品销售和收银,很是受消费者追捧,符合了企业对客户体验以及行业领先的追求. PDA收银系统是一款多功能可以取代专业收银 ...