我的问题是我试图将内存分配给我制作的应用程序(x86)(通过Linker禁用了ASLR),
void* space = VirtualAllocEx(processHandle, LPVOID(0x400000),
0x20000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
,返回值VirtualAllocEx
为NULL
(0)。如您所见,我试图在地址空间0x400000中分配空间,该地址空间是可执行文件的默认虚拟地址空间。现在很奇怪的是,这种内存分配可用于ASLR,但不适用于禁用ASLR的情况。
所以我的问题是:为什么会这样?我的意思是,为什么ASLR使您能够在这样的“关键”地址中分配空间?而且,为什么在没有ASLR的情况下此内存分配失败?这对现代系统不构成安全威胁吗?
答案 0 :(得分:2)
在禁用ASLR的情况下,您的代码将位于地址0x400000,因此分配将失败。
启用ASLR后,您的代码可以在任何地方,因此该代码有时(可能大多数时候)可以工作,但有时显然是随机失败的,这更糟。
解决方案:将lpAddress
传递为NULL,让系统决定分配的位置。您为什么还要做其他事情?
请注意,从安全角度(或者实际上是其他任何角度)来看,地址0x400000没有什么特别的。只是Windows恰好在禁用ASLR的情况下将您的代码建立在此处。
答案 1 :(得分:1)
启用ASLR后,它可能大部分时间都可以工作,但从理论上讲,它可以使用0x400000作为随机基数。禁用ASLR后,可能已将EXE加载到那里,因此您无法在同一地址分配新的内存。
0x400000不是关键地址,对Windows没有特殊含义。 EXE PE标头指定地址,Microsoft工具链使用0x400000作为x86 EXE文件的默认值。 Microsoft ARM64链接器会强制您使用4 GiB以上的其他地址。