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