如何将图像指针传递给 windows 中的 Image_dos_header

How to pass the Image pointer to Image_dos_header in windows

How to properly construct the NtHeader when calling PIMAGE_NT_HEADERS64 Microsoft docs 似乎对这个函数没有太多评论,问题是从 void* 转换为 DWORD失败

int runPE64(void* Image)
{
    /*
    non relevant code 
    */
    char CurrentFilePath[1024];
    DOSHeader = PIMAGE_DOS_HEADER(Image); // Initialize Variable
    NtHeader = PIMAGE_NT_HEADERS64( DWORD(Image) + DOSHeader->e_lfanew); // Initialize
    GetModuleFileNameA(0, CurrentFilePath, 1024); // path to current executable

    return 0;
}



int main()
{

    unsigned char data[] = {0x4D,0x5A,0x00}; // this is dummy data 
    runPE64(data);

    return 0;
}

编译时出错

$ g++ runPE64.cpp 
runPE64.cpp: In function 'int runPE64(void*)':
runPE64.cpp:31:41: error: cast from 'void*' to 'DWORD' {aka 'long unsigned int'} loses precision [-fpermissive]
   31 |         NtHeader = PIMAGE_NT_HEADERS64( DWORD(Image) + DOSHeader->e_lfanew); // Initialize
      |                                         ^~~~~~~~~~~~
runPE64.cpp:31:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
   31 |         NtHeader = PIMAGE_NT_HEADERS64( DWORD(Image) + DOSHeader->e_lfanew); // Initialize
      |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

是否有另一种方法可以做到这一点,或者对于传递什么有什么好的解释 PIMAGE_NT_HEADERS64

DWORD 在 32 位和 64 位系统中都是 32 位(4 字节)大小。

编译器警告您 DWORD 的大小与编译中的 void* 指针的大小不同,因此您会丢失位。这意味着您必须编译 64 位可执行文件,其中指针的大小为 64 位(8 字节)。

您需要类型转换为 DWORD_PTR,无论您是为 32 位还是 64 位编译,它的大小都与指针相同。

NtHeader = PIMAGE_NT_HEADERS64( DWORD_PTR(Image) + DOSHeader->e_lfanew);

或者,您可以使用指针算法代替整数算法:

NtHeader = PIMAGE_NT_HEADERS64( LPBYTE(Image) + DOSHeader->e_lfanew); // Initialize