《Linux内核分析》 实践四——ELF文件格式分析

20135211李行之

一、概述

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

  • 可重定向文件:文件保存着代码和适当的数据,用来和其他的目标文件一起来创建一个可执行文件或者是一个共享目标文件。(目标文件或者静态库文件,即linux通常后缀为.a和.o的文件)
  • 可执行文件:文件保存着一个用来执行的程序。(例如bash,gcc等)
  • 共享目标文件:共享库。文件保存着代码和合适的数据,用来被下连接编辑器和动态链接器链接。(linux下后缀为.so的文件。)
    目标文件既要参与程序链接又要参与程序执行:

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

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

二、分析ELF文件头(ELF header)

  • 进入终端输入:cd /usr/include 进入include文件夹后查看elf.h文件,查看ELF的文件头包含整个文件的控制结构
  • 写一个小程序(hello 20135211)进行编译,生成hello可执行文件。
    使用‘readelf –a hello’命令,都得到下面的ELF Header头文件的信息,如下图:
  • 通过上图信息,可以得出Elf Header的Size为64bytes,所以可以使用hexdump工具将头文件的16进制表打开。
    如下图使用:‘hexdump –x hello –n 64’命令来查看hello文件头的16进制表(前64bytes)对格式进行分析。
  • 第一行,对应e_ident[EI_NIDENT]。实际表示内容为7f454c46020101000000000000000000,前四个字节7f454c46(0x45,0x4c,0x46是'e','l','f'对应的ascii编码)是一个魔数,表示这是一个ELF对象。接下来的一个字节02表示是一个64位对象,接下来的一个字节01表示是小端法表示,再接下来的一个字节01表示文件头版本。剩下的默认都设置为0.
  • 第二行,e_type值为0x0002,表示是一个可执行文件。e_machine值为0x003e,表示是Advanced Micro Devices X86-64处理器体系结构。e_version值为0x00000100,表示是当前版本。e_entry值为0x 004003f0,表示入口点。
  • 第三行,e_phoff值为0x40,表示程序头表。e_shoff值为0x1278,表示段表的偏移地址。
  • 第四行,e_flags值为0x00000000,表示未知处理器特定标志。e_ehsize值为0x0040,表示elf文件头大小(正好是64bytes)。e_phentsize表示一个program header表中的入口的长度,值为0x0038。e_phnum的值为0x0008,给出program header表中的入口数目。e_shentsize值为0x0040表示段头大小为64个字节。e_shnum值为0x001f,表示段表入口有31个。e_shstrndx值为0x001c,表示段名串表的在段表中的索引号。

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

  • file elf1显示生成的目标文件hello的类型
  • elf1是一个可执行文件。输入:ls –l hello查看hello的大小:
  • 如图可知,hello大小为6712字节。
    输入:hexdump –x hello来用16进制的数字来显示hello的内容
    (其中,第二列是16进制表示的偏移地址)
  • 输入:objdump –x hello来显示hello中各个段以及符号表的相关信息:
  • 输入:readelf –a hello来查看各个段信息:
  • ELF文件头信息:
  • 段表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。

下面以可执行文件hello为例,以保存代码段的 section 为例来讲解读取某个section 的过程。
使用‘vi /usr/include/elf.h ’命令查看Sections Header的结构体:

由上面分析可知,section headers table中的每一个section header所占的size均为64字节,ELF header得到了e_shoff变量的值为0X1278,也就是table入口的偏移量,通过看e_shnum值为0x001f,表示段表入口有31个。
所以从0x00001278开始有31个段,每个段占64个字节大小,输入 hexdump elf1查看:

  • 第一个段,其中内容全部为0,所以不表示任何段。
  • 第二个段,为.interp段,段偏移sh_offset为0X200,段大小sh_size为0X1c。
  • 第三个段,为.note.ABI-tag段,段偏移sh_offset为0X21c,段大小sh_size为0X 20。
  • 第四个段,为.note.gnu.build-i段,段偏移sh_offset为0X 23c,段大小sh_size为0X 24。
  • 第五个段,为.gnu.hash段,段偏移sh_offset为0X 260,段大小sh_size为0X 1c。

…………

  • 第十四个段,为.text段, 段偏移sh_offset为0X 3f0, 段大小sh_size为0X 182。
  • 第二十五个段,为.data段, 段偏移sh_offset为0X 8d8, 段大小sh_size为0X 10。
  • 第二十六个段,为.bss段, 段偏移sh_offset为0X 8e8(红线),段大小sh_size为0X 08。
  • 第二十九个段, 为.symtab段,段偏移sh_offset为0X910,段大小sh_size为0X0648。
  • 第三十个段, 为.strtab段,段偏移sh_offset为0Xf58,段大小sh_size为0X214.

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

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

得到了和上面的readelf得到的相同。
使用下面命令对hello的文本段(.text)进行反汇编:
objdump –d hello 得到如下图:

可以看出,使用反汇编的16进制数据和前面查找到的是相同的。

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

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

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

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

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

《Linux内核分析》实践4的更多相关文章

  1. linux内核分析实践二学习笔记

    Linux实践二--内核模块的编译 标签(空格分隔): 20135328陈都 理解内核的作用 Linux内核[kernel]是整个操作系统的最底层,它负责整个硬件的驱动,以及提供各种系统所需的核心功能 ...

  2. 《Linux内核分析》期末总结

    Linux内核设计期中总结 版权声明:本文为博主原创文章,未经博主允许不得转载. 前八周博客汇总及总结 Linux内核设计第一周——从汇编语言出发理解计算机工作原理 我们学习了汇编语言的基础知识,这一 ...

  3. 《Linux及安全》期中总结&《Linux内核分析》期终总结

    [5216 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK NINE ...

  4. 《Linux内核分析》第五周 扒开系统调用的三层皮(下)

    [刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK FIVE( ...

  5. Linux内核分析第五周学习总结:扒开系统调用的三层皮(下)

    韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.给MenuO ...

  6. Linux内核分析第六周学习总结:进程的描述和进程的创建

    韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.进程的描述 ...

  7. Linux内核分析——期末总结

    Linux内核学习总结 首先非常感谢网易云课堂这个平台,让我能够在课下学习,课上加强,体会翻转课堂的乐趣.孟宁老师的课程循序渐进,虽然偶尔我学习地不是很透彻,但能够在后续的课程中进一步巩固学习,更加深 ...

  8. linux内核分析 课程总结

    Linux内核分析 链接汇总 Linux内核分析第一周学习总结--计算机是如何工作的 Linux内核分析第二周学习总结--操作系统是如何工作的 Linux内核分析第三周学习总结--构造一个简单的Lin ...

  9. 《Linux内核分析》期终总结&《Linux及安全》期中总结

    <Linux内核分析>期终总结&<Linux及安全>期中总结 [李行之 原创作品 转载请注明出处 <Linux内核分析>MOOC课程http://mooc. ...

随机推荐

  1. 如何开启win10的上帝模式

    用了这么久的电脑,小编才知道还有“上帝模式”这一说,原谅小编的孤陋寡闻.翻阅资料才知道,上帝模式简单来说就是一个全能的控制面板,如控制面板的功能.界面个性化.辅助功能选项等方方面面的控制设置,几乎包含 ...

  2. January 29th, 2018 Week 05th Monday

    Losing all hope was freedom. 彻底绝望就是真正的自由. Losing all the hopes, and we are free to challenge everyth ...

  3. January 27th, 2018 Week 04th Saturday

    How long is forever? Sometimes, just one second. 永远有多久?有时候只是一秒. Just one second can make your life t ...

  4. SQL update select结合语句详解及应用

    QL update select语句 最常用的update语法是: 1 2 UPDATE TABLE_NAME SET column_name1 = VALUE WHRER column_name2 ...

  5. php 对象教程

    [PHP面向对象(OOP)编程入门教程]6.如何去使用对象中的成员 作者:qianyunlai.com  发布于:2012-05-19 15:02  分类:PHP基础  浏览(280) 上面看到PHP ...

  6. 1 C++ 线程

    #include "iostream" //#include "thread" //头文件一般不加入,复制到别的文件,导致命名冲突 //总增加 //using ...

  7. mybatis逆向工程之动态web项目

    有了逆向工程,单表的增删改查以及相关的实体类,还有属性注释都不用自己写了,都可以自动化生成,只需如下三步即可 逆向工程的优点是:自动化生成实体类和对应的增删改查,效率相对于之前个人开发时一个个写增删改 ...

  8. 查看和指定SpringBoot内嵌Tomcat的版本

    查看当前使用的Tomcat版本号 Maven Repository中查看 比如我们需要查Spring Boot 2.1.4-RELEASE的内嵌Tomcat版本, 可以打开链接: https://mv ...

  9. android.view.WindowManager$BadTokenException: Unable to add window

    这是在加载dialog时出现的一个异常.转载地址:http://hi.baidu.com/fbdfp/item/7dea2d0ade9121813d42e23d 扔了好久的android又开始断断续续 ...

  10. Skyline中的GDAL

    安装Skyline的TerraExplorer Pro软件后,我们很容易在其安装目录中找到这样一些文件: gdal.dll.gdal_csharp.dll.ogr_csharp.dll.osr_csh ...