目标文件格式分析____ELF

来源:互联网 发布:手机淘宝购物流程视频 编辑:程序博客网 时间:2024/04/30 06:24
这里不使用工具详细逐步分析验证ELF内容 可参见书目《程序员的自我修养---链接装载与库》本文主要也是阅读该书第三章的读书笔记 供整理思路 理清脉络之用

     ELF主要内容:
     1.文件头:
          里面主要包含包含了:
          a.平台版本信息:里面有个比较有意思的魔数:
                最开始的4个字节是所有ELF文件都必须相同的标识码,分别为0x7F、0x45、0x4c、0x46,第一个字节对应ASCII字符里面的DEL 控制符,后面3个字节刚好是ELF这3个字母的ASCII码。这4个字节又被称为ELF文件的魔数,几乎所有的可执行文件格式的最开始的几个字节都是魔数。比如a.out格式最开始两个字节为 0x01、0x07;PE/COFF文件最开始两个个字节为0x4d、0x5a,即ASCII字符MZ。这种魔数用来确认文件的类型,操作系统在加载可执行文件的时候会确认魔数是否正确,如果不正确会拒绝加载。

  各种魔数的由来

  a.out格式的魔数为0x01、0x07,为什么会规定这个魔数呢?

  UNIX早年是在PDP小型机上诞生的,当时的系统在加载一个可执行文件后直接从文件的第一个字节开始执行,人们一般在文件的最开始放置一条跳转(jump)指令,这条指令负责跳过接下来的7个机器字的文件头到可执行文件的真正入口。而0x01 0x07这两个字节刚好是当时PDP-11的机器的跳转7个机器字的指令。为了跟以前的系统保持兼容性,这条跳转指令被当作魔数一直被保留到了几十年后的今天。
         b.文件类型: 可重定位文件(ET_REL),可执行文件(ET_EXEC),共享目标文件(ET_DYN),核心转储文件
         c.该ELF程序入口虚拟地址 对于可重定位文件 为0
         d.段表在ELF文件中的偏移量
         e.ELF文件头本身的大小
         f.段表中的条目大小
         g.段表中的条目数
         h.段表字符串所在的段在段表中的下标
     通过文件头,我们能得到 两个比较重要的段的一些信息:段表和段表字符串表
          段表字符串表主要存放各个段的名字
     2.段表:
          段表是一个结构体数组 每一个结构体条目用于描述一个段的信息(段表本身的主要信息已由文件头给出)。
          这就是段表中用于描述其他所有段信息的结构体条目
           依次向下,包含的主要信息:
           段名(sh_name): 这里的段名给出的是段名在段名字符串表中偏移量,段表字符串表在本段表中的下标已经在文件头中给出,因此我们可以得到段表字符串表从而得到所有段的名字
          段的类型(sh_type):
               


        段的标志(sh_flags)
  
      段的虚拟地址(sh_addr): 如果该段可以被加载 那么该值为加载后的虚拟地址 否则为0
      段偏移(sh_offset): 如果该段存在于文件中,那么sh_offset指出该段在整个ELF文件中的偏移 否则无意义(比如对于.bss来说)
      段大小(sh_size): 段的长度
      段的链接信息(sh_link和sh_info):如果该段是与链接相关的(包括静态和动态)
 
     段地址对齐(sh_addralign) 由于对齐方式均以2的幂为基准,因此该字段表示2的幂数 当sh_addralign为1或0时 对齐无要求
     段条目大小(sh_entsize) 对于一些固定大小结构体组成的数组表示的段(比如符号表),该段指示出各个结构体条目大小        
     3.字符串表(strtab)和段表字符串表(shstrtab) 保存整个文件的字符串信息。字符串表主要保存文件中的变量名等 段表字符串表用以保存段中用到的字符串(比如段名)。这样才使得其他很多段的字符串引用是一个定长的偏移 便于得到一个固定大小的条目
     4.符号表(.symtab):主要保存函数名和变量名的一些详细信息(注意,不只是符号名本身,而是包含其大小,所在段等信息)
     

     
st_info低四位表示符号类型 高28位表示符号绑定信息  详细见下表

符号所在段(st_shndx)
 



     5.数据段(.data和.bss):
          .data只保存具体数据值 .bss保存未初始化的全局变量和局部静态变量的值 .bss
               注:假如某全局变量初始化为0 尽管其已经初始化 但是有可能编译器优化后仍将其放在.bss里 还有就是全局未初始化变量(静态变量)可能并不会占用bss空间,
     6.代码段(.text) 存放反汇编代码


主要的段就是这些。重要的有几点
     1.ELF将所有不定长的字符串(段名,变量名,函数名等)都放在字符串表,段表字符串表中
     2.通过文件头段表信息和段表字符串下标  可以解析整个ELF文件
原创粉丝点击