1. 程式人生 > 其它 >elf檔案--基於《ctf競賽權威指南pwn篇》

elf檔案--基於《ctf競賽權威指南pwn篇》

1.ELF概念:

ELF(Executable and Linkable Format),即“可執行可連結格式”,最初由UNIX系統實驗室作為應用程式二進位制介面(Application Binary Interface – ABI)的一部分而制定和釋出,是COFF(Common file format)格式的變種。Linux系統上所執行的就是ELF格式的檔案,相關定義在“/usr/include/elf.h”檔案裡。


它和在Windows下pe檔案是相對的。



可以看到ELF檔案非常的多,我沒有細細的看。

2.ELF檔案的幾種型別:

ELF檔案分為三種類型,可執行檔案(.exec)、可重定位檔案(.rel)和共享目標檔案(.dyn):
  1. 可執行檔案(executable file):經過連結的、可執行的目標檔案,通常也被稱為程式。
  2. 可重定位檔案(relocatable file):由原始檔編譯而成且尚未連結的目標檔案,通常以“.o”作為副檔名。用於與其他目標檔案進行連結以構成可執行檔案或動態連結庫,通常是一段位置獨立的程式碼(Position Independent Code, PIC)。
    對於.o結尾的檔案,在編譯的時候可以link到我們的程式中去
  3. 共享目標檔案(shared object file):動態連結庫檔案。用於在連結過程中與其他動態連結庫或可重定位檔案一起構建新的目標檔案,或者在可執行檔案載入時,連結到程序中作為執行程式碼的一部分。

3.ELF檔案的結構

在ELF檔案格式規範中,ELF檔案被統稱為object file,這與我們通常理解的.o檔案是不太一樣的。

  • 在審視一個目標檔案時,有兩種視角可供選擇,一種是連結視角,通過節(Section)來進行劃分;另一種是執行視角,通過段(Segment)來進行劃分

下面我們先從連結視角去來看看:

(這是簡化版的elf檔案頭)
我們可以看見程式碼段(.text)和資料段(.data)是分開處理的,這一點就是從安全的角度去出發考慮的。
下面我們自上而下的介紹連結視角去看的elf檔案.


首先我們寫一個簡單的helloworld程式,然後使用gcc編譯器將編譯過程中的中間檔案給生成出來。


我們額可以通過gcc生成幾個不同main可執行檔案過程中的幾個中間檔案檢視elf檔案readelf -h main



我們可以看見這個第一條就是一個magic,這個是個什麼意思呢??這個美其名曰魔術字元(7f 45 4c 46),當檔案被對映到記憶體中的時候,通過尋找這
個字元可以確定對映的地址。

這裡我們給出ELF64_Ehdr結構體的程式碼:

看完了elf_hander下面我們就來看看section節:

  • 一個目標檔案包含了許多的節,這些節的資訊保持在節頭表中(section header table)中,表的每一項都是ELF64_Shdr的結構體(注意與之前的ELF64_Ehdr區別)

檢視節表頭

讀取節頭表 readelf -S main.o


至於另外的兩個.data和.bss段我不想看了,因為腿這會麻了。


這是一些其他節的東西,我看著書上面寫出來的我複製一些吧,也算自己記憶。


字串表(shstrtab和strtab)中包含了以null結尾的字元序列,用來表示符號名和節名,引用字串時只需給出字元序列在表中的偏移即可。字串表的第一個字元和最後一個字元都是null字元,以確保所有字串的開始和終止。



  • 符號表(.dynsym和.symtab)記錄了目標檔案中所用到的所有符號資訊,通常分為.dynsym和.symtab,前者是後者的子集。.dynsym儲存了引用自外部檔案的符號,只能在執行時被解析,而.symtab還儲存了本地符號,用於除錯和連結。目標檔案通過一個符號在表中的索引值來使用該符號。索引值從0開始計數,但值為0的表項不具有實際的意義,它表示未定義的符號。每個符號都有一個符號值(symbol value),對於變數和函式,該值就是符號的地址。


num就是索引值。

  • 接下來我們看的是重定位
    重定位是連線符號定義與符號引用的過程。可重定位檔案在構建可執行檔案或共享目標檔案時,需要把節中的符號引用換成這些符號在程序空間中的虛擬地址。


這裡offset是在重定位時候需要被修改的符號偏移,info分為兩個部分:type知識如何修改引用,symbol指示應該修改引用為那個符號,addend表示對於被修改符號的引用做偏移調整。


以上呢就是在link視角下去看elf檔案了