ELF檔案格式第三講,節頭(section header)
ELF檔案格式第三講,節頭(section header)
一丶節頭
1.1 概念簡介
段(segment) 和 節(section)是有區別的。 節不是段。 段是程式執行的必要組成部分。 在每個段中會有程式碼或者資料被劃分為不同的節。 而 節頭表 則是對這些節的位置和大小的描述,主要是用於連結和除錯。
因為節頭表沒有對程式的記憶體佈局進行描述,對程式記憶體佈局的描述的是 程式頭表(第二講)的任務。 所以
節頭表就是對程式頭的補充。所以我們將“節頭表”都填充為無用的值的話程式還是可以正常啟動的。 雖然可以修改,但是隨著版本的升級,保不準以後會使用。 就跟window平臺上的最小PE一樣,在xp下可以是100kb以下。win7下則對各個表的限制更嚴格了。所以需要100kb以上。 win10同理。 所以節頭表以後可能會使用。
readelf -l 顯示一個段對應有那些節。 很直觀的可以看到節和段的關係。
readelf -S
...... Section to Segment mapping: 段節... 00 01 .interp 02 .interp .note.gnu.build-id .note.gnu.property .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt 03 .init .plt .text .fini 04 .rodata .eh_frame_hdr .eh_frame 05 .init_array .fini_array .dynamic .got .got.plt .data .bss 06 .dynamic 07 .note.gnu.build-id .note.gnu.property .note.ABI-tag 08 .note.gnu.property 09 .eh_frame_hdr 10 11 .init_array .fini_array .dynamic .got
1.2 節頭和節
如果二進位制檔案中缺少了 節頭 ,並不意味著節是不存在的。只是沒有辦法通過節頭來引用節了,對於偵錯程式或者反編譯(IDA)程式來說,參考的資訊就變少了。
每一個節都儲存了某種型別的程式碼和資料。 資料可以是程式中的全域性變數,也可以是聯結器所需要的動態連結的資訊。 這點跟windows平臺的 windowsPE檔案格式設計很像。 節頭可以被抹除,預設的ELF檔案是有節頭的。
如果節頭被抹除,那麼 objcopy objdump gdb IDA 等工具就可能無法使用。
而節頭表中的 .dynsym這樣的節(記錄了函式名和偏移地址,匯入匯出等符號)就無法分析。進而就增大了逆向的難度。
1.3 節頭 結構
- 結構
/* Section Header */
typedef struct {
Elf32_Word sh_name; /* name - index into section header
string table section */
Elf32_Word sh_type; /* type */
Elf32_Word sh_flags; /* flags */
Elf32_Addr sh_addr; /* address */
Elf32_Off sh_offset; /* file offset */
Elf32_Word sh_size; /* section size */
Elf32_Word sh_link; /* section header table index link */
Elf32_Word sh_info; /* extra information */
Elf32_Word sh_addralign; /* address alignment */
Elf32_Word sh_entsize; /* section entry size */
} Elf32_Shdr;
typedef struct {
Elf64_Half sh_name; /* section name */
Elf64_Half sh_type; /* section type */
Elf64_Xword sh_flags; /* section flags */
Elf64_Addr sh_addr; /* virtual address */
Elf64_Off sh_offset; /* file offset */
Elf64_Xword sh_size; /* section size */
Elf64_Half sh_link; /* link to another */
Elf64_Half sh_info; /* misc info */
Elf64_Xword sh_addralign; /* memory alignment */
Elf64_Xword sh_entsize; /* table entry size */
} Elf64_Shdr;
- 欄位含義如下
索引為0的表是 (SHN_UNDEF) 儘管這個表的意義是未定義的節區應用。
這個節區固定的值為如下:
010Edit中的取值為如下:
-
欄位型別
型別定義結果如下
-
sh_flag欄位
此欄位定義了一個節區中包含的內容是否可以修改,是否可以執行的資訊。 如果一個標誌位被設定,則該位取值為1. 定義的各位都設定為0
SHF_EXECINSTR: 節區包含可執行的機器指令。
SHF_MASKPROC: 所有包含於刺眼嗎中的四位都用於處理器專用的語義
在32 or 64下欄位還增加了
typedef enum <Elf32_Xword> {
SF32_None = 0x0, 無
SF32_Exec = 0x1, 執行
SF32_Alloc = 0x2, 此節區執行過程中佔用記憶體。某些控制接續並不會出現於目標檔案的記憶體映像中,對於那些節區此值為0
SF32_Alloc_Exec = 0x3,
SF32_Write = 0x4, 寫
SF32_Write_Exec = 0x5, 寫執行
SF32_Write_Alloc = 0x6, 寫記憶體
SF32_Write_Alloc_Exec = 0x7
} s_flags32_e;
typedef enum <Elf64_Xword> {
SF64_None = 0x0,
SF64_Exec = 0x1,
SF64_Alloc = 0x2,
SF64_Alloc_Exec = 0x3,
SF64_Write = 0x4,
SF64_Write_Exec = 0x5,
SF64_Write_Alloc = 0x6,
SF64_Write_Alloc_Exec = 0x7
} s_flags64_e;
-
節區型別於欄位
根據節區型別的不同,那麼s_link s_info也是不同的。
如下表
1.4特殊節區
下圖是系統中使用的節區以及他們的型別和屬性。 簡單概括圖。