`VirtualAllocEx` returns 指定不同的起始地址时相同的地址?

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

我试图让 calc.exe 显示一个消息框,但是 calc.exe 总是在我执行我的程序时崩溃。因此,我尝试将代码注入到我自己的进程中,以便查看调试消息。这样做给了我指向 pData->msg 的异常 "Access violation at... Cannot execute..."。然后我发现 pThreadpData 得到了相同的地址。这怎么可能?我实际上将 VirtualAllocExlpAddress 设置为 pPagepPage + 128 以获得相同的起始地址。

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

VirtualAllocEx 分配的内存部分可整除内存页面大小,即 4096 字节。

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.

尝试使用堆函数(HeapAlloc、HeapFree、HeapCreate)。

或者你可以这样做:

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