Windows PE文件格式

在PE文件頭以前

理論

Windows的PE(Portable Executable)文件有兩個頭,一個是是Windows頭,一個是DOS頭。在文件的最開始會有一段DOS的EXE文件頭,來講明這個程序不能夠在DOS環境下運行。咱們須要在DOS頭+3Ch處,會有一個4字節的指針指向windows頭。html

根據+3Ch處的值,定位到Windows文件頭能夠看到"PE"兩個字節,Windows頭就今後處開始。這也就是Windows EXE文件常常被稱爲PE文件的緣由。windows

實踐

  1. 在xp環境下,用QuickView打開一個EXE文件,觀察其頭部。
    • 在00h處有兩個字節4D 5A表示這是一個DOS頭。
    • 在4Eh處,有一個字符串This program cannot be run in DOS mode. 代表這不是一個DOS文件
    • 在3C處,有一個四字節指針,其值爲000000D0h,顏色標黃,指向windows頭

  1. 查看文件地址D0處的值學習

    能夠看到此處的兩個字節爲50 45即「PE」,表示這個EXE文件是一個PE文件,從這兩個字節開始纔是PE的文件頭。ui

PE文件頭

背景知識

要了解PE文件頭的具體內容,咱們須要對Windows的內存管理,文件存儲有必定的瞭解。接下來作簡要的說明,想要了解更詳細的內容能夠去學習操做系統的相關知識。操作系統

Windows經過分段以及分頁兩種機制管理內存和實現進程的隔離及保護。如下說明會涉及到一些寄存器和比較抽象的概念,不懂也沒有關係。只須要知道結論,*一個進程的虛擬地址會通過一些轉換成爲真正的物理地址. *進程之間的虛擬地址能夠相同,但相同的虛擬地址會轉化成不一樣的物理地址。指針

  • 在Windows系統中,爲了向下兼容,保留了分段(section)的的機制,可是CS,DS,SS這些段地址在GDT表中的值所有爲0,因此通過分段後的邏輯地址(logical address)與線性地址(linear address)是徹底一致的,在此處不用過多理會。
  • 對於分頁(paging)機制,每個進程都有一個屬於他們本身的頁目錄表,每個頁目錄表是不同的,線性地址須要通過頁表項的查詢,轉換成的真正的物理地址。因此對於不一樣進程而言,相同的線性地址會轉化成爲不一樣的物理地址。

有了分頁的機制後,windows的exe在運行時統一被載入內存的基地址=400000hcode

在PE文件頭中出現的內存地址都是以RVA(relative virtual address)相對虛擬地址的形式表示的,即htm

程序真正的虛擬地址 = 相對虛擬地址+載入內存的基地址=RVA+400000hblog

PE文件頭的具體內容

有了上述的瞭解後,接下來咱們來看PE文件頭的具體內容。如下的描述涉及到的偏移地址均爲16進制,且均相對於PE文件頭。進程

以一個EXE文件的PE頭爲例,咱們來講明,PE文件頭一些重要的項的具體含義。

000000d0: 5045 0000 4c01 0300 2fe6 a25d 0000 0000  PE..L.../..]....
			  |
		          +------------------------------- +06 用兩個字節來保存段的數量,此時爲0003個段
000000e0: 0000 0000 e000 0f01 0b01 0600 0050 0000  .............P..
000000f0: 0050 0000 0000 0000 4510 0000 0010 0000  .P......E.......
				|
				+------------------------- +28 程序的32位入口地址,即當前EXE在運行時,																													第一條指令執行的相對虛擬地址
00000100: 0060 0000 0000 4000 0010 0000 0010 0000  .`....@.........
		      |		|	    |
		      |		|	    +------------- +3C 文件對齊,兩個字節,此處爲1000h
		      |		+------------------------- +38 內存對齊,兩個字節,此處爲1000h
		      |				
		      +----------------------------------- +34 程序載入內存的基地址,4個字節EXE通常上都爲400000h																												
00000110: 0400 0000 0000 0000 0400 0000 0000 0000  ................
00000120: 00b0 0000 0010 0000 0000 0000 0300 0000  ................
	    |	      |
            |	      |
            |	      +---------------------------------- +54 EXE文件頭的文件長度(通過文件對齊以後),載入內存後會進行內存對齊(包括DOS頭和Windows頭)
            |                                                                                          																				 					
            +-------------------------------------------- +50 EXE文件載入內存後的總長度=文件頭+各個section載入內存後的總長度(通過內存對齊後)
  • 在PE+F8處定義了各個section的描述,每個節的描述的大小爲28h字節,在QV中查看具體的值以下:

  • PE+F8+0: 節名,8字節,以00做爲結束標記
  • PE+F8+8:節的內存長度 4980h
  • PE+F8+C:節的內存偏移 1000h
  • PE+F8+10: 節的文件長度 5000h
  • PE+F8+14: 節的文件偏移 1000h
  • PE+F8+24: 節的屬性,read,write,execute

關於PE文件頭中的輸出表、輸入表、資源表、重定位表的描述比較複雜,會另寫文檔講述。

輸出表:To do...

輸入表:Windows PE文件的輸入表

重定位表:To do...

隨筆是我的學習的總結,若有錯誤歡迎指出!

相關文章
相關標籤/搜索