记:ELF文件解析初定义——Section段相关讲解

16 篇文章 0 订阅
11 篇文章 1 订阅

0x00 概论

因为TI的DSP输出文件与传统的ELF文件不符,所以本人就顺道研究了一下现在的ELF的文件格式。 会将其陆续完成在文章中。
承接上文,上文书说到,解析文件头格式,数据段的分配定义,与数据段的约束。

阅读本文之前,您需要掌握的技能有:

技能名称技能熟练度技能教程链接
C语言了解暂无

0x10 Section Table介绍与说明

接下来将会讲述Section数据段的区域相关的定义。

数据段表头的定义在上文已经讲过,而数据段表的指针也在上文的文件头中进行了说明。有了数据段表头指针,就可以得到数据段的起始位置的定义。定义如下:

数据定义数据格式个数说明
section header nameElf32_Word1数据段名称
section header typeElf32_Word1数据段的类型
section header flagsElf32_Word1此数据段的标志位
section header addressElf32_Address1数据段的关于代码执行的地址
section header offsetElf32_Offset1数据段在文件中的偏移量
section header sizeElf32_Word1数据段的长度
section header linkElf32_Word1索引位数量
section header infoElf32_Word1其他类的信息
section header address alignElf32_Word1数据排列定义
section header entry sizeElf32_Word1数据段的入口长度,用于索引(如果有的话)
BFD Compatible下文强调1用于兼容BFD文件的兼容定义,是一个定义完善的数据结构
section header content AddressElf32_Address(容器为Elf32_Char)1数据的真实数据指针

这就是一条完整的Section 数据条。有了这个,再加上上文的数据段表头的入口地址,就可以顺利的从文章起始找到文件的数据段的结构,从而抓取整个数据段的列表的所有的数据。而只要有软件遍历了所有的数据段数据结构,解析了所有的数据段参数,就可以生成下图这样的数据表了。

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 701856 000000 00      0   0  4
  [ 1] .shstrtab         STRTAB          00000000 701856 00013c 00      0   0  4
  [ 2] .strtab           STRTAB          00000000 701992 01509b 00      0   0  4
  [ 3] .symtab           SYMTAB          00000000 716a2f 02f790 10      2 10471  4
  [ 4] GreenDreamer      PROGBITS        05201314 052013 521314 01   A  0   0  1
  [ 5] GreenDreamer      PROGBITS        05201314 052013 521314 01   A  0   0  1
  [ 6] GreenDreamer      PROGBITS        05201314 052013 521314 01   A  0   0  4
  [ 7] GreenDreamer      PROGBITS        05201314 052013 521314 01  AX  0   0  4
  [ 8] GreenDreamer      PROGBITS        05201314 052013 521314 01   A  0   0  1
  [ 9] GreenDreamer      PROGBITS        05201314 052013 521314 01   A  0   0  1
  [10] GreenDreamer      PROGBITS        05201314 052013 521314 01  AX  0   0  1
  [11] GreenDreamer      PROGBITS        05201314 052013 521314 01   A  0   0  1
  [12] GreenDreamer      PROGBITS        05201314 052013 521314 01   A  0   0  1
  [13] GreenDreamer      NOBITS          20000000 052013 01c4a8 01  WA  0   0  8
  [14] .debug_abbrev     PROGBITS        00000000 0c9d4c 0170ec 01      0   0  0
  [15] .debug_frame      PROGBITS        00000000 0e0e38 024b30 01      0   0  0
  [16] .debug_info       PROGBITS        00000000 105968 052013 01      0   0  0
  [17] .debug_line       PROGBITS        00000000 052013 12a014 01      0   0  0
  [18] .debug_loc        PROGBITS        00000000 491c24 052013 01      0   0  0
  [19] .debug_macinfo    PROGBITS        00000000 4d1550 01d7b5 01      0   0  0
  [20] .debug_pubnames   PROGBITS        00000000 052013 01744c 01      0   0  0
  [21] .iar.debug_frame  PROGBITS        00000000 506154 00919e 01      0   0  0
  [22] .iar.debug_line   PROGBITS        00000000 052013 052013 01      0   0  0
  [23] .comment          PROGBITS        00000000 56a588 1696c0 01      0   0  0
  [24] .iar.rtmodel      PROGBITS        00000000 052013 000021 01      0   0  0
  [25] .ARM.attributes   ARM_ATTRIBUTES  00000000 052013 00002a 01      0   0  0
  [26] GreenDreamer      PROGBITS        080101d0 052013 052013 01  AX  0   0  0
  [27] GreenDreamer      PROGBITS        08062268 052013 01dd8c 01  AX  0   0  0
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  y (purecode), p (processor specific)

但是这里着重的说明一下BFD Compatible ,这个是一个兼容了Binary File Descriptor library的文件数据结构的指针,主要作用就是将content指针的数据转换扩充,成为BFD可以解析的数据段,而且此数据结构为双向链表的结构,所以就可以在仅读取一个Section 数据条的情况下,遍历出所有的数据条节点。

上图的节点中,有一个比较重要的是flag标志,这个标志所代表的含义详见如下,这些flag主要是提供给链接器处理的,所以也就还好,但是还是需要列出来。以便可以显示数据段,这些段的定义也都很简单,诸如数据段、组别、执行段、可变长字段等。暂时不冲突的数据仅有31个字节。其中还有两个字节是重复的。

section_flag定义

定义数据长度解释
name字符串段名字
id整数段标号
Index整数段位置
next指针下一个段。都是本身的指针
prev指针上一个段,都是本身的指针
vma2*Elf32_Wordvma段与flag
lmaElf32_Wordlma段
sizeElf32_Word一个在bss区域的长度
rawsizeElf32_Word真实区域的长度
compressed_sizeElf32_Word压缩后的真实数据长度
relaxrelax_table单个区间的数据
relax_countElf32_Word区间的个数
output_offsetElf32_Word数据段对于文件的偏移
output_section指针指向的帧数输出段
alignElf32_Word定义的文件排列顺序
relocationElf32_Word指针记录关于这个section的相关参数
filepointfile指针三个指针,分别指向section、relocation、line
userdataElf32_Word指针数据真实的指针
symbolElf32_Word指针标签的真实指针

上面就是很多的重要参数了,其他的参数还有很多,但是对于数据的处理都不是太重要,比如line的信息以及line的格式等。这里就不做过多介绍了。

当然这个是程序内部对于section的处理相关的指针,而输出端的定义则与其相去甚远,相关的定义就在下面。

定义数据长度
NameElf32_Word
TypeElf32_Word
FlagsElf32_Word
AddressElf32_Address
OffsetElf32_Offset
SizeElf32_Word
LinkElf32_Word
InfoElf32_Word
Address alignElf32_Word
Entry sizeElf32_Word

上述区间可以看出,对应的就是输出的表格的第一行的参数。所以,Section段的主要工作只有两步:将一个由双向链表为基础构成的大型数据区块沿着双向链表逐个解析,并将其转换为上面的一一对应的结构体格式。随后将其整理成表打印出来。

处理流程

由此可以看出,这里的数据关键是数据区的解析,而数据区的解析主要是靠前文的文件头中的数据区的文件指针。

0x20 Section 定义

Section数据区虽然有着统一的数据结构,但是每个数据区都有着不同的作用。type就规定了每个区的不同的作用,具体的作用如下:

定义数据解释
NULL0基础
Program Bits1程序段
Symbol Table2符号段
String Table3字符段
Relocation addends4适配转移
Symbol Hash5符号hash表
Dynamic Link6动态链接
Relocation No Addends9适配未转移
Semantics10未定义的语义区间(0xFF类)
Dynamic Table11动态表格
Group17组合
Version define0x6ffffff5遵循GNU协议的架构数据
Version define0x6ffffffd数据版本定义
Version need0x6ffffffe数据版本需求
Symbol versions0x6fffffff符号版本
Processor-specific Low0x70000000特定的处理器代码-低段
Processor-specific High0x7FFFFFFF特定的处理器代码-高段
Application-specific Low0x80000000应用处理器代码-低段
Application-specific High0x8FFFFFFF应用处理器代码-高段
defined 1999年10月4号(SHT_HIUSER)Application-specific High0xFFFFFFFF最高的位置,定义的应该是最高位

这里先说明一下,这个最后的两行数据都是一样的,但是在1999年以后似乎就被废除了,虽然本人暂时没有找到可以支撑我这种说法的事实论据,但是从这个宏的含义还是可以看出一二的。

0x30 Section Flags

表中还有一段比较重要的数据就是每段数据的Flags,这段在最后的介绍中有数据解释:

Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  y (purecode), p (processor specific)

其中大多数的定义如下:

定义数据解释输出映射
SHF_WRITE0x00000001可写W (write)
SHF_ALLOC0x00000002缓存A (alloc)
SHF_EXECINSTR0x00000004可执行X (execute)
SHF_MERGE0x00000010合并区M (merge)
SHF_STRINGS0x00000020字符区S (strings)
SHF_INFO_LINK0x00000040信息区I (info)
SHF_LINK_ORDER0x00000080链接去声明L (link order)
SHF_OS_NONCONFORMING0x00000100当前OS未定义参数O (extra OS processing required)
SHF_GROUP0x00000200数据组G (group)
SHF_TLS0x00000400线程本地存储部分T (TLS)
SHF_MASKOS0x0FF00000当前OS定义参数o (OS specific)
SHF_EXCLUDE0x80000000运行时包含库E (exclude)
SHF_MASKPROC0xF0000000执行标准参数p (processor specific)
SHF_X86_64_LARGE && (EM86_64|EM_L10M|EM_K10M)0x10000000特定64位专用参数l(未定义但存在的参数)
SHF_UNKNOWN-未定义参数x (unknown)

当然,这里有几项数据我并没有在代码和文档中寻找到原型,他们是y (purecode)、C (compressed),这两项在我仔细翻找下依然没有找到,可能没有在主流的代码位置上存在。

0x40 结论

以上就是Section Table的基本参数介绍,当然,这里讲述的主要是数据结构定义,而没有具体的参数进行说明。有些纸上点兵的嫌疑,但是也要先说明具体情况才可以为接下来的实现打好基础。

后面还有关于Symbol、string、debug等区位的解析与修改。详情请见随后的文章。

更多

本文首发自 记:ELF文件解析初定义——Section段相关讲解,更多文章可进入我的博客详查。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GreenDreamer

如果帮到了你,还望请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值