访问 PE 的 PIMAGE_EXPORT_DIRECTORY 结构的任何成员时崩溃

Crash while accessing any member of the PE's PIMAGE_EXPORT_DIRECTORY structure

我正在尝试获取 kernel32.dll 中函数的 RVA,我获取了导出目录的偏移量并将其添加到我的 file_map 中。但是,当我尝试对 PIMAGE_EXPORT_DIRECTORY 结构的任何成员执行任何操作时,我的程序崩溃了。如果不崩溃,我什至无法检查它是否是 nullptr。这是我的代码:

#include "Sample.h" //Just contains other headers
#include <dbghelp.h>
#include <imagehlp.h>

int main()
{
    char kernel_path[MAX_PATH];

    //PIMAGE_DOS_HEADER pDos_hdr = (PIMAGE_DOS_HEADER)GetModuleHandle("kernel32.dll");
    //if(pDos_hdr == NULL){printf("Invalid header: %d", (int)GetLastError());}

    if(GetModuleFileName(GetModuleHandle("kernel32.dll"), kernel_path, MAX_PATH) == 0)
    {
        printf("GetModuleFileName failed: %d", (int)GetLastError());
        return 1;
    }

    HANDLE hFile = CreateFile(kernel_path, GENERIC_READ, FILE_SHARE_READ,
       NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
    if(hFile == INVALID_HANDLE_VALUE){printf("Error getting file handle: 
       %d", (int)GetLastError());return 1;}

    HANDLE kernel_map = CreateFileMapping(hFile, NULL, 
       PAGE_READONLY|SEC_IMAGE, 0, 256, "KernelMap");

    LPVOID file_map = MapViewOfFile(kernel_map, FILE_MAP_READ, 0, 0, 0);
    if(file_map == 0){printf("Error getting mapped view: %d",
      (int)GetLastError());return 1;}

    PIMAGE_DOS_HEADER pDos_hdr = (PIMAGE_DOS_HEADER)file_map;
    if(pDos_hdr->e_magic == IMAGE_DOS_SIGNATURE){printf("Has MZ signature\n");}

    PIMAGE_NT_HEADERS pNt_hdr = (PIMAGE_NT_HEADERS)((char*)file_map+pDos_hdr->e_lfanew);
    if(pNt_hdr->Signature == 0x4550){printf("Has PE signature\n");}

    IMAGE_OPTIONAL_HEADER opt_hdr = pNt_hdr->OptionalHeader;
    IMAGE_DATA_DIRECTORY exp_entry = 
       opt_hdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
    PIMAGE_EXPORT_DIRECTORY pExp_dir = (PIMAGE_EXPORT_DIRECTORY)
        (((char*)file_map)+exp_entry.VirtualAddress);

    // Crashing Code --->
    void **func_table = (void**)((char*)file_map+pExp_dir->AddressOfFunctions);

    return 0;
}

From msdn, CreateFileMapping:: dwMaximumSizeLow [in] -

The low-order DWORD of the maximum size of the file mapping object. If this parameter and dwMaximumSizeHigh are 0 (zero), the maximum size of the file mapping object is equal to the current size of the file that hFile identifies.

您还没有将文件的完整大小映射到当前进程的虚拟内存。这是因为您限制了 (256) dwMaximumSizeLow parameter of the CreateFileMapping function. You can verify that by calling VirtualQuery.

HANDLE kernel_map = CreateFileMapping(hFile, NULL, 
PAGE_READONLY|SEC_IMAGE, 0, 0, "KernelMap"); // 5th Param = 0