快轉到主要內容

《Pwn - 0x02》What did the "Compilation" do? And what is ELF?

·6890 字
Computer-Science Pwn
目錄
PWN - 本文屬於一個選集。
§ : 本文

Compiling
#

在過去,計算機概論課程中,講者及教材上往往會這麼解釋高階語言執行檔的過程:

計概所說的編譯過程
計概所說的編譯過程

但事實上,該過程可以被拆解成更詳細的步驟,如下圖:

更詳細的編譯過程
更詳細的編譯過程

東西突然有點多,先大致說明一下表示方式:

  • (虛線):使用或透過什麼工具。
  • (箭頭):所產生的結果。

顏色表示對象:

  • 紫色區域:編譯過程的前後,也表示開頭與結尾。
  • 黃色區域:所使用的工具,通常工具本身也是程式。
  • 藍色區域:檔案的各個階段。

這兩項會再特別提出說明:

  • 綠色區域:執行檔。
  • 橘色區域:Loader (載入器),用於將程式傾印到記憶體上的程式。

先從最左上角紫色區域 開始觀看:

1. 撰寫 Source Code
#

Developer (開發者)透過Editor (編輯器)撰寫程式(高階語言),此刻的檔案為Source Code (原始碼)。該步驟應該撰寫過程式的都不陌生。

2. 產生優化後的 Source Code
#

接著當你開始嘗試編譯該檔案時,其實當下並非直接編譯,而是會先透過一個叫做「Preprocessor (預處理器)」的程式對 Source Code 進行優化,刪除原始碼中的Comment (註解)(程式執行是不需要註解的),並將其中所使用到的Library (函式庫)檔案路徑給標記上去,方便後續連結程式。而透過Preprocessor處理後所產生的檔案稱為「Expanded Source Code」,其檔案內容大概長這個樣子(此刻對觀看已經非常不友善了):

3. 編譯成 Assembly Language
#

接著就透過Compiler (編譯器)對優化過的原始檔進行Compile (編譯),之後產出Assembly Language (組合語言)檔案。其檔案內容大致長這樣(對於只寫過高階語言的朋友來說,應該已經進到另外一個領域了):

4. 組譯成 Object File
#

已經有了Assembly Language (組合語言)檔案,那麼就可以透過Assembler (組譯器)翻譯成Machine Code (機器語言),而在Assemble (組譯)Executable (執行檔)之前,其實還可以分成兩個步驟。在開始組譯後,會先產生出「Object File (目的檔)」,該檔案已經是Binary了,而Object File中會標記著各種所需要的Library (函式庫)位置,此刻的Library還並未被整合成一個檔案。除此之外,該檔案裡頭還會存放前一章提到檔案中的各種區段,包括.text.data.rodata.bss等,但在這邊,正確來說應該稱呼它們為「Sections」,而不是「Segments」,這部份稍後再提,只要先知道這是指一樣的東西即可。此刻檔案中已經包含各個Section的資料,也就是說程式主體已經都被轉成Binary了,距離完成只差最後一步,就是將Library也整合進來。

5. 連結成 Executable
#

為了完成最後整合Library的步驟,因此就有了Linker (連結器)。舉例在Ubuntu 20OS 下,沒意外的話Linker位置會在「/lib/ld-linux.so.2」,而這只是一個捷徑,該捷徑所指向的檔案才是真正的Linker,但每台裝置所使用的 Linker 來源或是版本可能不同,例如我的捷徑連結至「/lib/i386-linux-gnu/ld-2.31.so」。到了編譯的最後一步,將Object File與那些Library統整成一個可執行檔,當然Object File可能包含數個,一樣可以進行合併,最後產生出Executable (執行檔)

6. Loader
#

到目前為止,Executable已經被生產出來。
儘管已經在第五步驟Library給連結了,但… 並不代表程式全部都會被合併

在一般廣義上的Link (連結)可以被分成兩種來看,一種是「Static Linking (靜態連結)」,另外一種則是「Dynamic Linking (動態連結)」。這主要關聯到Library中的「Statically-Linked Library (靜態連結函式庫)」及「Dynamic-Link Library (動態連結函式庫)」:

  • Statically-Linked Library (靜態連結函式庫)
    • LinuxOS 上,靜態庫本身包含著ELF檔案,但自身並非ELF檔案,通常為「.a」副檔名,表示「Archive」,如同字面上的意思,如果 ELF 是書的話,那他就是裝書的書櫃。其內容多半較為簡單,無複雜操作,過於複雜、龐大的程式更適合以動態連結的方式進行,以避免最終產出的執行檔過大
    • 在透過Linker連結的過程中會被合併至Object File當中。
  • Dynamic-Link Library (動態連結函式庫)
    • 靜態連結函式庫最大的不同在於,動態連結函式庫並不會被直接整合到執行檔中,Um… 至少在Linking階段不會。
    • 由於不會預先被整合進執行檔,因此要求各個環境之間需擁有相同函式庫才能夠在開啟執行檔時被預期的載入相關程式碼。
    • WindowsOS 中常見的.dll檔便是「Dynamic-Link Library」的縮寫。

從上述內容可以發現,動態庫在執行檔生成的連結過程中,僅僅是被作為標記使用,而真正的程式碼則是在程式啟動時才被載入,並且若開發人員使用的動態函式庫在使用者環境上沒有或是版本有著差異,那將可能無法順利執行程式

其實說到這已經很明顯了,Loader指的正是用於在程式啟動時,協助載入動態庫的程式。

至於… 前面提到的「ELF」是什麼?


What is ELF?
#

ELF」為一種檔案格式,全稱為「Executable and Linkable Format (可執行與可連結格式)」,在過去也被稱作「Extensible Linking Format」,是一種Unix的執行檔格式。

ELF檔案主要有三種類型,分別是「Executable (執行檔)」、「Object File (目的檔)」、「Shared Object (動態鏈接庫、共享庫)」。

  • Executable:在前面已經提到了,這也應該是大家最為熟悉的。在LinuxOS 下副檔名多半為.out無附檔名等。
  • Object File:又稱作「Relocatable」,前面提到時沒說到,但Object File也是ELF檔案。在LinuxOS 下副檔名多半為.o
  • Shared Object:又稱作「Shared Library」,其實與Executable大致相同,最大差異僅僅是Shared Object可用於共享,時常用於程式動態連結階段被Loader連結的子程式,而Executable則通常不被當子程式使用,除此之外… 似乎是一樣的,總之就… 都是執行檔。在LinuxOS 下副檔名多半為.so

ELF檔案是可以被大致分成四塊區域來看的,分別是:

ELF Header
#

作為檔頭當然就是紀錄著檔案的一些基本資訊啦!
包含標示著該檔案是 ELF;是什麼類型的 ELF;為幾位元系統執行檔;版本;記憶體資料存放方式(Little-or-Big Endian)… 等。
當然也包括標注Program HeaderSection Header Table在檔案中的位置,這麼一來就可以透過該檔頭定位所有區塊了。
舉例,我有一執行檔名為「hello-word」,透過指令「readelf -h hello-world」即可查看該檔案的Header

 1ELF Header:
 2  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
 3  Class:                             ELF64
 4  Data:                              2's complement, little endian
 5  Version:                           1 (current)
 6  OS/ABI:                            UNIX - System V
 7  ABI Version:                       0
 8  Type:                              DYN (Shared object file)
 9  Machine:                           Advanced Micro Devices X86-64
10  Version:                           0x1
11  Entry point address:               0x10a0
12  Start of program headers:          64 (bytes into file)
13  Start of section headers:          12616 (bytes into file)
14  Flags:                             0x0
15  Size of this header:               64 (bytes)
16  Size of program headers:           56 (bytes)
17  Number of program headers:         13
18  Size of section headers:           64 (bytes)
19  Number of section headers:         29
20  Section header string table index: 28

這些資訊倒也不用全都了解,但基本的要先知道就好。
從圖中可以看見,Header中有一個叫做Magic的數字串,又被稱作「Magic Number (魔法數字)」,佔了檔案最開頭的16 BytesMagic Number對於檔案辨識是重要的一個指標,這些數字也被統稱「EI_IDENT」。

Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00

  • 0x00 ~ 0x03(EI_MAG0 ~ EI_MAG3):開頭的「7f」同時也是執行檔中的第一個字節,表記著該檔案是可執行檔。接著的「45」、「4c」、「46」表示著格式,也就是「ELF」三個英文字所個別對應的ASCII Code
  • 0x04(EI_CLASS):。欲執行檔案的系統位元,目前大多是使用0x02,也就是64-Bits,而0x01表示32-Bits。(為什麼沒有16-Bits呢?詳情可以看這篇文章:「linux - Why there is no 16-bit information in ELF magic number? - Stack Overflow」)
  • 0x05(EI_DATA):資料於記憶體中的存放格式,大多數為0x01,代表Little-Endian,目前大多數系統都是採用這種格式的。而0x02則表示Big-Endian(關於 Big-Endian 更多資訊可以看這篇文章:「Big Endian 與他們的現狀 - HackMD」)。若是你還不懂Big-EndianLittle-Endian是什麼的話,也不用擔心,之後該系列文章提到時會再詳細說明。
  • 0x06(EI_VERSION):標示了ELF版本,但就目前應該只會看見0x01,也就是第一版本,未來可能會繼續更新也說不定。
  • 0x07(EI_OSABI):標記著「OS Application Binary Interface」,也就是該 ELF 檔案於何統作業系統上運作(至於什麼是ABI,可以看維基百科解釋:應用二進位介面 - Wiki)。而例子中該欄位值為「0x00」,表示未指定。
  • 0x08(EI_ABIVERSION):標示「Application Binary Interface Version」,意思是該 ELF 檔案所使用的ABI版本。(該字節可以為0x00,用以表示不指定版本)
  • 0x09 ~ 0x15(EI_PAD):僅僅是用於「Padding (填充)」,剛好湊個 2 的次方數(16 Bytes),也是給未來的版本預留資訊的儲存空間。

至於這些資訊,剛才所說的指令會自動將這些資訊整理成文字顯示,各位就不用辛苦的記憶對應的意思了,例如上面終端輸出的這段:

1Class:                             ELF64
2Data:                              2's complement, little endian
3Version:                           1 (current)
4OS/ABI:                            UNIX - System V
5ABI Version:                       0
6Type:                              DYN (Shared object file)
7Machine:                           Advanced Micro Devices X86-64
8Version:                           0x1

Program Header
#

接著是Program Header
該區塊用於存放關於執行檔於執行時的必要資訊,包含動態連結函式庫為何、各個Segments對應Sections的分佈、Segments的權限(是否可讀/寫/執行…)等。
一樣拿hello-world這支檔案舉例,透過指令「readelf -l hello-world」可以查看檔案的Program Header

 1Elf file type is DYN (Shared object file)
 2Entry point 0x10a0
 3There are 13 program headers, starting at offset 64
 4
 5Program Headers:
 6  Type           Offset             VirtAddr           PhysAddr
 7                 FileSiz            MemSiz              Flags  Align
 8  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
 9                 0x00000000000002d8 0x00000000000002d8  R      0x8
10  INTERP         0x0000000000000318 0x0000000000000318 0x0000000000000318
11                 0x000000000000001c 0x000000000000001c  R      0x1
12      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
13  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
14                 0x0000000000000790 0x0000000000000790  R      0x1000
15  LOAD           0x0000000000001000 0x0000000000001000 0x0000000000001000
16                 0x00000000000002a5 0x00000000000002a5  R E    0x1000
17  LOAD           0x0000000000002000 0x0000000000002000 0x0000000000002000
18                 0x00000000000001b0 0x00000000000001b0  R      0x1000
19  LOAD           0x0000000000002d88 0x0000000000003d88 0x0000000000003d88
20                 0x0000000000000288 0x00000000000003d0  RW     0x1000
21  DYNAMIC        0x0000000000002da0 0x0000000000003da0 0x0000000000003da0
22                 0x0000000000000200 0x0000000000000200  RW     0x8
23  NOTE           0x0000000000000338 0x0000000000000338 0x0000000000000338
24                 0x0000000000000020 0x0000000000000020  R      0x8
25  NOTE           0x0000000000000358 0x0000000000000358 0x0000000000000358
26                 0x0000000000000044 0x0000000000000044  R      0x4
27  GNU_PROPERTY   0x0000000000000338 0x0000000000000338 0x0000000000000338
28                 0x0000000000000020 0x0000000000000020  R      0x8
29  GNU_EH_FRAME   0x0000000000002014 0x0000000000002014 0x0000000000002014
30                 0x0000000000000054 0x0000000000000054  R      0x4
31  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
32                 0x0000000000000000 0x0000000000000000  RW     0x10
33  GNU_RELRO      0x0000000000002d88 0x0000000000003d88 0x0000000000003d88
34                 0x0000000000000278 0x0000000000000278  R      0x1
35
36 Section to Segment mapping:
37  Segment Sections...
38   00     
39   01     .interp 
40   02     .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt 
41   03     .init .plt .plt.got .plt.sec .text .fini 
42   04     .rodata .eh_frame_hdr .eh_frame 
43   05     .init_array .fini_array .dynamic .got .data .bss 
44   06     .dynamic 
45   07     .note.gnu.property 
46   08     .note.gnu.build-id .note.ABI-tag 
47   09     .note.gnu.property 
48   10     .eh_frame_hdr 
49   11     
50   12     .init_array .fini_array .dynamic .got 

資訊很多,按部就班來讀,主要先找到「Program Headers:」,先單看這塊區域:

 1  Type           Offset             VirtAddr           PhysAddr
 2                  FileSiz            MemSiz              Flags  Align
 3  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
 4                  0x00000000000002d8 0x00000000000002d8  R      0x8
 5  INTERP         0x0000000000000318 0x0000000000000318 0x0000000000000318
 6                  0x000000000000001c 0x000000000000001c  R      0x1
 7      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
 8  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
 9                  0x0000000000000790 0x0000000000000790  R      0x1000
10  LOAD           0x0000000000001000 0x0000000000001000 0x0000000000001000
11                  0x00000000000002a5 0x00000000000002a5  R E    0x1000
12  LOAD           0x0000000000002000 0x0000000000002000 0x0000000000002000
13                  0x00000000000001b0 0x00000000000001b0  R      0x1000
14  LOAD           0x0000000000002d88 0x0000000000003d88 0x0000000000003d88
15                  0x0000000000000288 0x00000000000003d0  RW     0x1000
16  DYNAMIC        0x0000000000002da0 0x0000000000003da0 0x0000000000003da0
17                  0x0000000000000200 0x0000000000000200  RW     0x8
18  NOTE           0x0000000000000338 0x0000000000000338 0x0000000000000338
19                  0x0000000000000020 0x0000000000000020  R      0x8
20  NOTE           0x0000000000000358 0x0000000000000358 0x0000000000000358
21                  0x0000000000000044 0x0000000000000044  R      0x4
22  GNU_PROPERTY   0x0000000000000338 0x0000000000000338 0x0000000000000338
23                  0x0000000000000020 0x0000000000000020  R      0x8
24  GNU_EH_FRAME   0x0000000000002014 0x0000000000002014 0x0000000000002014
25                  0x0000000000000054 0x0000000000000054  R      0x4
26  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
27                  0x0000000000000000 0x0000000000000000  RW     0x10
28  GNU_RELRO      0x0000000000002d88 0x0000000000003d88 0x0000000000003d88
29                  0x0000000000000278 0x0000000000000278  R      0x1

在最上面標示了欄位名稱(有兩行),分別是「Type」、「Offset」、「VirtAddr」、「PhysAddr」、「FileSiz」、「MemSiz」、「Flags」、「Align」。
Program Header Table的結構可以在檔案「/usr/include/elf.h」中找到:

 1/* Program segment header.  */
 2
 3typedef struct
 4{
 5  Elf32_Word    p_type;                 /* Segment type */
 6  Elf32_Off     p_offset;               /* Segment file offset */
 7  Elf32_Addr    p_vaddr;                /* Segment virtual address */
 8  Elf32_Addr    p_paddr;                /* Segment physical address */
 9  Elf32_Word    p_filesz;               /* Segment size in file */
10  Elf32_Word    p_memsz;                /* Segment size in memory */
11  Elf32_Word    p_flags;                /* Segment flags */
12  Elf32_Word    p_align;                /* Segment alignment */
13} Elf32_Phdr;
14
15typedef struct
16{
17  Elf64_Word    p_type;                 /* Segment type */
18  Elf64_Word    p_flags;                /* Segment flags */
19  Elf64_Off     p_offset;               /* Segment file offset */
20  Elf64_Addr    p_vaddr;                /* Segment virtual address */
21  Elf64_Addr    p_paddr;                /* Segment physical address */
22  Elf64_Xword   p_filesz;               /* Segment size in file */
23  Elf64_Xword   p_memsz;                /* Segment size in memory */
24  Elf64_Xword   p_align;                /* Segment alignment */
25} Elf64_Phdr;

對照上面所看到的欄位可以發現是一樣的,並且在右方有著註解告知該欄位為 Segment 的什麼資訊。
這麼一來我們就可以知道各個欄位代表的是什麼了,接著先來看剛剛輸出的那些Type分別代表什麼,一樣在/usr/include/elf.h中可以找到如下資訊:

 1/* Legal values for p_type (segment type).  */
 2
 3#define PT_NULL         0               /* Program header table entry unused */
 4#define PT_LOAD         1               /* Loadable program segment */
 5#define PT_DYNAMIC      2               /* Dynamic linking information */
 6#define PT_INTERP       3               /* Program interpreter */
 7#define PT_NOTE         4               /* Auxiliary information */
 8#define PT_SHLIB        5               /* Reserved */
 9#define PT_PHDR         6               /* Entry for header table itself */
10#define PT_TLS          7               /* Thread-local storage segment */
11#define PT_NUM          8               /* Number of defined types */
12#define PT_LOOS         0x60000000      /* Start of OS-specific */
13#define PT_GNU_EH_FRAME 0x6474e550      /* GCC .eh_frame_hdr segment */
14#define PT_GNU_STACK    0x6474e551      /* Indicates stack executability */
15#define PT_GNU_RELRO    0x6474e552      /* Read-only after relocation */
16#define PT_LOSUNW       0x6ffffffa
17#define PT_SUNWBSS      0x6ffffffa      /* Sun Specific segment */
18#define PT_SUNWSTACK    0x6ffffffb      /* Stack segment */
19#define PT_HISUNW       0x6fffffff
20#define PT_HIOS         0x6fffffff      /* End of OS-specific */
21#define PT_LOPROC       0x70000000      /* Start of processor-specific */
22#define PT_HIPROC       0x7fffffff      /* End of processor-specific */

對照剛剛表中有的Type分別是:

  • PHDR Entry for header table itself
    Program Header,也就是該表本身的資訊。
  • INTERP Program interpreter
    基本上就是標記著要連結動態函式庫所使用的程式,以Linux來說就是之前所提到的/lib/i386-linux-gnu/ld-2.31.so
  • LOAD Loadable program segment
    要載入的區段,包含Text SegmentData Segment… 等。
  • DYNAMIC Dynamic linking information
    動態連結的相關資訊。
  • NOTE Auxiliary information
    只是輔助用的,此區是非必要的。
  • GNU_PROPERTY
    請自行閱讀linux-abi-draft.pdf 2.1.5的部份
  • GNU_EH_FRAME GCC .eh_frame_hdr segment
  • GNU_STACK Indicates stack executability
  • GNU_RELRO Read-only after relocation

最後這四項暫時不討論。

Sections
#

要查看hello-world這個檔案的Sections,可以使用指令「readelf -S hello-world」:

 1There are 29 section headers, starting at offset 0x3148:
 2
 3Section Headers:
 4  [Nr] Name              Type             Address           Offset
 5       Size              EntSize          Flags  Link  Info  Align
 6  [ 0]                   NULL             0000000000000000  00000000
 7       0000000000000000  0000000000000000           0     0     0
 8  [ 1] .interp           PROGBITS         0000000000000318  00000318
 9       000000000000001c  0000000000000000   A       0     0     1
10  [ 2] .note.gnu.propert NOTE             0000000000000338  00000338
11       0000000000000020  0000000000000000   A       0     0     8
12  [ 3] .note.gnu.build-i NOTE             0000000000000358  00000358
13       0000000000000024  0000000000000000   A       0     0     4
14  [ 4] .note.ABI-tag     NOTE             000000000000037c  0000037c
15       0000000000000020  0000000000000000   A       0     0     4
16  [ 5] .gnu.hash         GNU_HASH         00000000000003a0  000003a0
17       0000000000000028  0000000000000000   A       6     0     8
18  [ 6] .dynsym           DYNSYM           00000000000003c8  000003c8
19       0000000000000108  0000000000000018   A       7     1     8
20  [ 7] .dynstr           STRTAB           00000000000004d0  000004d0
21       0000000000000117  0000000000000000   A       0     0     1
22  [ 8] .gnu.version      VERSYM           00000000000005e8  000005e8
23       0000000000000016  0000000000000002   A       6     0     2
24  [ 9] .gnu.version_r    VERNEED          0000000000000600  00000600
25       0000000000000040  0000000000000000   A       7     2     8
26  [10] .rela.dyn         RELA             0000000000000640  00000640
27       0000000000000108  0000000000000018   A       6     0     8
28  [11] .rela.plt         RELA             0000000000000748  00000748
29       0000000000000048  0000000000000018  AI       6    24     8
30  [12] .init             PROGBITS         0000000000001000  00001000
31       000000000000001b  0000000000000000  AX       0     0     4
32  [13] .plt              PROGBITS         0000000000001020  00001020
33       0000000000000040  0000000000000010  AX       0     0     16
34  [14] .plt.got          PROGBITS         0000000000001060  00001060
35       0000000000000010  0000000000000010  AX       0     0     16
36  [15] .plt.sec          PROGBITS         0000000000001070  00001070
37       0000000000000030  0000000000000010  AX       0     0     16
38  [16] .text             PROGBITS         00000000000010a0  000010a0
39       00000000000001f5  0000000000000000  AX       0     0     16
40  [17] .fini             PROGBITS         0000000000001298  00001298
41       000000000000000d  0000000000000000  AX       0     0     4
42  [18] .rodata           PROGBITS         0000000000002000  00002000
43       0000000000000014  0000000000000000   A       0     0     4
44  [19] .eh_frame_hdr     PROGBITS         0000000000002014  00002014
45       0000000000000054  0000000000000000   A       0     0     4
46  [20] .eh_frame         PROGBITS         0000000000002068  00002068
47       0000000000000148  0000000000000000   A       0     0     8
48  [21] .init_array       INIT_ARRAY       0000000000003d88  00002d88
49       0000000000000010  0000000000000008  WA       0     0     8
50  [22] .fini_array       FINI_ARRAY       0000000000003d98  00002d98
51       0000000000000008  0000000000000008  WA       0     0     8
52  [23] .dynamic          DYNAMIC          0000000000003da0  00002da0
53       0000000000000200  0000000000000010  WA       7     0     8
54  [24] .got              PROGBITS         0000000000003fa0  00002fa0
55       0000000000000060  0000000000000008  WA       0     0     8
56  [25] .data             PROGBITS         0000000000004000  00003000
57       0000000000000010  0000000000000000  WA       0     0     8
58  [26] .bss              NOBITS           0000000000004040  00003010
59       0000000000000118  0000000000000000  WA       0     0     64
60  [27] .comment          PROGBITS         0000000000000000  00003010
61       000000000000002b  0000000000000001  MS       0     0     1
62  [28] .shstrtab         STRTAB           0000000000000000  0000303b
63       000000000000010a  0000000000000000           0     0     1
64Key to Flags:
65  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
66  L (link order), O (extra OS processing required), G (group), T (TLS),
67  C (compressed), x (unknown), o (OS specific), E (exclude),
68  l (large), p (processor specific)

可以看到除先前所介紹的.text.bss.data.rodata等 Sections 外,還多了許多 Sections。
至於其他未介紹的 Sections 作用為何,煩請讀者自行尋找相關資料,在此為防離題及篇幅過長不做討論。

另外,如同Program Header Table一樣,Section Header Table結構也能於檔案「/usr/include/elf.h」中找到:

 1/* Section header.  */
 2
 3typedef struct
 4{
 5  Elf32_Word    sh_name;                /* Section name (string tbl index) */
 6  Elf32_Word    sh_type;                /* Section type */
 7  Elf32_Word    sh_flags;               /* Section flags */
 8  Elf32_Addr    sh_addr;                /* Section virtual addr at execution */
 9  Elf32_Off     sh_offset;              /* Section file offset */
10  Elf32_Word    sh_size;                /* Section size in bytes */
11  Elf32_Word    sh_link;                /* Link to another section */
12  Elf32_Word    sh_info;                /* Additional section information */
13  Elf32_Word    sh_addralign;           /* Section alignment */
14  Elf32_Word    sh_entsize;             /* Entry size if section holds table */
15} Elf32_Shdr;
16
17typedef struct
18{
19  Elf64_Word    sh_name;                /* Section name (string tbl index) */
20  Elf64_Word    sh_type;                /* Section type */
21  Elf64_Xword   sh_flags;               /* Section flags */
22  Elf64_Addr    sh_addr;                /* Section virtual addr at execution */
23  Elf64_Off     sh_offset;              /* Section file offset */
24  Elf64_Xword   sh_size;                /* Section size in bytes */
25  Elf64_Word    sh_link;                /* Link to another section */
26  Elf64_Word    sh_info;                /* Additional section information */
27  Elf64_Xword   sh_addralign;           /* Section alignment */
28  Elf64_Xword   sh_entsize;             /* Entry size if section holds table */
29} Elf64_Shdr;

以及 Table 結構的解釋:

 1/* Legal values for sh_type (section type).  */
 2
 3#define SHT_NULL          0             /* Section header table entry unused */
 4#define SHT_PROGBITS      1             /* Program data */
 5#define SHT_SYMTAB        2             /* Symbol table */
 6#define SHT_STRTAB        3             /* String table */
 7#define SHT_RELA          4             /* Relocation entries with addends */
 8#define SHT_HASH          5             /* Symbol hash table */
 9#define SHT_DYNAMIC       6             /* Dynamic linking information */
10#define SHT_NOTE          7             /* Notes */
11#define SHT_NOBITS        8             /* Program space with no data (bss) */
12#define SHT_REL           9             /* Relocation entries, no addends */
13#define SHT_SHLIB         10            /* Reserved */
14#define SHT_DYNSYM        11            /* Dynamic linker symbol table */
15#define SHT_INIT_ARRAY    14            /* Array of constructors */
16#define SHT_FINI_ARRAY    15            /* Array of destructors */
17#define SHT_PREINIT_ARRAY 16            /* Array of pre-constructors */
18#define SHT_GROUP         17            /* Section group */
19#define SHT_SYMTAB_SHNDX  18            /* Extended section indeces */
20#define SHT_NUM           19            /* Number of defined types.  */
21#define SHT_LOOS          0x60000000    /* Start OS-specific.  */
22#define SHT_GNU_ATTRIBUTES 0x6ffffff5   /* Object attributes.  */
23#define SHT_GNU_HASH      0x6ffffff6    /* GNU-style hash table.  */
24#define SHT_GNU_LIBLIST   0x6ffffff7    /* Prelink library list */
25#define SHT_CHECKSUM      0x6ffffff8    /* Checksum for DSO content.  */
26#define SHT_LOSUNW        0x6ffffffa    /* Sun-specific low bound.  */
27#define SHT_SUNW_move     0x6ffffffa
28#define SHT_SUNW_COMDAT   0x6ffffffb
29#define SHT_SUNW_syminfo  0x6ffffffc
30#define SHT_GNU_verdef    0x6ffffffd    /* Version definition section.  */
31#define SHT_GNU_verneed   0x6ffffffe    /* Version needs section.  */
32#define SHT_GNU_versym    0x6fffffff    /* Version symbol table.  */
33#define SHT_HISUNW        0x6fffffff    /* Sun-specific high bound.  */
34#define SHT_HIOS          0x6fffffff    /* End OS-specific type */
35#define SHT_LOPROC        0x70000000    /* Start of processor-specific */
36#define SHT_HIPROC        0x7fffffff    /* End of processor-specific */
37#define SHT_LOUSER        0x80000000    /* Start of application-specific */
38#define SHT_HIUSER        0x8fffffff    /* End of application-specific */

References
#

Alpaca
作者
Alpaca
No one can stop my feet.
PWN - 本文屬於一個選集。
§ : 本文

相關文章

《Pwn - 0x01》Segments? Stack, Heap? .text, .data, .bss?
·2877 字
Computer-Science Pwn
《Pwn - 0x00》Hello, Pwn!
·674 字
Computer-Science Pwn

計算機領域中的「Pwn」是什麼意思?

How to set timezone on ubuntu?
·183 字
Computer-Science Ubuntu
PHP MySQL query with 「PDO」
·332 字
Computer-Science PHP SQL PDO MySQL

Don’t continue to use original MySQL functions in PHP, let’s try PDO !

How to use FFmpeg ?
·308 字
Computer-Science FFmpeg
Ubuntu 更改家目錄語言
·574 字
Computer-Science Ubuntu

簡單幾步變更家目錄的語言