ASLR和VirtualAlloc的奇怪行为

时间:2018-06-21 20:09:34

标签: c++ windows security winapi

我的问题是我试图将内存分配给我制作的应用程序(x86)(通过Linker禁用了ASLR),

void* space = VirtualAllocEx(processHandle, LPVOID(0x400000),
    0x20000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

,返回值VirtualAllocExNULL(0)。如您所见,我试图在地址空间0x400000中分配空间,该地址空间是可执行文件的默认虚拟地址空间。现在很奇怪的是,这种内存分配可用于ASLR,但不适用于禁用ASLR的情况。

所以我的问题是:为什么会这样?我的意思是,为什么ASLR使您能够在这样的“关键”地址中分配空间?而且,为什么在没有ASLR的情况下此内存分配失败?这对现代系统不构成安全威胁吗?

2 个答案:

答案 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以上的其他地址。