ELF文件格式,全稱為Excutable and Linking Format,是一個開放的可執行文件和鏈接文件格式,在LINUX上很流行,跨平台軟件的設計也多以ELF格式作為標准,其結構擴展性兼容性都很強.
ELF結構分析起來主要有兩種模式,一是編譯時模式,另一個是運行時模式,同一個文件在不同的時期用不同的眼光看,數據雖然沒變化,但是着重點是不同的,在編譯器,文件以數據節的形式分區,在運行時期,文件以程序段的形式分區
基本結構如下
可以看到,段,其實就是由節組成的,這篇文章中我們僅僅討論節,也就是說,僅僅討論鏈接視圖,首先我們先得知道ELF的數據類型定義
首先是ELF頭,ELF頭是ELF文件的標識,讀取一個ELF文件總是從ELF頭開始的,他總是在文件的開頭,結構如下
ELF頭開頭的結構體叫做魔數頭,是一個16位的數組,(從第九位開始,就是填充字節,沒有意義的數據)關於它的定義如下
ELF頭結構體雖然每一個數據的長度都不同,但是在文件的存儲上,它是以每個數據四位的情況來存儲的,只是說四位數據里面有效數據是那么長,這樣可以避免文件讀取的時候的結構體對齊的問題
通過ELF頭我們可以看到,ELF頭指定了文件節區頭表的文件偏移地址,以及節區頭表的數目和大小,通過這個,我們可以讀到節區頭表,也就是說,節區頭表不一定是緊挨在ELF頭的后面,他們的關系如下
節區表類似於一個數組,防止了e_shnum個節區頭信息,每個節區頭信息的長度是e_shensize,這e_shnum個節區在文件中的存放時連續的,節區頭信息如下
通過節區頭數據的sh_offset,我們可以找到這個節區頭對應的節區數據,節區數據也不是連續存放在文件中的
節區數據根據節區頭信息的sh_type信息有幾種分類
當sh_type為1,這是一個程序數據表,里面存放的是代碼二進制數據,長度為節頭指定長度
當sh_type為2,這是一個符號表,相當於一個數組,里面存放的結構體,數組長度為sh_size/sh_entsize,每個結構體的定義如下
當sh_type為3,這是一個字符串表,里面存放着一些字符,相當於一個字符數組,一個ELF文件里面有兩個字符串表,一個叫做節區頭符串表,一個叫做通用字符串表.我們在節區頭里面可以看到有一個sh_name,這是一個數字,我們需要去節區字符串表中尋找對應的字符串,尋找方式是,從sh_name中獲得的字符串開始索引,直到遇到’\0’字符停止,得到的數據就是該節區字符串表的名稱,節區字符串表存放在sh_strndx指向的節區里面,其他的所有名稱都存放在另一個字符串表中,
當sh_type為9,這是一個重定位表,依然相當於一個數組,里面存放了重定位結構體數組,數組長度為sh_size/sh_entsize,每個結構體的定義如下
重要的數據基本就是這些