Search code examples
c++winapivirtualalloc

`VirtualAllocEx` returns same address when specifying different start addresses?


I'm trying to bring calc.exe to show a messagebox, but calc.exe always crashes as soon as I execute my program. So I tried to inject the code to my own process in order to see debugging messages. Doing so gives me the exception "Access violation at... Cannot execute..." pointing to pData->msg. Then I found out that pThread and pData get the same address. How is this possible? I actually set lpAddress of VirtualAllocEx to pPage and pPage + 128 to not get the same start address.

// Allocate page
void *pPage = VirtualAllocEx(hProcess, NULL, 256, MEM_RESERVE, PAGE_EXECUTE_READWRITE);

// Commit memory for thread procedure
void *pThread = VirtualAllocEx(hProcess, pPage, 128, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

// Commit memory for thread data
void *pData = VirtualAllocEx(hProcess, (void*)((long long)pPage + 128), 128, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

// WriteProcessMemory, do stuff

// Release memory
VirtualFreeEx(hProcess, pPage, 256, MEM_RELEASE);

Solution

  • The VirtualAllocEx allocates memory with portions divisible memory page size which is 4096 byte.

    dwSize [in] The size of the region, in bytes. If the lpAddress parameter is NULL, this value is rounded up to the next page boundary. Otherwise, the allocated pages include all pages containing one or more bytes in the range from lpAddress to lpAddress+dwSize. This means that a 2-byte range straddling a page boundary causes both pages to be included in the allocated region.

    lpAddress [in, optional] The pointer that specifies a desired starting address for the region of pages that you want to allocate. If you are reserving memory, the function rounds this address down to the nearest multiple of the allocation granularity.

    Try to use Heap function (HeapAlloc, HeapFree, HeapCreate).

    Or you can do something like this:

    // Allocate page
    void *pPage = VirtualAllocEx(hProcess, NULL, 256, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    
    // Commit memory for thread data
    void *pData = (char*)pPage + 128;
    
    // WriteProcessMemory, do stuff
    
    // Release memory
    VirtualFreeEx(hProcess, pPage, 256, MEM_RELEASE);