%title缩略图

ELF节头

我们一路从ELF的文件头到ELF的程序头再到段(segment),现在进入ELF的节头部分,本文将要对ELF文件的节头进行拆解分析。

注意:ELF的节头不是节,节头是对节的信息的描述,例如节在文件中的偏移量,大小等等,节头类似一张表,里面有很多条目,每个条目就是1条描述信息,靠这些描述信息可以找到每个节(section)的位置,大小等等信息。

节头是对程序头的补充。如果二进制文件中缺少节头并不代表节即不存在。只是没有办法通过节头来引用,也没有办法通过gdb、objdump和objcopy这类工具进行调试和分析。

节头对于程序的执行来说不是必须的,没有节头表,程序也可以执行。每个ELF文件都有节,但是不一定有节头,因为可以人为删除节头。默认是有节头的。

节头在文件的什么地方呢?下面进行拆解

通过ELF文件头这篇文章我们拆分时发现节头的偏移量在文件头里有记录,对应的字段是e_shoff,示例文件的第41个字节开始至第48个字节就是e_shoff字段的内容了,内容就是节头的偏移量。

%title插图%num

内容是0x3960,十进制是14688,说明节头在文件中的偏移量是14688

那么节头大小是多少个字节呢?同样在文件头里有对应的字段记录着,e_shentsize*e_shnum的结果就是节头的大小。

示例文件e_shentsize是0x40,十进制是64,e_shnum是0x1e,十进制是30,64*30=1920,说明节头的大小是1920个字节

现在我们知道了节头的文件偏移量是14688,大小是1920,那么接下来我们查看节头里的内容

%title插图%num

内容篇幅有点儿多,以致于显示不清,不过没关系,显示的清也不知道代表什么

所以我们接下来参考Linux源码和elf手册,看看节头中每个节的构成。

%title插图%num

注:图中的占多少个字节是我自己标注的,源码中稍加分析即可得出大小。或者参考elf手册。

sh_name。该字段表示的是节的名称,内容只是一个索引值,根据该索引值在节头字符串表中可以找到真正的节名称。

sh_type。节的类型。

sh_flags。节的属性。

sh_addr。该字段表示的是节在进程内存映像中的虚拟地址,如果该节会加载到内存映像中的话。反之该字段的内容会是0。

sh_offset。该字段表示的是节在文件映像中的偏移量。如果节类型是SHT_NOBITS,则该节不占空间,此时sh_offset保存的只是一个概念位置。

sh_size。该字段顾名思义表示的是节的大小。要注意的是如果节类型是SHT_NOBITS时sh_size也有可能会是非0的情况,但实际上不占空间。

sh_link。从翻译上来看是特定节的索引,暂不知道具体用途,后续拆分时再关注。

sh_info。从翻译来看是表示额外的节信息,特定于节类型。

sh_addralign。该字段表示节在文件映像和内存映像中的对齐字节数。如果值是0或1表示没有对齐约束。

sh_entsize。该字段针对的是一些具有固定大小条目的节(或说是表,例如符号表),针对这种节,该字段表示的是每个条目的大小。否则该字段是0。

节头表的每个条目的构成已经过了一遍了,已知我的示例文件有30个节,每个节描述条目的大小是64个字节,节头表的偏移量是14688,那么我们挨个看看具体都是什么节。

第1个节(section)。

从节头表的偏移地址14688开始取64个字节就是第1个节的描述信息

%title插图%num

sh_name。sh_name的大小是4个字节,这里是00000000,值是0,表示字符串表索引为0的是该节的名称

sh_type。sh_type的大小也是4个字节。这里也是0

%title插图%num

类型是SHT_NULL,说明该节是SHT_NULL类型,表示的是一个空节,即无效的节,节描述信息里的其它字段都没有定义,都是0。

直接跳过,看看第2个节

第2个节(section)

14688+64=14752,从14752开始取64个字节就是第2个节的描述信息

%title插图%num

sh_name。占4个字节,这里是0x1b,十进制是27,说明在节头字符串表27个字节开始是该节的名称值

sh_type。占4个字节,这里是0x1

%title插图%num

对应的是SHT_PROGBITS,说明该节的类型是SHT_PROGBITS,说明是保存程序代码或数据的节。

sh_flags。占8个字节,这里是0x2

%title插图%num

2表示的属性是SHF_ALLOC,说明该节在程序执行期间会占用内存。

sh_addr。占8个字节,这里是0x2a8,说明该节在进程内存映像中的地址0x2a8

sh_offset。占8个字节,这里是0x2a8,十进制是680,说明该节在文件映像中的偏移量680。

sh_size。占8个字节,这里是0x1c,十进制是28,说明该节的大小是28个字节。

sh_link。占4个字节,这里是0,应该是没有关联其它节所以是0,后续进行验证。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x1,说明该节在文件映像和内存映像中不要求对齐。

sh_entsize。占8个字节,这里是0,说明该节没有固定大小的条目。如果有就不会是0,而是具体的值,该值就是每个条目的大小。例如符号表。

第3个节(section)

14752+64=14816,从14816处取64个字节就是第3个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x23,说明在节头字符串表35个字节开始是该节的名称值

sh_type。占4个字节,这里是0x7

%title插图%num

对应的节类型是SHT_NOTE,说明该节类型是SHT_NOTE类型,供应商或系统工程师可能需要使用特殊信息标记目标文件,以便其他程序可根据此信息检查一致性或兼容性。

sh_flags。占8个字节,这里是0x2,2表示的属性是SHF_ALLOC,说明该节在程序执行期间会占用内存。

sh_addr。占8个字节,这里是0x2c4,说明该节在进程内存映像中的地址0x2c4

sh_offset。占8个字节,这里是0x2c4,十进制是708,说明该节在文件映像中的偏移量708。

sh_size。占8个字节,这里是0x24,十进制是36,说明该节的大小是36个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x4,说明该节在文件映像和内存映像中对齐字节数是4字节。

sh_entsize。占8个字节,这里是0,说明该节没有固定大小的条目。如果有就不会是0,而是具体的值,该值就是每个条目的大小。例如符号表。

第4个节(section)

14816+64=14880,从14880处取64个字节就是第4个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x36,说明在节头字符串表54个字节开始是该节的名称值

sh_type。占4个字节,这里是0x7,对应的节类型是SHT_NOTE,说明该节类型是SHT_NOTE类型,elf手册对该类型解释为表示注释,目前尚不清楚作用在哪儿。

sh_flags。占8个字节,这里是0x2,2表示的属性是SHF_ALLOC,说明该节在程序执行期间会占用内存。

sh_addr。占8个字节,这里是0x2e8,说明该节在进程内存映像中的地址0x2e8

sh_offset。占8个字节,这里是0x2e8,十进制是744,说明该节在文件映像中的偏移量744。

sh_size。占8个字节,这里是0x20,十进制是32,说明该节的大小是32个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x4,说明该节在文件映像和内存映像中对齐字节数是4字节。

sh_entsize。占8个字节,这里是0,说明该节没有固定大小的条目。如果有就不会是0,而是具体的值,该值就是每个条目的大小。例如符号表。

第5个节(section)

14880+64=14944,从14944处取64个字节就是第5个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x44,说明在节头字符串表68个字节开始是该节的名称值

sh_type。占4个字节,这里是0x6ffffff6

%title插图%num

对应的节类型是SHT_GNU_HASH,说明该节类型是SHT_GNU_HASH类型,看到Oracle的solaris系统的文档解释说是GNU哈希节是GUN链接器开发人员新增的一个节,其性能比原始SYSV哈希更好。

sh_flags。占8个字节,这里是0x2,2表示的属性是SHF_ALLOC,说明该节在程序执行期间会占用内存。

sh_addr。占8个字节,这里是0x308,说明该节在进程内存映像中的地址0x308

sh_offset。占8个字节,这里是0x308,十进制是776,说明该节在文件映像中的偏移量776。

sh_size。占8个字节,这里是0x24,十进制是36,说明该节的大小是36个字节。

sh_link。占4个字节,这里是0x5,说明该节会关联到其它节,索引值是5

sh_info。占4个字节,这里是0x0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x8,说明该节在文件映像和内存映像中对齐字节数是8字节。

sh_entsize。占8个字节,这里是0,说明该节没有固定大小的条目。如果有就不会是0,而是具体的值,该值就是每个条目的大小。例如符号表。

第6个节(section)

14944+64=15008,从15008处取64个字节就是第6个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x4e,说明在节头字符串表78个字节开始是该节的名称值

sh_type。占4个字节,这里是0xb,即11

%title插图%num

类型是SHT_DYNSYM,是动态链接符号表。该节包含最少的动态链接符号集。 一个目标文件也可以包含一个SHT_SYMTAB节。

sh_flags。占8个字节,这里是0x2,2表示的属性是SHF_ALLOC,说明该节在程序执行期间会占用内存。

sh_addr。占8个字节,这里是0x330,说明该节在进程内存映像中的地址0x330

sh_offset。占8个字节,这里是0x330,十进制是816,说明该节在文件映像中的偏移量816。

sh_size。占8个字节,这里是0xa8,十进制是168,说明该节的大小是168个字节。

sh_link。占4个字节,这里是0x6,说明该节会关联到其它节,索引值是6。当前节类型是SHT_DYNSYM,故表示的是全局符号索引值是6。

sh_info。占4个字节,这里是0x1,当前节类型是SHT_DYNSYM,故表示该节的额外描述信息在字符节的索引值为1的地方。

sh_addralign。占8个字节,这里是0x8,说明该节在文件映像和内存映像中对齐字节数是8字节。

sh_entsize。占8个字节,这里是0x18,十进制是24,说明该节有固定大小的条目。每个条目的大小是24个字节。

第7个节(section)

15008+64=15072,从15072处取64个字节就是第7个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x56,说明在节头字符串表86个字节开始是该节的名称值

sh_type。占4个字节,这里是0x3

%title插图%num

知道了,表明该节类型是SHT_STRTAB,即字符串表,此时字符串表露出水面。一个目标文件可能会有多个字符串表节

sh_flags。站8个字节,这里是0x2,2表示的属性是SHF_ALLOC,说明该节在程序执行期间会占用内存。

sh_addr。占8个字节,这里是0x3d8,说明该节在进程内存映像中的地址0x3d8

sh_offset。占8个字节,这里是0x3d8,十进制是984,说明该节在文件映像中的偏移量984。

sh_size。占8个字节,这里是0x82,十进制是130,说明该节的大小是130个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x1,说明该节在文件映像和内存映像中无需对齐。

sh_entsize。占8个字节,这里是0,说明该节没有固定大小的条目。如果有就不会是0,而是具体的值,该值就是每个条目的大小。例如符号表。

第8个节(section)

15072+64=15136,从15136处取64个字节就是第8个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x5e,说明在节头字符串表94个字节开始是该节的名称值

sh_type。占4个字节,这里是0x6fffffff

%title插图%num

该节类型是SHT_GUN_versym。符号版本表,该节中包含一个版本信息索引表,每个表项的长度为2个字节,表项的数量与动态符号表.dynsym中所有符号的数目相同,并且一一对应。

sh_flags。站8个字节,这里是0x2,2表示的属性是SHF_ALLOC,说明该节在程序执行期间会占用内存。

sh_addr。占8个字节,这里是0x45a,说明该节在进程内存映像中的地址0x45a

sh_offset。占8个字节,这里是0x45a,十进制是1114,说明该节在文件映像中的偏移量1114。

sh_size。占8个字节,这里是0xe,十进制是14,说明该节的大小是14个字节。

sh_link。占4个字节,这里是5。说明该节会关联到其它节,索引值是5

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x2,说明该节在文件映像和内存映像中2个字节一对齐。

sh_entsize。占8个字节,这里是0x2,十进制是2,说明该节有固定大小的条目。每个条目的大小是2个字节。

第9个节(section)

15136+64=15200,从15200处取64个字节就是第9个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x6b,说明在节头字符串表107个字节开始是该节的名称值

sh_type。占4个字节,这里是0x6ffffffe

%title插图%num

该节类型是SHT_GNU_verneed,符号版本需求节,该节存在于可执行文件和动态库(动态库也会引用其他动态库中的符号)中,表示所符号版本所要求的元素。其中项的数目存储在.dynamic section中DT_VERNEEDNUM类型的表项中

sh_flags。站8个字节,这里是0x2,2表示的属性是SHF_ALLOC,说明该节在程序执行期间会占用内存。

sh_addr。占8个字节,这里是0x468,说明该节在进程内存映像中的地址0x468

sh_offset。占8个字节,这里是0x468,十进制是1128,说明该节在文件映像中的偏移量1128。

sh_size。占8个字节,这里是0x20,十进制是32,说明该节的大小是32个字节。

sh_link。占4个字节,这里是6。说明该节会关联到其它节,其它节在动态字符串节中的索引是6。

sh_info。占4个字节,这里是1,说明该节的表项数量是1。

sh_addralign。占8个字节,这里是0x8,说明该节在文件映像和内存映像中8个字节一对齐。

sh_entsize。占8个字节,这里是0,说明该节没有固定大小的条目。如果有就不会是0,而是具体的值,该值就是每个条目的大小。例如符号表。

第10个节(section)

15200+64=15264,从15264处取64个字节就是第10个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x7a,说明在节头字符串表122个字节开始是该节的名称值

sh_type。占4个字节,这里是0x4,

%title插图%num

类型是SHT_RELA,表示本节包含带有显式加数的重定位条目, 一个目标文件可能具有多个重定位节。

sh_flags。站8个字节,这里是0x2,2表示的属性是SHF_ALLOC,说明该节在程序执行期间会占用内存。

sh_addr。占8个字节,这里是0x488,说明该节在进程内存映像中的地址0x488

sh_offset。占8个字节,这里是0x488,十进制是1160,说明该节在文件映像中的偏移量1160。

sh_size。占8个字节,这里是0xc,十进制是12,说明该节的大小是12个字节。

sh_link。占4个字节,这里是5。说明该节会关联到其它节,其它节在动态符号节中的索引是5。

sh_info。占4个字节,这里是0,说明没有额外的描述信息。

sh_addralign。占8个字节,这里是0x8,说明该节在文件映像和内存映像中8个字节一对齐。

sh_entsize。占8个字节,这里是0x18,十进制是24,说明该节有固定大小的条目。每个条目的大小是24个字节。

第11个节(section)

15264+64=15328,从15328处取64个字节就是第11个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x84,说明在节头字符串表132个字节开始是该节的名称值

sh_type。占4个字节,这里是0x4,类型是SHT_RELA,表示本节包含带有显式加数的重定位条目, 一个目标文件可能具有多个重定位节。这是第2个重定位节。

sh_flags。站8个字节,这里是0x42,目前没有找到具体的解释。

sh_addr。占8个字节,这里是0x548,说明该节在进程内存映像中的地址0x548

sh_offset。占8个字节,这里是0x548,十进制是1352,说明该节在文件映像中的偏移量1352。

sh_size。占8个字节,这里是0x18,十进制是24,说明该节的大小是24个字节。

sh_link。占4个字节,这里是5。说明该节会关联到其它节,其它节在动态符号节中的索引是5。

sh_info。占4个字节,这里是0x17,说明被重定位节的索引值是23。

sh_addralign。占8个字节,这里是0x8,说明该节在文件映像和内存映像中8个字节一对齐。

sh_entsize。占8个字节,这里是0x18,十进制是24,说明该节有固定大小的条目。每个条目的大小是24个字节。

第12个节(section)

15328+64=15392,从15392处取64个字节就是第12个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x8e,说明在节头字符串表142个字节开始是该节的名称值

sh_type。占4个字节,这里是0x1,类型是SHT_RELA,表示本节包含带有显式加数的重定位条目, 一个目标文件可能具有多个重定位节。这是第2个重定位节。

%title插图%num

类型是SHT_PROGBITS,表示的是程序代码或者数据的节

sh_flags。站8个字节,这里是0x6,属性未知

sh_addr。占8个字节,这里是0x1000,说明该节在进程内存映像中的地址0x1000

sh_offset。占8个字节,这里是0x1000,十进制是4096,说明该节在文件映像中的偏移量4096。

sh_size。占8个字节,这里是0x17,十进制是23,说明该节的大小是23个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x4,说明该节在文件映像和内存映像中4个字节一对齐。

sh_entsize。占8个字节,这里是0,说明该节没有固定大小的条目。如果有就不会是0,而是具体的值,该值就是每个条目的大小。例如符号表。

第13个节(section)

15392+64=15456,从15456处取64个字节就是第13个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x89,说明在节头字符串表137个字节开始是该节的名称值

sh_type。占4个字节,这里是0x1,类型是SHT_RELA,表示本节包含带有显式加数的重定位条目, 一个目标文件可能具有多个重定位节。这是第3个重定位节。

sh_flags。站8个字节,这里是0x6,属性未知

sh_addr。占8个字节,这里是0x1020,说明该节在进程内存映像中的地址0x1020

sh_offset。占8个字节,这里是0x1020,十进制是4128,说明该节在文件映像中的偏移量4128。

sh_size。占8个字节,这里是0x20,十进制是32,说明该节的大小是32个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x10,十进制16,说明该节在文件映像和内存映像中16个字节一对齐。

sh_entsize。占8个字节,这里是0x10,十进制是16,说明该节有固定大小的条目。每个条目的大小是16个字节。

第14个节(section)

15456+64=15520,从15520处取64个字节就是第14个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x94,说明在节头字符串表148个字节开始是该节的名称值

sh_type。占4个字节,这里是0x1,类型是SHT_RELA,表示本节包含带有显式加数的重定位条目, 一个目标文件可能具有多个重定位节。这是第4个重定位节。

sh_flags。站8个字节,这里是0x6,属性未知

sh_addr。占8个字节,这里是0x1040,说明该节在进程内存映像中的地址0x1040

sh_offset。占8个字节,这里是0x1040,十进制是4160,说明该节在文件映像中的偏移量4160。

sh_size。占8个字节,这里是0x8,十进制是8,说明该节的大小是8个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x8,十进制8,说明该节在文件映像和内存映像中8个字节一对齐。

sh_entsize。占8个字节,这里是0x8,十进制是8,说明该节有固定大小的条目。每个条目的大小是8个字节。

第15个节(section)

15520+64=15584,从15584处取64个字节就是第15个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x9d,说明在节头字符串表157个字节开始是该节的名称值

sh_type。占4个字节,这里是0x1,类型是SHT_RELA,表示本节包含带有显式加数的重定位条目, 一个目标文件可能具有多个重定位节。这是第5个重定位节。

sh_flags。站8个字节,这里是0x6,属性未知

sh_addr。占8个字节,这里是0x1050,说明该节在进程内存映像中的地址0x1050

sh_offset。占8个字节,这里是0x1050,十进制是4176,说明该节在文件映像中的偏移量4176。

sh_size。占8个字节,这里是0x161,十进制是353,说明该节的大小是353个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x10,十进制16,说明该节在文件映像和内存映像中16个字节一对齐。

sh_entsize。占8个字节,这里是0,说明该节没有固定大小的条目。如果有就不会是0,而是具体的值,该值就是每个条目的大小。例如符号表。

第16个节(section)

15584+64=15648,从15648处取64个字节就是第16个节描述条目

%title插图%num

sh_name。占4个字节,这里是0xa3,说明在节头字符串表163个字节开始是该节的名称值

sh_type。占4个字节,这里是0x1,类型是SHT_RELA,表示本节包含带有显式加数的重定位条目, 一个目标文件可能具有多个重定位节。这是第6个重定位节。

sh_flags。站8个字节,这里是0x6,属性未知

sh_addr。占8个字节,这里是0x11b4,说明该节在进程内存映像中的地址0x11b4

sh_offset。占8个字节,这里是0x11b4,十进制是4532,说明该节在文件映像中的偏移量4532。

sh_size。占8个字节,这里是0x9,十进制是9,说明该节的大小是9个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x4,十进制4,说明该节在文件映像和内存映像中4个字节一对齐。

sh_entsize。占8个字节,这里是0,说明该节没有固定大小的条目。如果有就不会是0,而是具体的值,该值就是每个条目的大小。例如符号表。

第17个节(section)

15648+64=15712,从15712处取64个字节就是第17个节描述条目

%title插图%num

sh_name。占4个字节,这里是0xa9,说明在节头字符串表169个字节开始是该节的名称值

sh_type。占4个字节,这里是0x1,类型是SHT_RELA,表示本节包含带有显式加数的重定位条目, 一个目标文件可能具有多个重定位节。这是第7个重定位节。

sh_flags。站8个字节,这里是0x2,2表示的属性是SHF_ALLOC,说明该节在程序执行期间会占用内存。

sh_addr。占8个字节,这里是0x2000,说明该节在进程内存映像中的地址0x2000

sh_offset。占8个字节,这里是0x2000,十进制是8192,说明该节在文件映像中的偏移量8192。

sh_size。占8个字节,这里是0x11,十进制是17,说明该节的大小是17个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x4,十进制4,说明该节在文件映像和内存映像中4个字节一对齐。

sh_entsize。占8个字节,这里是0,说明该节没有固定大小的条目。如果有就不会是0,而是具体的值,该值就是每个条目的大小。例如符号表。

第18个节(section)

15712+64=15776,从15776处取64个字节就是第18个节描述条目

%title插图%num

sh_name。占4个字节,这里是0xb1,说明在节头字符串表177个字节开始是该节的名称值

sh_type。占4个字节,这里是0x1,类型是SHT_RELA,表示本节包含带有显式加数的重定位条目, 一个目标文件可能具有多个重定位节。这是第8个重定位节。

sh_flags。站8个字节,这里是0x2,2表示的属性是SHF_ALLOC,说明该节在程序执行期间会占用内存。

sh_addr。占8个字节,这里是0x2014,说明该节在进程内存映像中的地址0x2014

sh_offset。占8个字节,这里是0x2014,十进制是8212,说明该节在文件映像中的偏移量8212。

sh_size。占8个字节,这里是0x3c,十进制是60,说明该节的大小是60个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x4,十进制4,说明该节在文件映像和内存映像中4个字节一对齐。

sh_entsize。占8个字节,这里是0,说明该节没有固定大小的条目。如果有就不会是0,而是具体的值,该值就是每个条目的大小。例如符号表。

第19个节(section)

15776+64=15840,从15840处取64个字节就是第19个节描述条目

%title插图%num

sh_name。占4个字节,这里是0xbf,说明在节头字符串表191个字节开始是该节的名称值

sh_type。占4个字节,这里是0x1,类型是SHT_RELA,表示本节包含带有显式加数的重定位条目, 一个目标文件可能具有多个重定位节。这是第9个重定位节。

sh_flags。站8个字节,这里是0x2,2表示的属性是SHF_ALLOC,说明该节在程序执行期间会占用内存。

sh_addr。占8个字节,这里是0x2050,说明该节在进程内存映像中的地址0x2050

sh_offset。占8个字节,这里是0x2050,十进制是8272,说明该节在文件映像中的偏移量8272。

sh_size。占8个字节,这里是0x108,十进制是264,说明该节的大小是264个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x8,十进制8,说明该节在文件映像和内存映像中8个字节一对齐。

sh_entsize。占8个字节,这里是0,说明该节没有固定大小的条目。如果有就不会是0,而是具体的值,该值就是每个条目的大小。例如符号表。

第20个节(section)

15840+64=15904,从15904处取64个字节就是第20个节描述条目

%title插图%num

sh_name。占4个字节,这里是0xc9,说明在节头字符串表201个字节开始是该节的名称值

sh_type。占4个字节,这里是0xe,

%title插图%num

类型是SHT_INIT_ARRAY,该节表示函数指针数组,用于构成包含此节的可执行文件或共享目标文件的单个初始化数组。

sh_flags。站8个字节,这里是0x3,3表示的属性是SHF_ALLOC + SHF_WRITE,说明该节在程序执行期间会占用内存并且权限是可写的。

sh_addr。占8个字节,这里是0x3de8,说明该节在进程内存映像中的地址0x3de8

sh_offset。占8个字节,这里是0x2de8,十进制是11752,说明该节在文件映像中的偏移量11752。

sh_size。占8个字节,这里是0x8,十进制是8,说明该节的大小是8个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x8,十进制8,说明该节在文件映像和内存映像中8个字节一对齐。

sh_entsize。占8个字节,这里是0x8,十进制是8,说明该节有固定大小的条目。每个条目的大小是8个字节。

第21个节(section)

15904+64=15968,从15968处取64个字节就是第21个节描述条目

%title插图%num

sh_name。占4个字节,这里是0xd5,说明在节头字符串表213个字节开始是该节的名称值

sh_type。占4个字节,这里是0xf

%title插图%num

类型是SHT_FINI_ARRAY,该节表示函数指针数组,用于构成包含此节的可执行文件或共享目标文件的单个终止数组。

sh_flags。站8个字节,这里是0x3,3表示的属性是SHF_ALLOC + SHF_WRITE,说明该节在程序执行期间会占用内存并且权限是可写的。

sh_addr。占8个字节,这里是0x3df0,说明该节在进程内存映像中的地址0x3df0

sh_offset。占8个字节,这里是0x2df0,十进制是11760,说明该节在文件映像中的偏移量11760。

sh_size。占8个字节,这里是0x8,十进制是8,说明该节的大小是8个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x8,十进制8,说明该节在文件映像和内存映像中8个字节一对齐。

sh_entsize。占8个字节,这里是0x8,十进制是8,说明该节有固定大小的条目。每个条目的大小是8个字节。

第22个节(section)

15968+64=16032,从16032处取64个字节就是第22个节描述条目

%title插图%num

sh_name。占4个字节,这里是0xe1,说明在节头字符串表225个字节开始是该节的名称值

sh_type。占4个字节,这里是0x6

%title插图%num

类型是SHT_DYNAMIC,该节是存放动态链接信息。

sh_flags。站8个字节,这里是0x3,3表示的属性是SHF_ALLOC + SHF_WRITE,说明该节在程序执行期间会占用内存并且权限是可写的。

sh_addr。占8个字节,这里是0x3df8,说明该节在进程内存映像中的地址0x3df8

sh_offset。占8个字节,这里是0x2df8,十进制是11768,说明该节在文件映像中的偏移量11768。

sh_size。占8个字节,这里是0x1c0,十进制是448,说明该节的大小是448个字节。

sh_link。占4个字节,这里是6。说明该节会关联到其它节,其它节在字符串表节中的索引是6。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x8,十进制8,说明该节在文件映像和内存映像中8个字节一对齐。

sh_entsize。占8个字节,这里是0x10,十进制是16,说明该节有固定大小的条目。每个条目的大小是16个字节。

第23个节(section)

16032+64=16096,从16096处取64个字节就是第23个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x98,说明在节头字符串表152个字节开始是该节的名称值

sh_type。占4个字节,这里是0x1,类型是SHT_PROGBITS

sh_flags。站8个字节,这里是0x3,3表示的属性是SHF_ALLOC + SHF_WRITE,说明该节在程序执行期间会占用内存并且权限是可写的。

sh_addr。占8个字节,这里是0x3fd8,说明该节在进程内存映像中的地址0x3fd8

sh_offset。占8个字节,这里是0x2fd8,十进制是12248,说明该节在文件映像中的偏移量12248。

sh_size。占8个字节,这里是0x28,十进制是40,说明该节的大小是40个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x8,十进制8,说明该节在文件映像和内存映像中8个字节一对齐。

sh_entsize。占8个字节,这里是0x8,十进制是8,说明该节有固定大小的条目。每个条目的大小是8个字节。

第24个节(section)

16096+64=16160,从16160处取64个字节就是第24个节描述条目

%title插图%num

sh_name。占4个字节,这里是0xea,说明在节头字符串表234个字节开始是该节的名称值

sh_type。占4个字节,这里是0x1,类型是SHT_PROGBITS

sh_flags。站8个字节,这里是0x3,3表示的属性是SHF_ALLOC + SHF_WRITE,说明该节在程序执行期间会占用内存并且权限是可写的。

sh_addr。占8个字节,这里是0x4000,说明该节在进程内存映像中的地址0x4000

sh_offset。占8个字节,这里是0x3000,十进制是12288,说明该节在文件映像中的偏移量12288。

sh_size。占8个字节,这里是0x20,十进制是32,说明该节的大小是32个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x8,十进制8,说明该节在文件映像和内存映像中8个字节一对齐。

sh_entsize。占8个字节,这里是0x8,十进制是8,说明该节有固定大小的条目。每个条目的大小是8个字节。

第25个节(section)

16096+64=16224,从16224处取64个字节就是第25个节描述条目

%title插图%num

sh_name。占4个字节,这里是0xf3,说明在节头字符串表243个字节开始是该节的名称值

sh_type。占4个字节,这里是0x1,类型是SHT_PROGBITS

sh_flags。站8个字节,这里是0x3,3表示的属性是SHF_ALLOC + SHF_WRITE,说明该节在程序执行期间会占用内存并且权限是可写的。

sh_addr。占8个字节,这里是0x4020,说明该节在进程内存映像中的地址0x4020

sh_offset。占8个字节,这里是0x3020,十进制是12320,说明该节在文件映像中的偏移量12320。

sh_size。占8个字节,这里是0x10,十进制是16,说明该节的大小是16个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x8,十进制8,说明该节在文件映像和内存映像中8个字节一对齐。

sh_entsize。占8个字节,这里是0,说明该节没有固定大小的条目。如果有就不会是0,而是具体的值,该值就是每个条目的大小。例如符号表。

第26个节(section)

16224+64=16288,从16288处取64个字节就是第26个节描述条目

%title插图%num

sh_name。占4个字节,这里是0xf9,说明在节头字符串表249个字节开始是该节的名称值

sh_type。占4个字节,这里是0x8,类型是SHT_NOBITS

%title插图%num

此类型的节在文件中不占空节。但与SHT_PROGBITS相似。 尽管不包含任何字节,但sh_offset字段包含概念性文件偏移量。

sh_flags。站8个字节,这里是0x3,3表示的属性是SHF_ALLOC + SHF_WRITE,说明该节在程序执行期间会占用内存并且权限是可写的。

sh_addr。占8个字节,这里是0x4030,说明该节在进程内存映像中的地址0x4030

sh_offset。占8个字节,这里是0x3030,十进制是12336,说明该节在文件映像中的偏移量12336。

sh_size。占8个字节,这里是0x8,十进制是8,说明该节的大小是8个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x1,十进制1,说明该节在文件映像和内存映像中无需对齐。

sh_entsize。占8个字节,这里是0,说明该节没有固定大小的条目。如果有就不会是0,而是具体的值,该值就是每个条目的大小。例如符号表。

第27个节(section)

16288+64=16352,从16352处取64个字节就是第27个节描述条目

%title插图%num

sh_name。占4个字节,这里是0xfe,说明在节头字符串表254个字节开始是该节的名称值

sh_type。占4个字节,这里是0x1,类型是SHT_PROGBITS

sh_flags。站8个字节,这里是0x3,3表示的属性是SHF_ALLOC + SHF_WRITE,说明该节在程序执行期间会占用内存并且权限是可写的。

sh_addr。占8个字节,这里是0x0,说明该节在进程内存映像中的地址0x0

sh_offset。占8个字节,这里是0x3030,十进制是12366,说明该节在文件映像中的偏移量12366。插一句:该节偏移量正好接在上篇文章的末尾。

sh_size。占8个字节,这里是0x26,十进制是38,说明该节的大小是38个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x1,十进制1,说明该节在文件映像和内存映像中无需对齐。

sh_entsize。占8个字节,这里是0x1,十进制是1,说明该节有固定大小的条目。每个条目的大小是1个字节。

第28个节(section)

16352+64=16416,从16416处取64个字节就是第28个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x1,说明在节头字符串表1个字节开始是该节的名称值

sh_type。占4个字节,这里是0x2,类型是SHT_SYMTAB,即符号表节,此时符号表露出水面。通常,SHT_SYMTAB提供用于链接编辑的符号,尽管它也可以用于动态链接。 它是一个完整的符号表,它可能包含许多动态链接不需要的符号。 一个目标文件也可以包含一个SHT_DYNSYM节。

sh_flags。站8个字节,这里是0x0,无属性

sh_addr。占8个字节,这里是0x0,说明该节在进程内存映像中的地址0x0

sh_offset。占8个字节,这里是0x3058,十进制是12376,说明该节在文件映像中的偏移量12376。

sh_size。占8个字节,这里是0x600,十进制是1536,说明该节的大小是1536个字节。

sh_link。占4个字节,这里是1c。关联的字符串表的节头索引是0x1c

sh_info。占4个字节,这里是0x2d,比最后一个本地符号的符号表索引大一个(绑定STB_LOCAL)。

sh_addralign。占8个字节,这里是0x8,十进制8,说明该节在文件映像和内存映像中8字节一对齐。

sh_entsize。占8个字节,这里是0x18,十进制是24,说明该节有固定大小的条目。每个条目的大小是24个字节。

第29个节(section)

16416+64=16480,从16480处取64个字节就是第29个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x9,说明在节头字符串表9个字节开始是该节的名称值

sh_type。占4个字节,这里是3,节类型是SHT_STRTAB,即字符串表,前面说过一个目标文件可能会有多个字符串表节

sh_flags。站8个字节,这里是0x0,无属性。

sh_addr。占8个字节,这里是0,没有地址

sh_offset。占8个字节,这里是0x3658,十进制是13912,说明该节在文件映像中的偏移量13912。

sh_size。占8个字节,这里是0x1ff,十进制是511,说明该节的大小是511个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x1,说明该节在文件映像和内存映像中无需对齐。

sh_entsize。占8个字节,这里是0,说明该节没有固定大小的条目。如果有就不会是0,而是具体的值,该值就是每个条目的大小。例如符号表。

第30个节(section)

16480+64=16544,从16544处取64个字节就是第30个节描述条目

%title插图%num

sh_name。占4个字节,这里是0x11,说明在节头字符串表17个字节开始是该节的名称值

sh_type。占4个字节,这里是3,节类型是SHT_STRTAB,即字符串表,前面说过一个目标文件可能会有多个字符串表节

sh_flags。站8个字节,这里是0x0,无属性。

sh_addr。占8个字节,这里是0,没有地址

sh_offset。占8个字节,这里是0x3857,十进制是14423,说明该节在文件映像中的偏移量14423。

sh_size。占8个字节,这里是0x107,十进制是263,说明该节的大小是263个字节。

sh_link。占4个字节,这里是0。

sh_info。占4个字节,这里是0,说明特定节的描述信息是空的。

sh_addralign。占8个字节,这里是0x1,说明该节在文件映像和内存映像中无需对齐。

sh_entsize。占8个字节,这里是0,说明该节没有固定大小的条目。如果有就不会是0,而是具体的值,该值就是每个条目的大小。例如符号表。

到这节头表的拆解结束了,一共30个节。下一篇文章来看看这30个节每个节的内容是什么。

发表回复