ELF文件结构图
我这儿的示例文件编译的时候没有加任何选项,生成的是共享目标文件,并不是严格意义上的可执行文件,该文件的文件类型是DYN (Shared object file)。
默认情况下生成的都是DYN类型的共享目标文件,授予执行权限一样可以被执行,但是要细究会发现有很大区别,暂不细究。
记得在ELF的段(segment)这篇文章中我们已经知道了示例文件(共享目标文件)的前12336个字节的构成,如下图
前12336个字节是文件头、程序头和段(segment),12336个字节后面的内容是什么我当时留下的是未知。。。且待下回拆解
现在我来衔接上
在ELF的节(section)的这篇文章我们拆分是记得有2个节的偏移量是0x3030,十进制就是12336,这2个节分别是.bss节和.comment节
其中.bss节的大小是8个字节,.comment节的大小是38个字节,这2个节的偏移量都是从12336开始,但是.comment节包含了.bss节
没关系,不管谁包含谁,但是我们知道的是从12336个字节的地方开始是.comment节,大小是38个字节,其中包含了8个字节的.bss节的数据
12336+38=12374,那么12374个字节后面的内容是什么呢?
在ELF的节(section)这篇文章中拆分时可以发现12376个字节开始是.symtab节,12376-12374=2,中间的这2个字节的数据是0。
.symtab节大小是1536个字节,12376+1536=13912,13912正好又是.strtab节的偏移量,说明13912个字节后面是.strtab节
.strtab节的大小是511,13912+511=14423,14423正好是.shstrtab节的偏移量,说明14423个字节后面是.shstrtab节
.shstrtab节的大小是263,14423+263=14686,14686后面2个0字节的数据即14688正好是第1个节描述条目,第一个节描述条目都是0,描述条目就是该节本身,该条目的偏移量,也可以说是节头表的偏移量,因为节头表也是从14688开始的
这个空节的条目占了64个字节,14688+64=14752,14752正好是第2个节描述条目,即.interp节描述条目的偏移量,大小是64个字节,.interp节数据的偏移量是多少,根据ELF的节(section)这篇文章拆分是我们已经知道了每个节的偏移量和大小,该节的偏移量是680,大小是28,与PT_INTERP段重合,即PT_INTERP段同时也是.interp节
14752+64=14816,14816正好是第3个节描述条目,即.note.gnu.build-id节描述条目的偏移量,大小是64个字节,.note.gnu.build-id节数据的偏移量是708,大小是36,正好偏移量与PT_NOTE段相等,但是大小不等,PT_NOTE段大小68个字节,那说明PT_NOTE段包含了一个.note.gnu.build-id节
14816+64=14880,14880正好是第4个节描述条目,即.note.ABI-tag节的偏移量,大小是64个字节,.note.ABI-tag节数据的偏移量是744,大小是32,这正好是PT_NOTE段减去.note.gnu.build-id节的数据,说明PT_NOTE段刚好不多不少包含了.note.gnu.build-id节和.note.ABI-tag节
14880+64=14944,14944正好是第5个节描述条目,即.gnu.hash节描述条目的偏移量,大小是64个字节,.gnu.hash节数据的偏移量是776,大小是36,这正好衔接在.note.ABI-tag节后面
14944+64=15008,15008正好是第6个节描述条目,即.dynsym节描述条目的偏移量,大小是64个字节,.dynsym节数据的偏移量是816,大小是168,正好衔接在.gnu.hash节的后面(中间间隔4个字节的0)
15008+64=15072,15072正好是第7个节描述条目,即.dynstr节描述条目的偏移量,大小是64个字节,.dynstr节数据的偏移量是984,大小是130,正好衔接在.dynsym节的后面
15072+64=15136,15136正好是第8个节描述条目,即.gnu.version节描述条目的偏移量,大小是64个字节,.gnu.version节数据的偏移量是1114,大小是14,正好衔接在.dynstr节的后面
15136+64=15200,15200正好是第9个节描述条目即.gnu.version_r节描述条目的偏移量,大小是64个字节,.gnu.version_r节数据的偏移量是1128,大小是32,正好衔接在.gnu.version节后面
15200+64=15264,15264正好是第10个节描述条目即.rela.dyn节描述条目的偏移量,大小是64个字节,.rela.dyn节数据的偏移量是1160,大小是12,正好衔接在.gnu.version_r节的后面
15264+64=15328,15328正好是第11个节描述条目即.rela.plt节描述条目的偏移量,大小是64个字节,.rela.plt节数据的偏移量是1352,大小是24,位置虽然没有衔接上.rela.dyn节,但是可以看到是在.rela.dyn节的后面,且属于第一个PT_LOAD段(segment)
15328+64=15392,15392正好是第12个节描述条目即.init节描述条目的偏移量,大小是64个字节,.init节数据的偏移量是4096,大小是23,4096正好是第2个PT_LOAD段的偏移量,说明第2个PT_LOAD段的前23个字节是.init节
15392+64=15456,15456正好是第13个节描述条目即.plt节的偏移量,大小是64个字节,.plt节数据的偏移量是4128,大小是32,正好衔接在.init节后面(中间间隔9个字节的0)
15456+64=15520,15520正好是第14个节描述条目即.plt.got节描述条目的偏移量,大小是64个字节,.plt.got节数据的偏移量是4160,大小是8个字节,正好衔接在.plt节的后面
15520+64=15584,15584正好是第15个节描述条目.即text节描述条目的偏移量,大小是64个字节,.text节数据的偏移量是4176,大小是353个字节,正好衔接在.plt.got节的后面(中间间隔8个字节的0)
15584+64=15648,15648正好是第16个节(.fini节)描述条目的偏移量,大小是64个字节,.fini节数据的偏移量是4532,大小是9个字节,正好衔接在.text节后面(中间间隔3个字节的0)
15648+64=15712,15712正好是第17个节(.rodata节)描述条目的偏移量,大小是64个字节,.rodata节数据的偏移量是8192,大小是17,8192正好是第3个PT_LOAD段的偏移量,说明第3个PT_LOAD段的前17个字节是.rodata节
15712+64=15776,15776正好是第18个节(.eh_frame_hdr节)描述条目的偏移量,大小是64个字节,.eh_frame_hdr节数据的偏移量是8212,大小是60个字节,偏移量和大小都与PT_GNU_EH_FRAME段重合,说明PT_GNU_EH_FRAME段同时也是.eh_frame_hdr节
15776+64=15840,15840正好是第19个节(.eh_frame节)描述条目的偏移量,大小是64个字节,.eh_frame节数据的偏移量是8272,大小是264,正好衔接在.eh_frame_hdr节后面
15840+64=15904,15904正好是第20个节(.init_array节)描述条目的偏移量,大小是64个字节,.init_array节数据的偏移量是11752,大小是8个字节,偏移量与第4个PT_LOAD段重合,该节衔接在.eh_frame节后面(中间间隔3216个字节的0)
15904+64=15968,15968正好是第21个节(.fini_array节)描述条目的偏移量,大小是64个字节,.fini_array节数据的偏移量是11760,大小是8个字节,正好衔接在.init_array节后面
15968+64=16032,16032正好是第22个节(.dynamic节)描述条目的偏移量,大小是64个字节,.dynamic节数据的偏移量是11768,大小是480个字节,偏移量和大小与PT_DYNAMIC段重合,说明PT_DYNAMIC段同时也是.dynamic节,该节正好衔接在.fini_array节后面
16032+64=16096,16096正好是第23个节(.got节)描述条目的偏移量,大小是64个字节,.got节数据的偏移量是12248,大小是40个字节,正好衔接在.dynamic节后面
16096+64=16160,16160正好是第24个节(.got.plt节)描述条目的偏移量,大小是64个字节,.got.plt节数据的偏移量是12288,大小是32个字节,正好衔接在.got节后面
16160+64=16224,16224正好是第25个节(.data节)描述条目的偏移量,大小是64个字节,.data节数据的偏移量是12320,大小是16,正好衔接在.got.plt节后面
16224+64=16288,16288正好是第26个节(.bss节)描述条目的偏移量,大小是64个字节,.bss节数据的偏移量是12336,大小是8个字节,正好衔接在.data节后面
16288+64=16352,16352正好是第27个节(.comment节)描述条目的偏移量,大小是64个字节,.comment节数据的偏移量是12336,大小是38个字节,偏移量与.bss节相同,大小不同,.comment节的前8个字节是.bss节
16352+64=16416,16416正好是第28个节(.symtab节)描述条目的偏移量,大小是64个字节,.symtab节数据的偏移量是12376,大小是1536个字节,衔接在.comment节后面(中间间隔2个字节的0)
16416+64=16480,16480正好是第29个节(.strtab节)描述条目的偏移量,大小是64个字节,.strtab节数据的偏移量是13912,大小是511个字节,正好衔接在.symtab节后面
16480+64=16544,16544正好是第30个节(.shstrtab节)描述条目的偏移量,大小是64个字节,.shstrtab节数据的偏移量是14423,大小是263,正好衔接在.strtab节后面
其实从14688个字节开始取1920个字节这正好是整个示例文件的节头,即节头表。
上面第30个节描述条目算完之后16544+64=16608,14688+1920也等于16608,是吻合的
16608就是整个示例文件的大小。
现在我们开始将图补充完整