PE教程3: File Header (檔案頭)

看雪資料發表於2015-11-15

 

PE教程3: File Header (檔案頭)

本課我們將要研究 PE header file header(檔案頭)部分。

至此,我們已經學到了哪些東東,先簡要回顧一下:

  • DOS MZ header 又命名為 IMAGE_DOS_HEADER.。其中只有兩個域比較重要: e_magic 包含字串"MZ"e_lfanew 包含PE header在檔案中的偏移量。
  • 比較e_magic 是否為IMAGE_DOS_SIGNATURE以驗證是否是有效的DOS header。比對符合則認為檔案擁有一個有效的DOS header
  • 為了定位PE header,移動檔案指標到e_lfanew所指向的偏移。
  • PE header的第一個雙字包含字串"PE\0\0"。該雙字與IMAGE_NT_SIGNATURE比對,符合則認為PE header有效。

本課我們繼續探討關於 PE header 的知識。 PE header 的正式命名是 IMAGE_NT_HEADERS。再來回憶一下這個結構。

IMAGE_NT_HEADERS STRUCT
    Signature dd ?
    FileHeader IMAGE_FILE_HEADER <>
    OptionalHeader IMAGE_OPTIONAL_HEADER32 <>
IMAGE_NT_HEADERS ENDS

Signature PE標記,值為50h, 45h, 00h, 00hPE\0\0)。
FileHeader 該結構域包含了關於PE檔案物理分佈的一般資訊。
OptionalHeader 該結構域包含了關於PE檔案邏輯分佈的資訊。

最有趣的東東在 OptionalHeader 裡。不過,FileHeader 裡的一些域也很重要。本課我們將學習FileHeader下一課研究OptionalHeader

IMAGE_FILE_HEADER STRUCT
    Machine WORD ?
    NumberOfSections WORD ?
    TimeDateStamp dd ?
    PointerToSymbolTable dd ?
    NumberOfSymbols dd ?
    SizeOfOptionalHeader WORD ?
    Characteristics WORD ?
IMAGE_FILE_HEADER ENDS

Field nameMeanings
Machine該檔案執行所要求的CPU。對於Intel平臺,該值是IMAGE_FILE_MACHINE_I386 (14Ch)。我們嘗試了LUEVELSMEYERpe.txt宣告的14Dh14Eh,但Windows不能正確執行。看起來,除了禁止程式執行之外,本域對我們來說用處不大。
NumberOfSections 檔案的節數目。如果我們要在檔案中增加或刪除一個節,就需要修改這個值。
TimeDateStamp檔案建立日期和時間。我們不感興趣。
PointerToSymbolTable用於除錯。
NumberOfSymbols用於除錯。
SizeOfOptionalHeader指示緊隨本結構之後的 OptionalHeader 結構大小,必須為有效值。
Characteristics關於檔案資訊的標記,比如檔案是exe還是dll

簡言之,只有三個域對我們有一些用: Machine, NumberOfSections Characteristics。通常不會改變 Machine Characteristics 的值,但如果要遍歷節表就得使用 NumberOfSections
為了更好闡述 NumberOfSections 的用處,這裡簡要介紹一下節表。

節表是一個結構陣列,每個結構包含一個節的資訊。因此若有3個節,陣列就有3個成員。 我們需要NumberOfSections值來了解該陣列中到底有幾個成員。 也許您會想檢測結構中的全0成員起到同樣效果。Windows確實採用了這種方法。為了證明這一點,可以增加NumberOfSections的值,Windows仍然可以正常執行檔案。據我們的觀察,Windows讀取NumberOfSections的值然後檢查節表裡的每個結構,如果找到一個全0結構就結束搜尋,否則一直處理完NumberOfSections指定數目的結構。 為什麼我們不能忽略NumberOfSections的值? 有幾個原因。PE說明中沒有指定節表必須以全0結構結束。Thus there may be a situation where the last array member is contiguous to the first section, without empty space at all. Another reason has to do with bound imports. The new-style binding puts the information immediately following the section table's last structure array member. 因此您仍然需要NumberOfSections

翻譯:iamgufeng [Iczelion's Win32 Assembly Homepage][LuoYunBin's Win32 ASM Page]

 

相關文章