Search code examples
c++windowsbyteportable-executabledword

What's the difference between casting the type of a 32 bit address to (BYTE *) and (DWORD *)


My program runs on a 32bit Windows ,so the type of the address in the virtual memory space is DWORD. And I want to hook API by changing the address of the API in IAT . So , I get the base address of the image of the target process first. Then , I try to get the start address of the IMAGE_OPTIONAL_HEADER structure.

IMAGE_OPTIONAL_HEADER32* pOptionalHeader=(IMAGE_OPTIONAL_HEADER*)((BYTE*)g_hCurrentProcessBase+pDosHeader->e_lfanew+24); //variable g_hCurrentProcessBase is the base address of the image of the target process

As you see , I cast g_hCurrentProcessBase to BYTE* type, but at first , I casted it to DWORD* type , like this:

IMAGE_OPTIONAL_HEADER32* pOptionalHeader=(IMAGE_OPTIONAL_HEADER*)((DWORD*)g_hCurrentProcessBase+pDosHeader->e_lfanew+24);

But it didn't work , getting a wrong address of IMAGE_OPTIONAL_HEADER structure. But the the value of the variable g_hCurrentProcessBase should be a DWORD (I run it on 32bit Windows system) , but casting this variable to DWORD * didn't work , making it get a wrong address . But casting it to BYTE* works ,so what't the difference between them ?Why casting it to DWORD * don't work?


Solution

  • Pointer arithmetic is different according to the type of the value it points to.

    If you cast the pointer to DWORD, adding 24 actually adds 24*sizeof(DWORD) to your address.

    When casting to BYTE, it just adds 24 to the address (BYTE is 1 byte)

    Note: If you really wanted your pointer as a DWORD (not the case here):

    If you want to skip 24 bytes, just add 24/sizeof(DWORD) to your DWORD* pointer. Since DWORD is of size 4 it works as you want (even if it was 2 or 8 it would work).

    Or compute the pointer using BYTE* cast, and then cast to DWORD*