非感知可执行文件的ASLR和Windows系统DLL?

非感知可执行文件的ASLR和Windows系统DLL?,windows,dll,kernel32,aslr,Windows,Dll,Kernel32,Aslr,从a: 地址空间布局随机化(ASLR) 当系统运行时,ASLR将可执行映像移动到随机位置 靴子,使它更难被利用 代码以可预测的方式运行。暂时 支持ASLR的组件,所有 它加载的组件也必须 支持ASLR。例如,如果A.exe 使用B.dll和C.dll,这三个 必须支持ASLR。默认情况下,Windows Vista和更高版本将随机化系统 DLL和EXE,但DLL和EXE 由ISV创建的必须选择加入以支持 使用/DYNAMICBASE链接器的ASLR 选择权 我不太明白。以WIndows上每个进程

从a:

地址空间布局随机化(ASLR) 当系统运行时,ASLR将可执行映像移动到随机位置 靴子,使它更难被利用 代码以可预测的方式运行。暂时 支持ASLR的组件,所有 它加载的组件也必须 支持ASLR。例如,如果A.exe 使用B.dll和C.dll,这三个 必须支持ASLR。默认情况下,Windows Vista和更高版本将随机化系统 DLL和EXE,但DLL和EXE 由ISV创建的必须选择加入以支持 使用/DYNAMICBASE链接器的ASLR 选择权

我不太明白。以WIndows上每个进程加载的基本系统dll为例:
NtDll.dll
kernel32.dll

如果具有非感知可执行文件,这些系统DLL是否会使用ASLR?也就是说,对于此可执行文件,在Win7上每次系统重新启动后,它们会在不同的基址加载,还是会像在Win XP上一样,在系统重新启动后始终在相同的基址加载

为了更清楚地说明我的意思:我典型的虚拟程序的启动堆栈如下所示:

    write_cons.exe!wmain()  Line 8  C++
    write_cons.exe!__tmainCRTStartup()  Line 583 + 0x19 bytes   C
    write_cons.exe!wmainCRTStartup()  Line 403  C
>   kernel32.dll!_BaseProcessStart@4()  + 0x23 bytes    
查看
BaseProcessStart
的asm,我在XP框中看到:

_BaseProcessStart@4:
7C817054  push        0Ch  
7C817056  push        7C817080h 
7C81705B  call        __SEH_prolog (7C8024D6h) 
7C817060  and         dword ptr [ebp-4],0 
...
现在我感兴趣的是:

在Windows XP上,无论我重新启动此计算机多少次,地址始终为0x7C817054。如果我使用的是带ASLR的Win7,那么如果加载kernel32.dll的可执行文件没有为ASLR启用,那么在重新启动之间这个地址会改变吗


(注意:对于我,atm.,这个地址只适用于一个小用例:在VisualStudio中,我只能设置一个“数据断点”对于程序集级函数,这是一个断点@0x7…-如果我想在特定的ntdll.dll或kernel32.dll函数中中断,在Windows XP中,我不必在重新启动之间调整断点。随着ASLR的启动(此问题的范围),我必须在重新启动之间更改数据断点。)

从技术上讲,无论系统DLL是否重新定位,这都不重要,因为链接器将绑定到符号,而不是地址。这些符号由运行时加载器解析为实例系统DLL的地址,因此二进制文件应该是不明智的。然而,据我所见,windows 7将在每次重新启动时重置基本随机化,包括系统DLL(注意:这是在widows server 2008 R2上调试WOW64应用程序的结果)。您还可以通过一些注册表编辑在系统范围内禁用ASLR,但这并不真正相关

更新:

文章中关于ASLR的部分解释了什么被重新定位以及何时被重新定位。 它没有提到基址是否会在每次重新启动时重置,但对于系统DLL,它永远不会保证在同一地址加载两次,重新启动或不重新启动。
根据这篇文章,重要的是,所有的东西都需要选择ASLR,以便重新定位系统dll。

您的程序将解析对系统dll的调用,无论它们在哪里加载。但是,除非您的可执行文件与/DYNAMICBASE链接,否则将不会为其提供随机基址。换句话说,exe将始终在相同的基址加载


如果希望在随机地址加载exe,则必须将其与/DYNAMICBASE链接,并且它引用的每个DLL也必须与/DYANMICBASE链接。系统DLL(从Vista开始)都与/DYNAMICBASE链接。

Debug+Windows+模块,地址列。重新启动几次,让我们知道你发现了什么。@Hans:这正是引起我兴趣的事情。不幸的是,我个人只能在atm机上使用Win7开发设备。是2008R2服务器,我不打算重新启动CI服务器只是为了尝试;-)+因为我想问同样的问题。我在Windows7 64位上做了一点实验,在阅读了答案和评论之后,我得出结论:每次重新启动时,系统DLL的基础都会重新定位。我的可执行文件中未与
/DYNAMICBASE
链接的其他非系统DLL的基础不会重新定位。“无论它们在哪里加载”。。。这意味着在Win7上重新启动时,它们的地址会有所不同?是的,我相信Vista和Windows 7上的系统DLL将以随机地址加载,无论您的应用程序或其DLL是否支持ASLR。感谢您的更新。不知何故,你的回答/评论和@Necrolis的回答/评论似乎不一致:-)事实上,根据我在他的回答中看到的最新情况,我认为我们是一致的。系统DLL将以随机地址加载。除非你启用它,否则你的东西不会被激活。。。Necrolis写道:“但是对于系统DLL,它永远不会保证在同一地址加载两次”vs.“但是对于系统DLL,它永远不会保证在同一地址加载两次”。。。我现在肯定很困惑:-)“windows 7将在每次重新启动时重置基本随机化”。。。“重置”到底是什么意思?@martin:如果某个东西有一个首选的基址,它将在第一次加载时加载到那里,它将被重新定位,但是在重新启动后,它将在首选的基址上加载,以便再次加载等@Necrolis:我想在Windows上使用ASLR时,对于所有进程,每个系统DLL将始终加载在相同的地址上,但对于系统DLL,此地址将在重新启动之间更改@马丁:根据微软的说法,如果ASLR适用于该过程,那么所有DLL(包括系统DLL)的基数都是随机的。根据我的经验,即使ASLR有效(这可能不适用于系统dll),dll的第一次加载也会发生在其首选地址。@Martin:我使用ollydbg和禁用ASLR的进程进行测试(通过ProcessExplorer确认),启动应用程序几次,没有重新定位任何dll,重新启动,重复检查,再次重新启动第三次检查(这是在windows server 2008 R2 SP1上)。但是,我正在检查WOW64进程