2011-11-24 49 views
2

我在Win32 NT頭文件中遇到問題,導致我輸入名稱的RVA爲奇數。這是給我的問題的相關代碼:導入地址表會導致導入名稱的RVA不正確

//Get a pointer to the import table 
PIMAGE_IMPORT_DESCRIPTOR piidImportTableAddr; 
piidImportTableAddr = (PIMAGE_IMPORT_DESCRIPTOR)(pImgNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + (DWORD)pMemFile); 

while(piidImportTableAddr->Name != 0) 
{ 
    //Itterate over every IMAGE_IMPORT_DESCRIPTOR structure, extracting the names of the DLLs to import 
    char* name = (char*)((DWORD)piidImportTableAddr->Name + (DWORD)pMemFile); 

    //Do nothing for now 

    piidImportTableAddr++; 
} 

然而,piidImportTableAddr結構的成員包含有壞的指針地址,這裏是會員的表格:

Characteristics 0x42746553 
OriginalFirstThunk 0x42746553 
TimeDateStamp 0x646f4d6b 
ForwarderChain 0x02260065 
Name 0x54746547 
FirstThunk 0x4d747865 

這些都是糟糕的RVA和內存位置。有沒有什麼我在做這個方法查找DLL名稱時做錯了?我將導入表的RVA與PE Lord中顯示的RVA進行了比較,它們是相同的,所以我不確定IMAGE_IMPORT_DESCRIPTORs爲什麼不正確。

這裏是源代碼的鏈接,在它的全部:http://pastebin.com/32MBEvWU

回答

1

您具有導入表的RVA,但由於模塊尚未加載,因此這些部分仍處於其物理位置。導入部分的物理偏移量通常與RVA不同。您將必須迭代節標題(_IMAGE_SECTION_HEADER),並使用VirtualAddressVirtualSize值查找包含導入表的部分。然後從PointerToRawData獲取該部分的物理地址。

所以,你要實際地址是這樣的:

importTableRVA - importSectionRVA + importSectionPhysicalAddress + pMemFile 
+0

對不起,你能解釋一下嗎?我理解你所說的摘要,但我不太瞭解「導入表」和「導入部分」之間的區別。 – dymk

+0

@Dylan:PE文件被分成不同的部分,代碼,數據,導入,導出等不同部分。通常,導入部分被命名爲「.idata」。但文件中的部分佈局與加載模塊的佈局不同,因此您必須調整地址。我推薦閱讀微軟自己的文檔:http://msdn.microsoft.com/en-us/windows/hardware/gg463125 – Timo

+0

@Dylan:只是爲了澄清,導入部分通常*包含導入表以及導入地址表和其他一些數據。規範是相當有說服力的,所以任何部分都可以包含幾乎任何東西。 – Timo

1

你的代碼給您正在檢查已經被虛擬化模塊,多數民衆贊成的IAT(加載到內存中),這意味着IAT會印象不包含RVA,而是由Windows加載程序將地址調整爲所需的動態偏移量。然而,據說這是由LordPE報告的數據是可疑的,如果二進制模塊實際上是有效的(即:Windows可以加載它並運行),那麼你可能是在處理一個混淆文件,否則二進制文件已損壞或不是win32 PE文件。

+0

啊,那我檢查裝入程序的內存映射文件的模塊,並且尚未由Windows PE感動裝載機。我正在測試的模塊是notepad.exe,因此它不會被混淆。 – dymk