我遇到了Win32 NT标头的问题,导致我输入名称的奇怪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_DESCRIPTOR不正确。
以下是完整源代码的链接:http://pastebin.com/32MBEvWU
答案 0 :(得分:1)
您的代码给人的印象是您正在检查已经虚拟化(加载到内存中)的模块的IAT,这意味着IAT将不包含RVA,但是地址将由Windows加载程序调整为需要动态抵消。
然而,话虽如此,LordPE报告的数据是可疑的,如果二进制模块实际上是有效的(即:windows可以加载它并且它运行),那么你可能正在处理一个混淆的文件,否则二进制文件是损坏的或不是win32 PE文件。
答案 1 :(得分:1)
您拥有导入表的RVA,但由于尚未加载模块,因此这些部分仍位于其物理位置。导入部分的物理偏移量通常与RVA不同。您将不得不遍历节标题(_IMAGE_SECTION_HEADER),并使用VirtualAddress
和VirtualSize
值查找包含导入表的节。然后从PointerToRawData
获取该部分的实际地址。
所以你想要的实际地址是这样的:
importTableRVA - importSectionRVA + importSectionPhysicalAddress + pMemFile