如何在64位Windows上让VirtualAlloc从0x000'00000000地址保留内存页?
如何强制VirtualAlloc从0x000000000000地址开始保留内存
Windows默认会保留低地址初始页面(通常为0x0到0xFFFF)作为无效区域,用于捕获空指针访问,因此直接调用VirtualAlloc(0x0, ...)会失败。要实现从0地址开始分配内存且不让系统自选位置,需按以下步骤操作:
步骤1:允许进程分配低地址内存(Windows 10 1809+)
通过SetProcessInformation函数开启低地址内存分配权限,该API仅支持Windows 10 1809及更高版本:
#include <windows.h> #include <processthreadsapi.h> BOOL EnableLowAddressAllocation() { PROCESS_MEMORY_ALLOCATION_MODE allocMode = {0}; allocMode.AllowLowMemoryAllocation = TRUE; return SetProcessInformation( GetCurrentProcess(), ProcessMemoryAllocationMode, &allocMode, sizeof(allocMode) ); }
步骤2:调用VirtualAlloc指定0地址分配
确保低地址权限开启成功后,调用VirtualAlloc时明确指定起始地址为0x000000000000,同时注意分配大小需为系统页面大小的整数倍:
LPVOID AllocateMemoryFromZero(SIZE_T reqSize) { SYSTEM_INFO sysInfo; GetSystemInfo(&sysInfo); // 将请求大小对齐到页面边界 SIZE_T alignedSize = (reqSize + sysInfo.dwPageSize - 1) & ~(sysInfo.dwPageSize - 1); return VirtualAlloc( (LPVOID)0x000000000000, alignedSize, MEM_RESERVE | MEM_COMMIT, // 按需选择仅保留地址空间(MEM_RESERVE)或同时提交物理内存 PAGE_READWRITE // 根据需求设置内存保护属性,如PAGE_NOACCESS、PAGE_EXECUTE_READ等 ); }
关键注意事项
- 若系统版本低于Windows 10 1809,无法绕过低地址页面保护,此方法不适用。
- 分配0地址内存后,空指针访问(如
*(int*)0)不会触发系统访问违例,可能导致程序出现难以调试的逻辑错误,需谨慎使用。 - 必须先确保
EnableLowAddressAllocation调用成功,否则VirtualAlloc指定0地址仍会失败。
内容的提问来源于stack exchange,提问作者user12653758
相关产品推荐
相关产品推荐

