Home > Enterprise >  How to pass the Image pointer to Image_dos_header in windows
How to pass the Image pointer to Image_dos_header in windows

Time:05-08

How to properly construct the NtHeader when calling PIMAGE_NT_HEADERS64 Microsoft docs does not seem to have much remarks on this function, the problem is that casting from void* to DWORD fails

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;
}

Error when compiling

$ 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
      |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Is there another way to do this or is there any good explanation of what to pass PIMAGE_NT_HEADERS64

CodePudding user response:

DWORD is 32 bits (4 bytes) in size, in both 32-bit and 64-bit systems.

The compiler is warning you that the size of DWORD is different than the size of a void* pointer in your compilation, so you will lose bits. This means you must be compiling a 64-bit executable, where pointers are 64 bits (8 bytes) in size.

You need to typecast to DWORD_PTR instead, which is the same size as a pointer, whether you compile for 32-bit or 64-bit.

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

Alternatively, you can use pointer arithmetic instead of integer arithmetic:

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