菜鳥筆記之PWN入門(1.1.0)ELF 檔案格式和程式段解析(簡版)

XiDP發表於2024-09-18

ELF (Executable and Linkable Format): 是一種用於 可執行檔案目標檔案 的檔案格式,類似於 Windows 下的 PE 檔案格式。

ELF 主要包括三種型別的檔案:

  • 可重定位檔案 (relocatable): 編譯器和彙編器產生的 .o 檔案,由 Linker 處理。
  • 可執行檔案 (executable): Linker.o 檔案進行處理後輸出的檔案,代表程序映像。
  • 共享物件檔案 (shared object): 動態庫檔案,通常是 .so 檔案。

ELF 檔案包含多個段,每個段承擔不同的作用。以下是一些入門級 PWN 可能需要用到的段(僅介紹這些基本段):

  1. .text: 用於儲存程式中的程式碼片段。
  2. .data: 用於儲存已經初始化的全域性變數和區域性變數。
  3. .bss: 用於儲存未初始化的全域性變數和區域性變數。
  4. .plt: 用於連結和跳轉到對應的 .got 表。
  5. .got.plt: 儲存對應函式的真實地址的表。
  6. .rodata: 只讀資料
  7. .init: 程式初始化和終止的程式碼

ELF 檔案中的段在程式執行前會被載入到記憶體中,然後在計算機記憶體中
一個程式可以認為由bss段data段text段三個部分組成的。
text段data段都存在可執行檔案當中,程式執行時,系統從可執行檔案中載入至記憶體
bss段在可執行檔案中只是一個符號用於佔位,由系統根據其符號進行初始化

如何載入:

.text 段

  • 程式碼段 (code segment): 用來存放 程式執行的程式碼
  • 這個段的大小在程式執行之前就已經確定,因為編譯好的程式程式碼量一般是固定的。
  • 該段通常有讀和執行許可權,但一般禁止修改(當然,也有部分特殊架構允許修改程式碼段)。
  • 在程式碼段中,可能也包含一些常數變數,例如字串。

.data 段

  • 資料段 (data segment): 用來存放已經 初始化的全域性變數
  • 資料段屬於靜態記憶體分配,即被程式分配後大小不再改變。

例子:

#include <stdio.h>
int str[30] = "i_am_xidp_and_i_love_pwn";
int main() {
    printf("%s", str);
    return 0;
}

在上述例子中,已經被賦值好的資料 str 會被放在 .data 段中。由於其大小是固定的,因此 .data 段中的資料也是固定大小的。

.bss 段

  • bss 段 (bss segment): 用於存放程式中未初始化的全域性變數。
  • .data 段一樣,屬於靜態記憶體分配。

例子:

#include <stdio.h>
int str[30];
int main() {
    scanf("%s", str);
    printf("%s", str);
    return 0;
}

.bss 段本身不會佔用 ELF 檔案的實際大小,它在 ELF 等可執行檔案中只是一個符號用於佔位。程式執行時,會根據這個符號在計算機中分配相應的記憶體大小。

資料區: .data 段和 .bss 段通常被稱為資料區。

參考文獻:
Linux可執行檔案格式-ELF結構詳解 - 我叫平沢唯 - 部落格園 (cnblogs.com)
PWN入門(1-1-2)-bss段、data段、text段、堆(heap)和棧(stack) (yuque.com)

相關文章