PE格式解析-NT頭與地址換算

PE文件格式是什麼?
在Windows下,我們使用的exe、dll等文件都是使用的PE文件格式。當我們雙擊一個exe文件的時候,OS是根據PE格式來知道文件裏面的代碼以及數據的分佈的。

1、瞭解文件偏移地址、虛擬地址、相對虛擬地址
文件偏移地址:數據在文件內相對於文件頭的偏移
虛擬地址(VA):數據(代碼以及真正的data)加載到內存後,在內存裏面的地址
相對虛擬地址(RVA):數據(代碼以及真正的data)加載到內存後,其中的一條指令或數據相對於VA的地址

2、文件偏移地址與相對虛擬地址相同嗎?
答案是:不相同
瞭解這個之前,我們先來了解下文件對齊值與內存對齊值(塊對齊值)

文件的對齊值大小:200h,也就是512字節。因爲硬盤的一個扇區大小爲512字節,設置文件對齊值爲512字節是爲了提升硬盤的工作效率(對於所有的硬盤驅動來說,都是以一個扇區來進行讀寫,每次發一個信號要讀取數據的時候,它最少讀取512字節數據)
例如:
我們的代碼段爲300字節時,在內存裏面佔用的空間爲512字節,剩餘的212字節填充爲0,湊足512字節,方便我們讀取出來的時候一次性讀寫,而不必再去識別這512字節裏面哪裏爲代碼段,哪裏爲數據段,一次提升操作硬盤的效率。
如果代碼段爲513字節,在硬盤上就會佔用1024個字節,剩餘的511字節爲0

內存對齊值大小:1000h,也就是4096字節。同文件的對齊值相似,只要你少於4096字節時,它都會佔用4096字節的空間,即時你只有一個字節,它也會佔用4096字節的空間

文件對齊值與內存對齊值(塊對齊值)
示意圖

通過以上了解,我們可以得知,文件偏移地址與相對虛擬地址是不相同的。首先,一個是在硬盤一個是在內存中,其次它們的對齊值不同導致了他們的偏移量也會不相同。我們可以看以下示意圖(注:圖中釋義不是來自於上圖的實際值)
對齊值

映像:文件被加載到內存後,才叫做一個映像。
我們不難發現,映像大小和實際文件的大小又不相同,畢竟內存裏面爲0x1000對齊,硬盤爲0x200對齊
(附屬一句:文件的實際大小與文件佔用空間的不相同的原因,因爲操作系統(OS)會對我們的文件進行一些屬性之類的標識,所以它們的大小不相同)

3、PE格式解析
推薦幾款解析PE文件的工具:WinHex、Stud_PE、LoadPE
PE文件一半

通過以上PE格式示意圖,使用WinHex+Stud_PE進行解析(對於區段及之後內容下次再解析)
解析1
註釋內容
這裏寫圖片描述

程序入口點RVA:程序被加載起來後,windows 執行的第一條指令“在內存中的地址”
起始RVA
基址:我們的應用程序應該被加載到內存的哪一片區域(如果使用的可變基址,操作系統在加載應用程序的時候,會進行基址的隨機變換)
通過兩次加載,我們不難看出,隨機基址導致每次程序加載到內存後的基址都不相同
這裏寫圖片描述

這裏寫圖片描述

4、文件偏移與RVA值的換算
首先我們要知道,PE格式裏面,大量採用的是RVA值,而此時如果我沒有將程序(一個PE文件)加載到內存的時候,我是怎麼知道它的RVA值呢?
要求:轉換一個內存地址RVA到一個文件的偏移是多少,怎麼實現?
1、把PE文件中的所有區段信息全部讀取出來
2、RVA屬於哪一個區段
3、RVA - RVA(用需要查找的RVA減去整個區段頭的RVA,
計算出指定的內存地址相對於區段頭的偏移量) + File offset(區段頭在文件裏面的偏移)
(區段:就是.text、.data等段,下次再詳細解釋)
區段
舉個例子:
如果此時我的RVA值爲1014,那麼文件偏移爲多少?
1、.text段的RAV(VirtualOffset)爲1000,大小爲4B48字節,明顯我們的1014屬於這個範圍。對於的.text段的文件偏移(RawOffset)爲400.
2、(1014-1000)+ 400 = 414,這就是我們的文件偏移值
這裏寫圖片描述
注:虛擬地址爲基址加上相對虛擬地址,而第一張圖或者PE文件的解析中我們可以發現,基址爲400000,所以虛擬地址爲400000+1014=101014.

本文難免有所錯誤,如有問題歡迎留言

發佈了54 篇原創文章 · 獲贊 38 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章