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

时间:2016-07-06 04:42:43

标签: c++ pointers dll portable-executable

我正在尝试获取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;
}

1 个答案:

答案 0 :(得分:0)

  

来自msdn CreateFileMapping ::    dwMaximumSizeLow [in] -

     

文件映射对象的最大大小的低位DWORD。如果   此参数和dwMaximumSizeHigh为0(零),最大大小为   文件映射对象等于文件的当前大小   hFile识别。

您尚未将文件的完整大小映射到当前进程的虚拟内存。这是因为您dwMaximumSizeLow函数的CreateFileMapping参数有限(256)。您可以通过致电VirtualQuery验证这一点。

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