Search code examples
c++windowsreadprocessmemory

What does a cast from byte buffer to a struct do?


I am trying to understand the following code.

PLOADED_IMAGE ReadRemoteImage(HANDLE hProcess, LPCVOID lpImageBaseAddress) {

BYTE* lpBuffer = new BYTE[BUFFER_SIZE];

BOOL bSuccess = ReadProcessMemory
    (
    hProcess,
    lpImageBaseAddress,
    lpBuffer,
    BUFFER_SIZE,
    0
    );

if (!bSuccess)
    return 0;   

PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)lpBuffer;

PLOADED_IMAGE pImage = new LOADED_IMAGE();

pImage->FileHeader = 
    (PIMAGE_NT_HEADERS32)(lpBuffer + pDOSHeader->e_lfanew);

pImage->NumberOfSections = 
    pImage->FileHeader->FileHeader.NumberOfSections;

pImage->Sections = 
    (PIMAGE_SECTION_HEADER)(lpBuffer + pDOSHeader->e_lfanew + 
    sizeof(IMAGE_NT_HEADERS32));

return pImage;
}

The code consists of a Windows API call ReadProcessMemory which asks for a pointer to a buffer where the API call will update it's return. What I dont understand is what comes after. what does the operation

PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)lpBuffer;

Do? From all I could tell it is a cast, However I have not been able to locate any structure called PIMAGE_DOS_HEADER. I am starting to think that it is not a cast, which leaves me stumped to what operation this is. This is acompanied further by the next line where:

pImage->FileHeader = 
(PIMAGE_NT_HEADERS32)(lpBuffer + pDOSHeader->e_lfanew);

From what I gathered lpBuffer is a Byte Array, so what is the role of the () here? How can you add a byte array to something else?


Solution

  • Following Microsoftian convention, the type PIMAGE_DOS_HEADER is a typedef defining a pointer to a IMAGE_DOS_HEADER struct.

    Therefore,

    PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)lpBuffer;
    

    is casting the BYTE * pointer lpBuffer to the more-specifically-typed IMAGE_DOS_HEADER * variable pDOSHeader, presumably in the hopes that lpBuffer is in fact pointing to a IMAGE_DOS_HEADER struct (since otherwise you'll be invoking undefined behavior when you try to read struct-member-variables via the pointer).

    From what I gathered lpBuffer is a Byte Array, so what is the role of the () here? How can you add a byte array to something else?

    They are doing pointer-math. In particular they are adding pDOSHeader->e_lfanew to the value of lpBuffer, and then casting the resulting pointer to a PIMAGE_NT_HEADERS32.