我将整个 PE 加载到std::vector<Byte> fileContent
using 中std::fstream
。
然后我获得了可执行文件的 dos 头:
IMAGE_DOS_HEADER* imageDosHeader = (IMAGE_DOS_HEADER*)fileContent.data();
之后,我检查 PE 是否有效(MZ
和PE00
签名)。
如果是,我会得到它的导入描述符:
IMAGE_IMPORT_DESCRIPTOR* imageImportDescriptor = (IMAGE_IMPORT_DESCRIPTOR*)((DWORD)imageDosHeader + imageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
//Note: the VirtualAddress field equals 0x4FFC, so I assume it's valid
现在,我遍历 dll 并尝试显示它们的名称如下:
for(DWORD i = 0; ; i++)
{
bool isCurrentDllValid = true;
//if all fields of the current dll are zeros, then this dll is the last one, so break the outer loop
for(DWORD j = 0; j < sizeof(IMAGE_IMPORT_DESCRIPTOR); j++)
{
if((*(DWORD*)((DWORD)&imageImportDescriptor[i] + j)))
break;
else if(j == sizeof(IMAGE_IMPORT_DESCRIPTOR) - 1)
isCurrentDllValid = false;
}
if(!isCurrentDllValid)
break;
char* dllName = (char*)((DWORD)imageDosHeader + imageImportDescriptor[i].Name);
问题是:试图显示dllName
崩溃的原因。
此外,该Name
领域是一个RVA,但其价值是0x6C61766E
(同样的事情,与其余字段,最小的一个是TimeDateStamp
有0x637465
,还是一个异常),而PE的大小小于0x7000
。
在十六进制编辑器中,例如的 RVA"KERNEL32.dll"
是0x46F0
.
你知道为什么会这样吗?我错过了一些非常简单的东西吗?