1. 程式人生 > >linux逆向分析之ELF檔案詳解

linux逆向分析之ELF檔案詳解

前言

首先如果大家遇到ELF二進位制檔案的逆向首先考慮的可能就是通過IDA進行靜態逆向分析演算法,那麼我們首先就要了解ELF(Executable
and Linking Format)的檔案格式。
ELF檔案格式主要分為以下幾類:
1. 可重定位檔案(Relocatable File),這類檔案包含了程式碼和資料,可以被用來連結成可執行檔案或共享目標檔案,靜態連結庫也可以歸為這一類,如.o檔案。
2. 可執行檔案(Executable File),這類檔案包含了直接執行的程式,如/bin/bash等。
3. 共享目標檔案(Shared Object File),連結器可以使用這種檔案跟其他的可重定位檔案和共享目標檔案連結,產生新的目標檔案;動態連結器可以將幾個共享目標檔案與可執行檔案結合,作為程序映像的一部分來執行,如glibc***.so。
4. 核心轉儲檔案(Core Dump File),當程序意外終止時,系統可以將該程序的地址空間內容及終止時的一些其他資訊轉儲到核心轉儲檔案。
一.elf檔案格式詳解

以上是elf檔案格式結構示意圖
檔案頭
檔案頭的結構定義如下所示:
typedef struct {
unsigned char e_ident[16]; /* ELF魔數,ELF字長,位元組序,ELF檔案版本等 */
Elf32_Half e_type; /*ELF檔案型別,REL, 可執行檔案,共享目標檔案等 */
Elf32_Half e_machine; /* ELF的CPU平臺屬性 */
Elf32_Word e_version; /* ELF版本號 */
Elf32_Addr e_entry; /* ELF程式的入口虛擬地址,REL一般沒有入口地址為0 */
Elf32_Off e_phoff; 
Elf32_Off e_shoff; /* 段表在檔案中的偏移 */
Elf32_Word e_flags; /* 用於標識ELF檔案平臺相關的屬性 */
Elf32_Half e_ehsize; /* 本檔案頭的長度 */
Elf32_Half e_phentsize; 
Elf32_Half e_phnum;
Elf32_Half e_shentsize; /* 段表描述符的大小 */
Elf32_Half e_shnum; /* 段表描述符的數量 */
Elf32_Half e_shstrndx; /* 段表字符串表所在的段在段表中的下標 */
} Elf32_Ehdr;
利用readelf命令可以檢視elf檔案的頭部資訊,大家可以對照著看


結構的各個成員的含義如註釋中所解釋的。對ELF檔案,有兩個檢視,一個是從裝載執行角度的,另一個是從連線角度的。從裝載執行角度,我們關注的是程式頭表,由程式頭表的指引把ELF檔案載入進記憶體執行它。從連線的角度,我們關注節頭表,由節頭表的指引把各個節連線組裝起來。e_type的值與這兩個檢視相聯絡,由它我們可以知道能夠從哪個檢視去解讀。
如果e_type=1,表明它是重定位檔案,可以從連線檢視去解讀它;
如果e_type=2,表明它是可執行檔案,至少可以從裝載執行檢視去解讀它;
如果e_type=3,表明它是共享動態庫檔案,同樣可以至少從裝載執行檢視去解讀它;
如果e_type=4,表明它是Coredump檔案,可以從哪個檢視去解讀依賴於具體的實現。
如上圖顯示的是可執行檔案那麼我就要從裝在執行檢視去解讀它

按照這兩個檢視,整個ELF檔案的內容這樣來組織:
首先是ELF檔案頭,也就是上面的Elf32_Ehdr結構。或者對64位的ELF檔案,是Elf64_Ehdr結構。ELF檔案頭位於檔案開始處,無論e_type的值是什麼,它是必須有的。
其次是程式頭表,對可執行檔案(e_type=2)和動態庫檔案(e_type=3),它是必須有的。對重定位檔案(e_type=1),程式頭表的有無是可選的。例如用gcc的-c選項生成的.o檔案,就沒有程式頭表。但無論如何,e_phoff和e_phnum、e_phentsize給出了ELF檔案的程式頭表資訊。沒有程式頭表時它們的值為零。
然後就是就是節頭表,對可執行檔案和動態庫檔案,它的有無是可選的,對重定位檔案,它是必須有的。
Program header table
每個程式頭表的每個表項的結構為:
typedefstruct
{
Elf32_Wordp_type;/*段型別*/
Elf32_Offp_offset;/*在檔案中的偏移*/
Elf32_Addrp_vaddr;/*執行時的虛地址*/
Elf32_Addrp_paddr;/*執行時的實體地址*/
Elf32_Wordp_filesz;/*在檔案中的位元組數*/
Elf32_Wordp_memsz;/*在記憶體中的位元組數*/
Elf32_Wordp_flags;/*標誌*/
Elf32_Wordp_align;/*位元組對齊*/
}Elf32_Phdr;

那什麼是所謂 sections 呢?可以說,sections 是在ELF檔案裡頭,用以裝載內容資料的最小容器。在ELF檔案裡面,每一個 sections 內都裝載了性質屬性都一樣的內容,比方:

1) .text section 裡裝載了可執行程式碼;

2) .data section 裡面裝載了被初始化的資料;

3) .bss section 裡面裝載了未被初始化的資料;

4) 以 .rec 打頭的 sections 裡面裝載了重定位條目;

5) .symtab 或者 .dynsym section 裡面裝載了符號資訊;

6) .strtab 或者 .dynstr section 裡面裝載了字串資訊;

7) 其他還有為滿足不同目的所設定的section,比方滿足除錯的目的、滿足動態連結與載入的目的等等。

Section heafer table
每個節頭表的每個表項的結構為:
typedefstruct
{
Elf32_Wordsh_name;/*節名索引*/
Elf32_Wordsh_type;/*節型別*/
Elf32_Wordsh_flags;/*載入和讀寫標誌*/
Elf32_Addrsh_addr;/*執行時的虛地址*/
Elf32_Offsh_offset;/*在檔案中的偏移*/
Elf32_Wordsh_size;/*位元組大小*/
Elf32_Wordsh_link;/*與其他節的關聯*/
Elf32_Wordsh_info;/*其他資訊*/
Elf32_Wordsh_addralign;/*位元組對齊*/
Elf32_Wordsh_entsize;/*如果由表項組成,每個表項的大小*/
}Elf32_Shdr;


這裡我們來討論一下連線檢視中section與裝載執行檢視segments之間的關係。
連結器在連結可執行檔案或動態庫的過程中,它會把來自不同可重定位物件檔案中的相同名稱的 section 合併起來構成同名的 section。接著,它又會把帶有相同屬性(比方都是隻讀並可載入的)的 section 都合併成所謂 segments(段)。segments 作為連結器的輸出,常被稱為輸出section。

一個單獨的 segment 通常會包含幾個不同的 sections,比方一個可被載入的、只讀的segment 通常就會包括可執行程式碼section .text、只讀的資料section .rodata以及給動態連結器使用的符號section .dymsym等等。section 是被連結器使用的,但是 segments 是被載入器所使用的。載入器會將所需要的 segment 載入到記憶體空間中執行。和用 sections header table 來指定一個可重定位檔案中到底有哪些 sections 一樣。在一個可執行檔案或者動態庫中, program header table中包含有 segments。

在當我們執行命令readelf -l讀取程式表頭的時候,結果顯示,在可執行檔案中,總共有8個 segments程式頭。同時,該結果也很明白顯示出了哪些 section 對映到哪一個 segment 當中去。比方在索引為2的那個segment 中,總共有18個 sections 對映進來,其中包括我們前面提到過的 .text section。注意這個segment 有兩個標誌: R 和 E。這個表示該segment是可讀的,也可執行的。如果你看到標誌中有W,那表示該segment是可寫的。

上面型別為PHDR的segment,用來包含程式頭表本身。型別為INTERP的segment只包含一個 section,那就是 .interp。在這個section中,包含了動態連結過程中所使用的直譯器路徑和名稱。在Linux裡面,這個直譯器實際上就是 /lib/ ,這可以通過下面的 hexdump 看出來:[[email protected] test_2]$ hexdump -s 0x134 -n 32 -C ./ElfCrackme2 
$ hexdump -s 0x134 -n 32 -C ./ElfCrackMe2
00000134 2f 6c 69 62 2f 6c 64 2d 6c 69 6e 75 78 2e 73 6f |/lib/ld-linux.so|
00000144 2e 32 00 00 04 00 00 00 10 00 00 00 01 00 00 00 |.2..............|
00000154
關於ELF格式的知識就說到這,想了解更多的去了解下大牛的文章點選開啟連結
--------------------- 
作者:mxtxgd 
來源:CSDN 
原文:https://blog.csdn.net/cavalier_anyue/article/details/45009297 
版權宣告:本文為博主原創文章,轉載請附上博文連結!