天天看點

ELF檔案格式ELF檔案格式

ELF檔案格式

0x00 準備

ELF全稱Executable and Linking Format,ELF檔案主要有3種,在檔案内部有2個byte用來指明該ELF檔案的類型(後文詳述)。為了分析ELF檔案的結構,準備好一個簡單的c語言“hello world”程式,編譯該檔案得到ELF檔案。

hw.c

#include <stdio.h>                                                                                                                              

int main(){
    printf("hello world!\n");
    return ;
}
           

指令:gcc -c hw.c

得到檔案hw.o

指令:gcc hw.c -o hw

得到檔案hw

在分析的過程中會:

  • 使用hexdump指令檢視ELF檔案的二進制資料
  • 使用readelf指令檢視ELF檔案的結構分析
  • 使用objdump指令檢視ELF檔案的資訊

指令:hexdump -C hw

得到ELF檔案hw的二進制顯示:

f  c                |.ELF............|
    e                |..>.....@.@.....|
           c8         |@...............|
               e  b   |....@...@.....|
                    |........@.......|
                    |@.@.....@.@.....|
  f8         f8         |................|
                    |................|
                    |......@.....|
           c         |@.............|
a0  c                  |................|
b0                    |................|
c0                    |..@.......@.....|
d0  c         c         |................|
                    |.. .............|
f0   e         e        |..........`.....|
........
           

0x01 ELF檔案頭(ELF Header):前64位元組

ELF檔案的前64個位元組(這裡指的是64位系統下,32位系統下稍有不同,是52個位元組)描述了ELF檔案的基本資訊,被稱為ELF頭

先分析前16個byte(0-15)

(0-3)byte:7f 45 4c 46

這個是ELF檔案的魔數,每一種檔案一般都有魔數,用來表明該檔案的類型,例如java的class檔案的魔數就是前4個byte :CAFEBABE

(4)byte : 02

這個位元組辨別此ELF檔案的平台類型,有3個可選值

0x00 :無效檔案

0x01 :32bit平台目标檔案(ELF檔案)

0x02 :64bit平台目标檔案

這裡是值為0x02表明是在64位系統下編譯的

(5)byte:01

這個位元組辨別二進制檔案的編碼類型,有3個可選值

0x00:無效編碼

0x01:小印第安排序(最大有意義的位元組占有最低的位址)

0x02:大印第安排序(最大有意義的位元組占有最高的位址)

這裡的值為0x01表明此ELF檔案使用的是小印第安排序

(6)byte:01

這個位元組指明ELF檔案格式的版本,目前必須為0x01

(7)byte :00 00 00 00 00 00 00 00 00

OS/ABI

(8)byte : 00

ABI version

(9-15)byte : 00 00 00 00 00 00 00

目前沒有意義,但是在将來可能有意義,規定必須每個byte都設定為0x00 ,但是其實不設定為0x00也可以,例如病毒程式就可以用這些byte來表明改ELF檔案是否已經被感染,或者是處于其他什麼狀态

再分析後48個byte(16-63)

(16-17)byte 02 00

這2個位元組表明文章開頭所說的ELF檔案的類型,(5)byte表明ELF檔案是小印第安排序,是以這2個位元組的值為0x0002 ,說明這是一個可執行檔案。這2個位元組的可選值如下:

0x0000 : 未知

0x0001 : 重定位檔案

0x0002 : 可執行檔案

0x0003 : 共享庫檔案

0x0004 : 核心檔案

0xff00 - 0xffff : 處理器相關

(18-19)byte 3e 00

這2個位元組表明機器架構,0x003e說明是x86_64機器

這個值的部分可選值有:

0x00 : No Manchine

0x02 : SPARC

0x03 : Intel 80386

0x12 : Sun SPARC 32+

0x2b : SPARC V9

0x3e : ADM 64

(20-23)byte 01 00 00 00

這4個位元組說明此目标檔案的版本,目前的版本均為1

(24-31)byte 40 04 40 00 00 00 00 00

這8個位元組是程式入口點位址,也就是main函數的邏輯位址,在64位系統下用8個位元組表示,32為系統下隻有4個位元組,這個值說明main函數的邏輯位址為:0x0000000000040440c8 19 00 00 00 00 00 00

(32-39)byte 40 00 00 00 00 00 00 00

這8個位元組是程式頭表(program header table)在目标檔案中的偏移位址,這裡的值為0x40,即64,說明程式頭表從第64位元組開始,也就是緊接着ELF Header之後。如果沒有程式頭表,這個值為0

(40-47)byte c8 19 00 00 00 00 00 00

這8個位元組是節頭表(section header table)在目标檔案中的偏移位址,這裡的值為0x19c8 ,說明節頭表在目标檔案的6600位元組。如果沒有節頭表這個值為0

(48-51)byte 00 00 00 00

這4個位元組就是一個與處理器相關的辨別(flag)

(52-53)byte 40 00

這2個位元組說明ELF Header本身的大小,64位系統的下是64位元組,是以是0x0040

(54-55)byte 38 00

這2個位元組辨別在程式頭表中每個程式頭的大小(以位元組為機關,每個程式頭的大小都是一樣的),此ELF檔案中每個程式頭的大小為0x38個位元組

(56-57)byte 09 00

這2個位元組說明程式頭表中程式頭的個數, 沒有的話就是0,此ELF檔案有9個程式頭

(58-59)byte 40 00

這2個位元組辨別在節頭表中每個節頭的大小(以位元組為機關,每個節頭的大小都是一樣的),此ELF檔案每個節頭的大小是0x40,即64個位元組

(60-61)byte 1e 00

這2個位元組辨別節頭表中節頭的個數,沒有的話就是0,0x1e說明ELF檔案有30個節頭

(62-63)byte 1b 00

這2個位元組表示的值是一個節頭表的索引值(是以這個值0x1b必然小于總數0x1e),通過這個索引值,可以在節頭表中找到一個特殊的節頭,在這個節頭中有每個節頭的字元串名字資訊。沒有這樣一個特殊的節頭的話這個值就是0

待續…

繼續閱讀