在Dump PE File的section table時候,一開始選用RVA來計算section的地址,,以期望能取到Section信息,,后來發(fā)現(xiàn)不完全正確,應該用PointerToRawData的值,。
如果根據(jù)自己定義的內存對齊的值,,將FileAlignment和SectionAlignment設為相同的對齊方式,這個時候生成的PE文件,,RVA和PointerToRawData的值指向同一個地址,,此時要取到Section的信息,,用RVA也可以,因為值是一樣的,。但是從意義上來說不完全正確,。 一般生成的PE文件,假設FileAlignment = 200 Byte; SectionAlignment = 1000 Byte,此時RVA的值不等于PointerToRawData的值,。如果不是由OS的loader裝載,,也就是說,我要自己dump一個PE File,在自己的code中用的是fopen(),fread()這樣的函數(shù)將文件讀進內存,,而他們的作用僅僅是copy,,并不像OS的loader將文件載入內存,因此自己要要取Section的信息,,應該以后者的值來計算,。因為如果是OS的loader載入文件,就會將文件按照Section
Alignment的預設值將文件的各個部分放置內存的各個memory page中,。
以下附上Section Header的定義,。
Section Header在WinNT.h中的結構定義:
typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
1.VirtualAddress:本Section的RVA(相對虛擬地址)。PE裝載器將本section映射至內存時會讀取本值,,因此如果域值是1000h,,而PE文件裝在地址400000h處,那么本節(jié)就被載到401000h,。微軟把第一個Section 的此域值設為0x1000h,。對于OBJ文檔,此域沒意義,,總為0,。
2.SizeOfRawData:經過文件對齊處理后Section尺寸,PE裝載器提取本域值了解需映射入內存的節(jié)字節(jié)數(shù),。 假設一個文件的文件對齊尺寸是0x200,,如果前面的 VirtualSize 域指示本Section的長度是0x388字節(jié),則本域值為0x400,,表示本節(jié)是0x400字節(jié)長,。在obj中,這個與表示有編譯器指定的真正的section 大小,。
3.PointerToRawData:這是本Section基于文件的偏移量,,PE裝載器通過本域值找到Section數(shù)據(jù)在文件中的位置。 如果是你自己以內存映射的方式應設了一個PE程序(而不是由操作系統(tǒng)的裝載器載入),,那么這個域比VirtualAddress更重要,。在這種情況下你有一個完全線性的文件映射,那么你就必須根據(jù)此值找到本Section的信息,而不是根據(jù)VirtualAddress
中的RVA值。
|