elf文件结构
elf文件結(jié)構(gòu)
有三種類型
可重定位文件(Relocatable File),包含由編譯器生成的代碼以及數(shù)據(jù)。鏈接器會將它與其它目標(biāo)文件鏈接起來從而創(chuàng)建可執(zhí)行文件或者共享目標(biāo)文件。在 Linux 系統(tǒng)中,這種文件的后綴一般為 .o 。
可執(zhí)行文件(Executable File),就是我們通常在 Linux 中執(zhí)行的程序。
共享目標(biāo)文件(Shared Object File),包含代碼和數(shù)據(jù),這種文件是我們所稱的庫文件,一般以 .so 結(jié)尾。一般情況下,它有以下兩種使用情景
鏈接器(Link eDitor, ld)可能會處理它和其它可重定位文件以及共享目標(biāo)文件,生成另外一個目標(biāo)文件。
動態(tài)鏈接器(Dynamic Linker)將它與可執(zhí)行文件以及其它共享目標(biāo)組合在一起生成進程鏡像
目標(biāo)文件既會參與程序鏈接又會參與程序執(zhí)行。出于方便性和效率考慮,根據(jù)過程的不同,目標(biāo)文件格式提供了其內(nèi)容的兩種并行視圖,如下
鏈接視圖
文件開始處是 ELF 頭部,給出文件的組織情況
program header table 告訴系統(tǒng)如何創(chuàng)建進程
section header table 描述文件節(jié)區(qū)信息
ELF Header
描述elf文件的概要信息
e_ident放魔數(shù),64還是32,小端還是大端,EV_CURRENT(版本必須是),填充
e_type是什么類型的elf文件
e_mechine是什么機器架構(gòu)
e_version 是EV_CURRENt
e_entey 是 程序入口點的虛擬地址
e_phoff是程序頭部表的字節(jié)偏移
e_shoff是節(jié)頭表(段表)的字節(jié)偏移
e_flags不知道有什么用
e_ehsize頭部的字節(jié)長度(head)
e_phentsize頭部每個表相的字節(jié)長度(Program Header ENTry SIZE)
e_phnum 頭部表的項數(shù)(Program Header entry NUMbe)
e_shentsize節(jié)頭的字節(jié)長度
e_shnum節(jié)頭的項數(shù)
e_shstrndx(看不懂)
Program Header Table
Program Header Table 是一個結(jié)構(gòu)體數(shù)組,每一個元素的類型是 Elf32_Phdr,描述了一個段或者其它系統(tǒng)在準備程序執(zhí)行時所需要的信息。其中,ELF 頭中的 e_phentsize 和 e_phnum 指定了該數(shù)組每個元素的大小以及元素個數(shù)。一個目標(biāo)文件的段包含一個或者多個節(jié)。程序的頭部只有對于可執(zhí)行文件和共享目標(biāo)文件有意義
該結(jié)構(gòu)用于定位 ELF 文件中的每個節(jié)區(qū)的具體位置。
內(nèi)存中任何段的虛擬地址與文件中對應(yīng)的虛擬地址之間的差值對于任何一個可執(zhí)行文件或共享對象來說是一個單一常量值。這個差值就是基地址,基地址的一個用途就是在動態(tài)鏈接期間重新定位程序
段內(nèi)容
一個段可能包括一到多個節(jié)區(qū),但是這并不會影響程序的加載。盡管如此,我們也必須需要各種各樣的數(shù)據(jù)來使得程序可以執(zhí)行以及動態(tài)鏈接等等
Section Header Table
其實這個數(shù)據(jù)結(jié)構(gòu)是在 ELF 文件的尾部
該結(jié)構(gòu)用于定位 ELF 文件中的每個節(jié)區(qū)的具體位置。
首先,ELF頭中的 e_shoff 項給出了從文件開頭到節(jié)頭表位置的字節(jié)偏移。e_shnum 告訴了我們節(jié)頭表包含的項數(shù);e_shentsize 給出了每一項的字節(jié)大小。
其次,節(jié)頭表是一個數(shù)組,每個數(shù)組的元素的類型是 ELF32_Shdr ,每一個元素都描述了一個節(jié)區(qū)的概要內(nèi)容
typedef struct {ELF32_Word sh_name;ELF32_Word sh_type;ELF32_Word sh_flags;ELF32_Addr sh_addr;ELF32_Off sh_offset;ELF32_Word sh_size;ELF32_Word sh_link;ELF32_Word sh_info;ELF32_Word sh_addralign;ELF32_Word sh_entsize; } Elf32_Shdr;sh_name 節(jié)名稱
sh_type 節(jié)類型
sh_flags 描述節(jié)是否可寫,可執(zhí)行,需要分配內(nèi)存等屬性
sh_addr 在內(nèi)存鏡像的位置
sh_offset在文件的偏移
sh_size 節(jié)區(qū)的字節(jié)大小
sh_link 此成員給出節(jié)區(qū)頭部表索引鏈接
sh_info 此成員給出附加信息
sh_addralign 某些節(jié)區(qū)的地址需要對齊
sh_entsize(不曉得)
elf中一些特殊的表(段)
.rel.xxxx (重定位表 用來描述修改段的內(nèi)容 調(diào)指令的) sh_type為SHT_REL ()
typedef struct {Elf32_Addr r_offset;//重定位入口點的偏移Elf32_Word r_info;//類型和符號 }Elf32_Re;.strtab 字符串表
.shstrtab 段表
.symtab 符號表(經(jīng)常被刪。。。)
Elf32_Sym的數(shù)組
(動態(tài)鏈接 延遲綁定的)
got
plt (dl_runtime_resolve())
.got保留全局變量引用的地址
.got.plt(函數(shù)引用的地址)(數(shù)組)
0 .dynamic段的地址
1 id
2 _d1_runtime_resolve(的地址)
.dynsym(動態(tài)符號表)
總結(jié)
- 上一篇: ftp客户端代码
- 下一篇: win7 由ie8升级ie11时安装不成