逆向工程之ELF文件格式分析

一、概述

1.ELF全稱Executable and Linkable Format,可執行連接格式,ELF格式的文件用於存儲Linux程序。ELF文件(目標文件)格式主要三種:

  • 可重定向文件:文件保存着代碼和適當的數據,用來和其他的目標文件一起來創建一個可執行文件或者是一個共享目標文件。(目標文件或者靜態庫文件,即linux通常後綴爲.a和.o的文件)
  • 可執行文件:文件保存着一個用來執行的程序。(例如bash,gcc等)
  • 共享目標文件:共享庫。文件保存着代碼和合適的數據,用來被下連接編輯器和動態鏈接器鏈接。(linux下後綴爲.so的文件。)
    目標文件既要參與程序鏈接又要參與程序執行:

一般的 ELF 文件包括三個索引表:ELF header,Program header table,Section header table。

  • ELF header:在文件的開始,保存了路線圖,描述了該文件的組織情況。
  • Program header table:告訴系統如何創建進程映像。用來構造進程映像的目標文件必須具有程序頭部表,可重定位文件不需要這個表。
  • Section header table:包含了描述文件節區的信息,每個節區在表中都有一項,每一項給出諸如節區名稱、節區大小這類信息。用於鏈接的目標文件必須包含節區頭部表,其他目標文件可以有,也可以沒有這個表。

二、分析ELF文件頭(ELF header)

  • 進入終端輸入:cd /usr/include 進入include文件夾後查看elf.h文件,查看ELF的文件頭包含整個文件的控制結構
    image001.png-409.5kB

  • 寫一個小程序(hello 20135328)進行編譯,生成hello可執行文件。
    使用‘readelf –a hello’命令,都得到下面的ELF Header頭文件的信息,如下圖:
    image005.png-90.1kB
    image007.png-336.2kB

  • 通過上圖信息,可以得出Elf Header的Size爲52bytes,所以可以使用hexdump工具將頭文件的16進製表打開。
    如下圖使用:‘hexdump -x hello -n 52 ’命令來查看hello文件頭的16進製表(前52bytes)對格式進行分析。
    QQ截圖20160601195715.png-135.3kB

  • 第一行
    • 對應e_ident[EI_NIDENT]。實際表示內容爲7f454c46010100010000000000000000,前四個字節7f454c46(0x45,0x4c,0x46是'e','l','f'對應的ascii編碼)是一個魔數,表示這是一個ELF對象。
    • 接下來的一個字節01表示是一個32位對象,接下來的一個字節01表示是小端法表示,再接下來的一個字節01表示文件頭版本。剩下的默認都設置爲0.
  • 第二行
    • e_type值爲0x0002,表示是一個可執行文件
    • 。e_machine值爲0x003e,表示是Advanced Micro Devices X86-64處理器體系結構。
    • e_version值爲0x00000001,表示是當前版本。
    • e_entry值爲0x 08048320,表示入口點。
  • 第三行
    • e_phof f值爲0x1178,表示程序頭表。
    • e_shoff值爲0x0034,表示段表的偏移地址。
  • 第四行
    • e_flags值爲0x001e,表示未知處理器特定標誌。
    • e_ehsize值爲0x0034,表示elf文件頭大小(正好是52bytes)。
    • e_phentsize表示一個program header表中的入口的長度,值爲0x0020。
    • e_phnum的值爲0x0009,給出program header表中的入口數目。
    • e_shentsize值爲0x0028表示段頭大小爲40個字節。e_shnum值爲0x001e,表示段表入口有30個。
    • e_shstrndx值爲0x001b,表示段名串表的在段表中的索引號。

      三、通過文件頭找到section header table,理解其內容

  • file elf顯示生成的目標文件hello的類型
  • elf是一個可執行文件。輸入:ls –l hello查看hello的大小:
    image013.png-125kB
  • 如圖可知,hello大小爲7336字節。
    輸入:hexdump –x hello來用16進制的數字來顯示hello的內容
    (其中,第二列是16進製表示的偏移地址)
    QQ截圖20160601193548.png-608.2kB
  • 輸入:objdump –x hello來顯示hello中各個段以及符號表的相關信息:
    image015.png-442.7kB
  • 輸入:readelf –a hello來查看各個段信息:
  • ELF文件頭信息:
    image017.png-402.2kB
  • 段表Section header table:
    image025.png-597.4kB
  • 符號表 Symbol table:
    image019.png-549.3kB
    image021.png-593.1kB
    image023.png-78.5kB

    四、通過section header table找到各section

    在一個ELF文件中有一個section header table,通過它我們可以定位到所有的 section,而 ELF header 中的e_shoff 變量就是保存 section header table 入口對文件頭的偏移量。而每個 section 都會對應一個 section header ,所以只要在 section header table 中找到每個 section header,就可以通過 section header 找到你想要的 section。

下面以可執行文件hello爲例,以保存代碼段的 section 爲例來講解讀取某個section 的過程。
使用‘vi /usr/include/elf.h ’命令查看Sections Header的結構體:
image027.png-540.1kB

由上面分析可知,section headers table中的每一個section header所佔的size均爲64字節,ELF header得到了e_shoff變量的值爲0X0034,也就是table入口的偏移量,通過看e_shnum值爲0x001e,表示段表入口有30個。
所以從0x00000034開始有30個段,每個段佔40個字節大小,輸入 hexdump hello查看:
image029.png-333.8kB

  • 第一個段,其中內容全部爲0,所以不表示任何段。
  • 第二個段,爲.interp段

  • 第三個段,爲.note.ABI-tag段

  • 第四個段,爲.note.gnu.build-i段

  • 第五個段,爲.gnu.hash段

.......

  • 第十四個段,爲.text段

  • 第十六個段,爲.rodata段

  • 第二十五個段,爲.data段

  • 第二十六個段,爲.bss段

  • 第二十九個段, 爲.symtab段

  • 第三十個段, 爲.strtab段

我們用readelf 命令去查看.text這個 section 中的內容,
輸入readelf –x 13 hello,(.text前面的標號爲13)對13索引號的.text的section的內容進行查看:
image031.png-566.3kB

下面用 hexdump 的方法去讀取.text這個 section 中的內容,通過看section header中.text中offset和size分別是0x320和0x192
輸入 hexdump –C hello
找到320後的192個
image033.png-159.3kB
image035.png-126.1kB
得到了和上面的readelf得到的相同。
使用下面命令對hello的文本段(.text)進行反彙編:
objdump –d hello 得到如下圖:
image037.png-404.4kB
image039.png-547kB
可以看出,使用反彙編的16進制數據和前面查找到的是相同的。

五、理解常見.text .strtab .symtab .rodata等section

image025.png-597.4kB

  1. text section是可執行指令的集合,.data和.text都是屬於PROGBITS類型的section,這是將來要運行的程序與代碼。查詢段表可知.text section的位偏移爲0x0000320,size爲0x0000192。
  2. strtab section是屬於STRTAB類型的section,可以在文件中看到,它存着字符串,儲存着符號的名字。位偏移爲0x000106f,size爲0x0000106
  3. symtab section存放所有section中定義的符號名字,比如“data_items”,“start_loop”。 .symtab section是屬於SYMTAB類型的section,它描述了.strtab中的符號在“內存”中對應的“內存地址”。 位偏移爲0x0001628,size爲0x0000430。
  4. rodata section,ro代表read only。位偏移爲0x000050c,size爲0x00000b0。

文章轉自:https://www.cnblogs.com/cdcode/p/5551649.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章