一 :概述

ELF全称Executable and Linkable Format,可执行连接格式,ELF格式的文件用于存储Linux程序。ELF文件(目标文件)格式主要三种:

(1)可重定向文件:文件保存着代码和适当的数据,用来和其他的目标文件一起来创建一个可执行文件或者是一个共享目标文件。

(目标文件或者静态库文件,即linux通常后缀为.a和.o的文件)

(2)可执行文件:文件保存着一个用来执行的程序。(例如bash,gcc等)

(3)共享目标文件:共享库。文件保存着代码和合适的数据,用来被下连接编辑器和动态链接器链接。(linux下后缀为.so的文件)

一般的 ELF 文件包括三个索引表:ELF header,Program header table,Section header table。

  • ELF header:在文件的开始,保存了路线图,描述了该文件的组织情况。
  • Program header table:告诉系统如何创建进程映像。用来构造进程映像的目标文件必须具有程序头部表,可重定位文件不需要这个表。
  • Section header table:包含了描述文件节区的信息,每个节区在表中都有一项,每一项给出诸如节区名称、节区大小这类信息。 用于链接的目标文件必须包含节区头部表,其他目标文件可以有,也可以没有这个表。
  • e_type表示文件类型,2表示可执行文件。

    e_machine:指明可以在哪种机器结构中运行。

    e_version:指明版本信息

    e_entry:指明系统运行该程序时将控制权转交到的虚拟地址的值,如果没有则为零。

    e_phoff: program header table在文件中的字节(Byte)偏移offset,如果没有program header table, 则该值为零。

    e_shoff: section header table在文件中的字节偏移,如果没有section header table, 则该值为零

    e_flags: 有关处理器的信息

    e_ehsize: elf header的大小,单位:字节

    e_phentsize: 在program header table中一个entry的大小,前面提到过,program header table & section header table都是数组,所以它们的每一个元素,即每一个entry的大小,都是一样的。

    e_phnum: program header table中元素的个数,即entry的个数。

    e_shentsize: section header table每一个entry的大小,与e_phentsize类似。

    e_shnum: section header table中元素的个数,即entry的个数。可以看出来,这个program header table或者section header table的大小可以用entry的个数乘以每一个entry的大小得到。

    e_shstrndx: 指明string name table在section header table中的index。

二:分析ELF文件头。

1. 进入终端输入:cd /usr/include 进入include文件夹后查看elf1.h文件,查看ELF的文件头包含整个文件的控制结构。

2. 写一个简单的代码,进行编译运行,生成elf可执行文件。

使用‘readelf –a elf1’命令,都得到下面的ELF Header头文件的信息,如下图:

3.如下图使用:‘hexdump –x elf1 –n ’命令来查看elf1文件头的16进制表对格式进行分析。

  • 第一行,对应e_ident[EI_NIDENT]。实际表示内容为7f454c46010101000000000000000000;前四个字节7f454c46(0x45,0x4c,0x46是'e','l','f'对应的ascii编码)是一个魔数,表示这是一个ELF对象。接下来的一个字节01表示是一个32位对象,接下来的一个字节01表示是小端法表示,再接下来的一个字节01表示文件头版本。剩下的默认都设置为0.
  • 第二行,e_type值为0x0002,表示是一个可执行文件。(若为0x0001,表示重定位文件)。

e_machine值(2字节)为0x0003,说明是intel 80386。

e_version值(4字节)为0x00000100,表示是当前版,0是非法版本。e_entry值为0x8048320 ,表示入口点。

  • 第三行,e_shoff值为0x114c,表示段表的偏移地址。

e_phoff(4字节)值为0x00000034 ,表示程序头表

e_flags(4字节)0x00000000,表示未知处理器特点标志(#define EF_SH_UNKNOWN 0x0)

e_ehsize(2字节)0x0034,表示ELF文件头大小为0x34H,(64位的是0x40H)

e_phentsize(2字节)0x0020,program header的大小是32比特。

e_phnum(2字节) 0x0009,program headers的数量是9个

                    e_ ehentsize(2字节) 0x0028,表示段头大小为40字节(由此可知section header table 里面表个header的大小)

e_ shnum(2字节) 0x001e,表示段表入口地址有30个(由此知道段表有30个段)

e_shstrndx (2字节) 0x001b,表示段名串表的在段表中的索引号(由此知.shstrtab段(符号表)的信息在段表的索引号是27)

4.使用readelf -h elf1查看ELF文件头,将上述分析结果进行对比。

三、通过文件头找到section header table,理解其内容。

file elf1显示生成的目标文件elf1的类型

elf1是一个可执行文件。输入:ls –l elf1查看elf1的大小:

输入:hexdump –x elf1来用16进制的数字来显示elf1的内容(第二列是16进制表示的偏移地址)

输入:objdump –x elf1来显示elf1中各个段以及符号表的相关信息:program header:程序头。

输入:readelf –a hello来查看各个段信息:

section header table:

符号表 Symbol table:

四、通过section header table找到各section

在一个ELF文件中有一个section header table,通过它我们可以定位到所有的 section,而 ELF header 中的e_shoff 变量就是保存 section header table 入口对文件头的偏移量。而每个 section 都会对应一个 section header ,所以只要在 section header table 中找到每个 section header,就可以通过 section header 找到你想要的 section。

使用‘vi /usr/include/elf1.h ’命令查看Sections Header的结构体:

 由之前文件头的分析可知:e_shoff(4字节)值为0x0000114C,表示段表的偏移地址

 e_ ehentsize(2字节) 0x0028,表示段头大小为40字节(由此可知section header table 里面表个header的大小)

 e_ shnum(2字节) 0x001e,表示段表入口地址有30个(由此知道段表有30个段)

 段表大小 28H*1e=08B0

所以从0x0000114C—0X000019FC,存储的是段表。

  • 第一个段,其中内容全部为0,所以不表示任何段。

  • 第二个段,为.interp段
  • 第三个段,为.note.ABI-tag段。

  • 第四个段,为.note.gnu.build-i段。

  • 第五个段,为.gnu.hash段。

我们用readelf 命令去查看.text这个 section 中的内容,
   输入readelf –x 13 elf1,(.text前面的标号为13)对13索引号的.text的section的内容进行查看:

下面用 hexdump 的方法去读取.text这个 section 中的内容,通过看section header中.text中offset和size分别是0x000320和0x0001b2,通过16进制向10进制转换得到     offset:800和size:418。
输入 hexdump –s 800 –n 418 –C elf1

得到了和上面的readelf得到的相同。
使用下面命令对elf1的文本段(.text)进行反汇编:
objdump –d elf1得到如下图,可以看出,使用反汇编的16进制数据和前面查找到的是相同的。

五、理解常见.text .strtab .symtab .rodata等section

①.text section是可执行指令的集合,.data和.text都是属于PROGBITS类型的section,这是将来要运行的程序与代码。查询段表可知.text section的位偏移为0x8048320,size为0x0001b2。

②.strtab section是属于STRTAB类型的section,可以在文件中看到,它存着字符串,储存着符号的名字。位偏移为0x0000000,size为0x000251。

③.symtab section存放所有section中定义的符号名字,比如“data_items”,“start_loop”。 .symtab section是属于SYMTAB类型的section,它描述了.strtab中的符号在“内存”中对应的“内存地址”。 位偏移为0x00000000,size0x000430为。

④.rodata section,ro代表read only。位偏移为0x08048e8,size为0x000010。

20135218 实践四 ELF文件格式分析的更多相关文章

  1. Linux及安全实践四——ELF文件格式分析

    Linux及安全实践四——ELF文件格式分析 一.ELF文件格式概述 1. ELF:是一种对象文件的格式,用于定义不同类型的对象文件中都放了什么东西.以及都以什么样的格式去放这些东西. 二.分析一个E ...

  2. Linux课题实践四——ELF文件格式分析

    2.4   ELF文件格式分析 20135318 刘浩晨 ELF全称Executable and Linkable Format,可执行连接格式,ELF格式的文件用于存储Linux程序.ELF文件(目 ...

  3. linux第三次实践:ELF文件格式分析

    linux第三次实践:ELF文件格式分析 标签(空格分隔): 20135328陈都 一.概述 1.ELF全称Executable and Linkable Format,可执行连接格式,ELF格式的文 ...

  4. Linux实践:ELF文件格式分析

    标签(空格分隔): 20135321余佳源 一.基础知识 ELF全称Executable and Linkable Format,可执行连接格式,ELF格式的文件用于存储Linux程序.ELF文件(目 ...

  5. 实践2.4 ELF文件格式分析

    实践2.4 ELF文件格式分析 1.ELF文件头 查看/usr/include/elf.h文件: #define EI_NIDENT (16) typedef struct { unsigned ch ...

  6. 20135337——linux实践三:ELF文件格式分析(32位系统)

    ELF文件格式分析 可重定位文件 十六进制形式显示内容 显示各个段.符号表相关信息 查看各个段信息 elf文件头信息 段表 符号表信息 查看堆栈 具体分析 1.ELF文件头信息(小字节优先,均十六进制 ...

  7. 20135306 2.4 ELF文件格式分析

    2.4   ELF文件格式分析 20135306 黄韧 ELF全称Executable and Linkable Format,可执行连接格式,ELF格式的文件用于存储Linux程序.ELF文件(目标 ...

  8. linux实践之ELF文件分析

    linux实践之ELF文件分析 下面开始elf文件的分析. 我们首先编写一个简单的C代码. 编译链接生成可执行文件. 首先,查看scn15elf.o文件的详细信息. 以16进制形式查看scn15elf ...

  9. Linux课程实践四:ELF文件格式分析

    一.ELF文件格式概述 1. ELF文件 ELF:Executable and Linking Format,是一种对象文件的格式,用于定义不同类型的对象文件(Object files)中都放了什么东 ...

随机推荐

  1. 软件工程实践_Task2_sudoku

    软工实践_Task2 标签(空格分隔): 软工实践 相关要求:第二次作业--个人项目实战 github:传送门 解题思路 先是一点杂谈. 首先,看完作业要求之后,心里先有个大概的框架. 语言:C++ ...

  2. jeDate 日期控件

    写在前面的话: 最近在做一个日期范围的功能,研究了一个12306网站的日期范围选择,他用的是jcalendar.js,没有直接在日历插件里面做判断开始时间小于结束时间 而是自己在代码里面做了判断如下: ...

  3. spring.factories

    在Spring Boot中有一种非常解耦的扩展机制:Spring Factories.这种扩展机制实际上是仿照Java中的SPI扩展机制来实现的. Java SPI机制SPI的全名为Service P ...

  4. 基于Redis实现的抢购代码示例

    示例代码是基于博客 https://blog.csdn.net/qq1013598664/article/details/70183908的错误案例修改而来,如果有问题望多多指点,错误代码可以去原文查 ...

  5. linux(centos 7)下安装elasticsearch 5 的 IK 分词器

    (一)到IK 下载 对应的版本(直接下载release版本,避免mvn打包),下载后是一个zip压缩包 (二)将压缩包上传至elasticsearch 的安装目录下的plugins下,进行解压,运行如 ...

  6. PLSQL Developer12连接远程Oracle xe 11g

    目标: .学习使用docker下载oracle xe 11g .使用PLSQL连上启动运行oracle xe 11g容器服务 1.准备工作 Linux 安装docker 下载PLSQL Develop ...

  7. js将有父子关系的数据转换成树形结构数据

    js将有父子关系的数据转换成树形结构数据 比如如下基本数据: let allDatas = [ { id: 3, name: 'bbbb', parendId: 1 }, { id: 2, name: ...

  8. #ifdef __cplusplus extern "C" { #endif”的定义

      平时我们在linux c平台开发的时候,引用了一些Cpp或者C的代码库,发现一些头文件有如下代码条件编译. #ifdef __cplusplus extern "C" { #e ...

  9. 浅析单点登录,以及不同二级域名下的SSO实现

    一家公司有多个产品线,就可能要有多个子域名,下头以baidu域名为例,a.baidu.com, b.baidu.com.com 是顶级域名,baidu 就是一个二级域名,a和b就是子域名. 当用户在a ...

  10. 如何传递参数给ASP.NET Core的中间件(Middleware)

    问题描述 当我们在ASP.NET Core中定义和使用中间件(Middleware)的时候,有什么好的办法可以给中间件传参数吗? 解决方案 在ASP.NET Core项目中添加一个POCO类来传递参数 ...