我试图让calc.exe显示一个消息框,但calc.exe总是在我执行程序时崩溃。因此,我尝试将代码注入到自己的进程中,以便查看调试消息。这样做会导致指向pData->msg
的异常"在…处发生访问冲突,无法执行…"。然后我发现pThread
和pData
得到了相同的地址。这怎么可能?实际上,我将VirtualAllocEx
的lpAddress
设置为pPage
和pPage + 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]区域的大小,以字节为单位。如果lpAddress参数为NULL,则该值四舍五入到下一页边界。否则,分配的页面包括包含一个或多个字节的所有页面,这些字节的范围从lpAddress到lpAddress+dwSize。这意味着跨越页面边界的2字节范围导致两个页面都被包括在所分配的区域中。
lpAddress[in,可选]为要分配的页面区域指定所需起始地址的指针。如果要保留内存,函数会将此地址四舍五入到分配粒度的最近倍数。
尝试使用堆函数(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);