我试图在 kernel32.dll 中找到 loadlibrary 的 RVA。我已经阅读了一些关于解析 PE header 的文档,但我似乎无法找出为什么我指向导出目录的指针似乎无效。
hFile = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
err = GetLastError();
return err;
}
hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (hFileMapping == 0)
{
err = GetLastError();
CloseHandle(fileName);
return err;
}
lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
if (lpFileBase == 0)
{
err = GetLastError();
CloseHandle(fileName);
CloseHandle(hFileMapping);
return err;
}
dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
pNTHeader = (PIMAGE_NT_HEADERS)((BYTE*)dosHeader + dosHeader->e_lfanew);
base = (DWORD64)dosHeader;
我在这里打开文件,当我用调试器运行这里时,一切似乎都很好。
exportsStartRVA = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
exportsEndRVA = exportsStartRVA + pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
这里我成功访问了DataDirectory,得到了导出目录的VirtualAddress和Size。
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader);
unsigned i;
for (i = 0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++)
{
// Is the RVA within this section?
if ((exportsStartRVA >= section->VirtualAddress) &&
(exportsStartRVA < (section->VirtualAddress + section->Misc.VirtualSize)))
break;
}
我浏览了所有部分,直到获得包含 exportStartRVA 的部分标题。现在“section”指针指向导出目录的 Section Header。
exportDir = (PIMAGE_EXPORT_DIRECTORY)((PBYTE)base + exportsStartRVA + section->PointerToRawData - section->VirtualAddress);
在这里我得到一个指向导出目录的指针。
PDWORD pfunctions = (PDWORD)((PBYTE)base + (DWORD64)exportDir->AddressOfFunctions + header->PointerToRawData - header->VirtualAddress);
PDWORD ordinals = (PDWORD)((PBYTE)base + (DWORD64)exportDir->AddressOfNameOrdinals + header->PointerToRawData - header->VirtualAddress);
PSTR* name = (PSTR*)((PBYTE)base + (DWORD64)exportDir->AddressOfNames + header->PointerToRawData - header->VirtualAddress);
PSTR funcName;
for (unsigned i = 0; i < (DWORD64)exportDir->NumberOfNames; i++)
{
funcName = name[i];
}
编辑:我认为问题在于我的取消引用,funcName 除了内存访问错误之外实际上没有给我任何东西。
最佳答案
AddressOfNames 是 RVA 到字符串名称列表的 RVA,而不是字符串列表的 RVA。
关于c++ - PIMAGE_EXPORT_DIRECTORY - 内存访问错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26616379/