VA
是絕對位置
RVA
是由基準位置後的相對位置
並且可以這樣換算 : VA + ImageBase = RVA
而 PE Header
中通常以 RVA
標記位置訊息。
PE檔解析
我們先上一份看起來很簡單的表
這四個區塊代表著在 PE 檔中的內容分區。而不同的區塊有不同功能,存放各自任務需要的資料。
DOS Header
: 開頭有一個校驗碼。在 windows NT
架構中大多數欄位用不到了,但是裡面有放 NT Header
的起點位置偏移量 ( 工具人的概念 )。NT Header
: 開頭也有一個校驗碼。可以再分成 File header
跟 Optional header
,裡面放著要裝載程式所需要的準備與檔案資料。Section Header
: 標示出 DATA
部分的資訊,讓編譯器可以知道資料有幾個區塊與資料的位置在哪裡。Section Data
: 這邊放著我們寫的資料,像是 .text
.data
.idata
等等的。好,現在讓這表現出原形。
雖然看起來很複雜,但不過就是上面那幾個區塊的內容,我們來看這些區塊的內容有甚麼含意。
這個部分一開始會有一個校驗碼
( Magic number
) ,一定會是 4D 5A 00 00
( M Z 0 0 )。
然後中間這些不用管,那個現在不重要。
其實 Windows NT 之前 Win 是基於 DOS系統,為了向前兼容所以才保留這個格式。
然後在 0x3C
的位置有標示 NT Header
的位置( RVA
),依據這個位置就可以找到 NT Header
。
看看在 winnt.h
中這個結構長甚麼樣
裡面的 e_magic
是校驗碼,e_lfanew
是 NT Header
的 RVA
(文件偏移)同時也是 FOA
(檔案位置) ,要記起來。
這個部分一開始也會有一個校驗碼
,一定會是 50 45 00 00
( P E 0 0 )。
裡面三個物件 : 校驗碼
、FileHeader
、OptionalHeader
。
這個部分在生成 COFF
檔案時就出現了,記錄編譯時的訊息。
其中這些的意思 :
Machine
機械碼類型,像我是 8664
對應 AMD64
NumberOfSections
代表 Section
中有幾個塊狀區塊
TimeDateStamp
編譯時的時間
SizeOfOptionalHeader
就是 OptionHeader
的大小
Characteristics
紀錄 PE 模組屬性,可以透過 value
來得知意義
包含連接器補上的紀錄資訊,使 application loader
可以正確裝載程式
有夠長,列出重要的部分 :
ImageBase
: PE model
應該要被寫在哪個位置上
Size of Image
: 這程式要申請多大的記憶體
SizeOfHeaders
: [DOS + NT + Selection] header
有多大
AddressOfEntryPoint
: 程式進入點
,也就是 EP,很重要
SectionAlignment
: 動態區段
對齊大小
FileAlignment
: 靜態區段
對齊大小
DataDirectory
: 這是一個 list
, 紀錄 15 種可能需要的資料的起始與大小。
附上他的結構
NT Header
到這邊結束,接下來是 Section
。
在編譯時編譯器把程式碼轉成很多塊,為了記錄這些塊狀資料的資訊所以有了 Section Header
。
看起來很容易理解。首先可以看到很多個區塊,這些區塊的數量在 NT Header -> FileHeader . NumberOfSections
可以得到。
PointerToRawData
: 這個 Block
在靜態檔案
的偏移量
SizeOfRawData
: Block
所使用的空間
VirtualAddress
: 寫入 Image base
的偏移量,也就是 page
中的 Offset
。
VirtualSize
: 動態空間所需要分配的空間
Characteristics
: 紀錄空間在編譯時該區段的使用權限 ( 讀 / 寫 / 執行 )。