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

Posted

技术标签:

【中文标题】用于非感知可执行文件的 ASLR 和 Windows 系统 DLL?【英文标题】:ASLR and Windows System DLLs for non-aware executables? 【发布时间】:2011-09-17 18:46:41 【问题描述】:

来自Microsoft article:

地址空间布局随机化 (ASLR)

当系统运行时,ASLR 将可执行映像移动到随机位置 靴子,使其更难被利用 可预测地运行的代码。 对于一个 支持 ASLR 的组件,所有 它加载的组件也必须 支持 ASLR。 例如,如果 A.exe 消耗 B.dll 和 C.dll,所有三个 必须支持 ASLR。 默认情况下,Windows Vista 及更高版本将随机化系统 DLL 和 EXE,但 DLL 和 EXE 由 ISV 创建的必须选择支持 使用 /DYNAMICBASE 链接器的 ASLR 选项。

我不太明白。获取 Windows 上每个进程加载的基本系统 DLL:NtDll.dllkernel32.dll

如果有一个不知道的可执行文件,这些系统 DLL 会使用 ASLR 吗?也就是说,在 Win 7 上每次系统重启后,它们会在不同的基地址加载这个可执行文件,还是在系统重启后总是像在 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.,这个地址只有一个小用例有用:在 Visual Studio 中,我只能为汇编级函数设置一个“数据断点”,即断点 @ 0x7 ... - 如果我想中断特定的 ntdll.dll 或 kernel32.dll 函数,在 Windows XP 中,我不必在重新启动之间调整断点。随着 ASLR 的启动(这个问题的范围)我会在重新启动之间更改数据断点。)

【问题讨论】:

调试 + Windows + 模块,地址栏。重启几次,让我们知道你发现了什么。 @Hans:这只是引起了我的兴趣。不幸的是,我个人可以使用的唯一 Win7 Dev 盒子,atm。是 2008R2 服务器,我不会为了尝试而重新启动我们的 CI 服务器 ;-) +1 因为我想问同样的问题。我在 Windows 7 64 位上进行了一些实验,在阅读了答案和 cmets 之后,我得出的结论是系统 DLL 的基础在每次重新启动时都会重新定位。我的可执行文件中未与/DYNAMICBASE 链接的其他非系统DLL 的基础不会重定位。 【参考方案1】:

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

更新:

this 文章中关于 ASLR 的部分解释了重定位的内容和时间。 它没有提到基础是否会在每次重新启动时重置,但对于系统 dll,它永远不会保证在同一地址加载两次,重新启动或不重新启动。 重要的是根据文章,一切都需要选择加入 ASLR 才能重新定位系统 dll。

【讨论】:

“windows 7 将在每次重启时重置基础随机化”...“重置”到底是什么意思? @martin: 如果某些东西有一个首选基地址,它会在第一个实例中加载,它会被重新定位,但是在重新启动后它将在首选基地址加载第一次加载再等等。 @Necrolis :我认为在 Windows 上使用 ASLR,每个系统 DLL 将始终加载到所有进程的相同地址,但是这个地址会在系统 DLL 重新启动之间发生变化...... ??跨度> @martin:根据MS的说法,如果ASLR应用于进程,那么所有dll的base都是随机的,包括系统dll。根据我的经验,即使 ASLR 生效(这可能不适用于系统 dll),第一次加载 dll 也会在其首选地址发生。 @Martin:我使用 ollydbg 和一个禁用了 ASLR 的进程进行了测试(通过 ProcessExplorer 确认),启动了应用程序几次,没有重新定位任何 dll,重新启动,重复检查,再次重新启动进行了第三次检查(这是在 Windows Server 2008 R2 SP1 上)。但是,我正在检查 WOW64 进程【参考方案2】:

您的程序将解析对系统 DLL 的调用,无论它们何时被加载。但是,除非您的可执行文件与 /DYNAMICBASE 链接,否则它不会被赋予随机基地址。换句话说,您的 exe 将始终加载到相同的基地址。

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

【讨论】:

“无论它们碰巧被加载到哪里” ...这意味着它们的地址在 Win7 上的重新启动之间有所不同? 是的,我相信无论您的应用程序或其 DLL 是否支持 ASLR,Vista 和 Windows 7 上的系统 DLL 都会以随机地址加载。 感谢您的更新。不知何故,您的回答/评论和@Necrolis 的回答/评论似乎不一致:-) 实际上,根据我现在在他的回答中看到的更新,我认为我们达成了一致。系统 DLL 将在随机地址加载。你的东西不会,除非你启用它。 hmmm ... Necrolis 写道:“但对于系统 dll,它永远不会保证在同一地址加载两次”与“但对于系统 dll,它永远不会保证在同一个地址加载两次”......我现在肯定很困惑:-)

以上是关于用于非感知可执行文件的 ASLR 和 Windows 系统 DLL?的主要内容,如果未能解决你的问题,请参考以下文章

如何检测我的 iOS 应用已启用 PIE/ASLR?

linux内存布局和地址空间布局随机化(ASLR)下的可分配地址空间

ASLR与mshta.exe报错“系统无法执行指定程序”有啥关系?

在没有 ASLR 的情况下寻找(内存,GC 相关)heisenbug 消失

IOS逆向-ASLR

单层感知器