Windows Vista 下的指针稳定性
Posted
技术标签:
【中文标题】Windows Vista 下的指针稳定性【英文标题】:Pointer stability under Windows Vista 【发布时间】:2009-10-21 18:29:26 【问题描述】:一段时间以来,我一直在 Windows XP Pro 64 位下使用 Visual Studio 2005 处理 C 和 C++ 项目。我在调试器中不时使用的流行技巧之一是记住程序上次调试运行中的数字指针值(例如0x00000000FFAB8938
),将其添加到具有适当类型转换的监视窗口(例如, ((MyObject *) 0x00000000FFAB8938)->data_field
) 然后在下次调试运行时观察对象占用的内存。在许多情况下,这是一件非常方便和有用的事情,因为只要代码保持不变,可以合理地预期分配的内存布局也将保持不变。简而言之,它有效。
但是,最近我开始在装有 Windows Vista(家庭高级版)64 位的笔记本电脑上使用相同版本的 Visual Studio。奇怪的是,在该设置中使用此技巧要困难得多。实际的内存地址似乎经常在运行之间发生变化,没有明显的原因,即即使程序的代码根本没有改变。看起来实际地址并不是完全随机变化的,它只是从一组固定的或多或少稳定的值中选择一个值,但无论如何,这使得进行这种类型的内存监视变得更加困难。
有谁知道 Windows Vista 中这种行为的原因?是什么导致内存布局发生变化?这是从其他 [系统] 进程对进程地址空间的一些外部入侵吗?还是Vista下Heap API实现的一些怪癖/功能?有什么办法可以防止这种情况发生吗?
【问题讨论】:
在 Linux 下,自较长时间以来一直存在旨在避免缓冲区溢出攻击的堆随机化器。也许它最终也被MS实现了? 嗯,我知道这一点,但据我所知,它仅在您 重新启动 计算机时有效。更准确地说,我听说 MS 实现了他们的版本以在每次启动时随机化事物(不知道它在 Linux 上是如何工作的)。所以,我在 Vista 中观察到的行为似乎并不相关。 虽然这可能是什么。我正在运行 VS 2005,它是可以调试 64 位应用程序的 32 位应用程序。 AFAIK,它通过 MS 的远程调试机制工作。是不是每次我从 VS 2005 启动一个 64 位应用程序时,Vista 本质上都会“启动”一个新的 64 位环境(从而导致事情变得随机化)? 看起来 Vista 确实有堆随机化:msdn.microsoft.com/en-us/library/bb430720.aspx 我认为这是一个好问题,并不是因为它代表了一种尝试调试代码的特别好方法,而是它突出了一个安全问题,并且是操作系统可以用来防御它的一种小技术。跨度> 【参考方案1】:Windows Vista 实现address space layout randomization, heap randomization, and stack randomization。这是一种安全机制,试图防止依赖于每段代码和数据在内存中的位置的缓冲区溢出攻击。
可以通过设置MoveImages 注册表值来关闭ASLR。我找不到禁用堆随机化的方法,但一些微软人建议计算相对于_crtheap
的地址。即使堆移动,相对地址也可能保持稳定。
【讨论】:
感谢您的引用。 :) 推测是一回事,但很高兴看到证据。以上是关于Windows Vista 下的指针稳定性的主要内容,如果未能解决你的问题,请参考以下文章