【问题标题】:Collision with "Uninitialized Stack Pointer"与“未初始化的堆栈指针”冲突
【发布时间】:2021-11-28 19:47:00
【问题描述】:

我最近得知 MSVC 的未初始化堆栈内存的调试模式标记是 0xCCCCCCCC。我现在很担心;虽然不太可能,但如果 malloc()/new/any 指针巧合地作为 this 指针结束会发生什么?它会抛出错误吗?这会导致重要系统出现问题吗?

【问题讨论】:

  • “如果 malloc()/new/any 指针巧合地作为 this 指针结束会发生什么?” 这当然不会发生,MS 开发人员似乎不会最聪明的,但他们没有那么愚蠢。
  • 0xCCCCCCCC 没有什么神奇或特别之处。如果 malloc()/new 最终从该位置的堆中分配,那么它将是一个有效位置。
  • 这是一个陷阱值……它本身就在非法地址范围内。它允许识别未初始化的存储。巧合的是 HeapAlloc 之类的用 0xbaadf00d 初始化内存
  • 不会发生,该地址只能映射到 ring0 页面(操作系统内核和驱动程序)。从而可靠地生成 AVE。 docs.microsoft.com/en-us/windows/win32/memory/…
  • “如果 malloc()/new/any 指针巧合地作为 this 指针结束会发生什么?” -- 好主意。你能想出比0xCCCCCCCC 更好的东西来用作标记吗?关于为什么 MSVC 不使用您的“更好”的想法有什么想法吗?

标签: c++ c visual-studio visual-c++


【解决方案1】:

标准要求malloc 进行适当对齐以存储任何类型的变量,new 返回适当对齐的指针,以便可以将其转换为任何完整对象类型的指针。

0xCCCCCCCC 的因式分解中有 2^2,这意味着最高对齐是 4 字节对齐(不能被 8 整除)。所以在 MSVC 中的 x86 上(long long 是 8 个字节)mallocnew 将永远不会返回 0xCCCCCCCC


这是我想到的,我相信故事还有更多。

【讨论】:

  • 我应该补充一点,用 0xcccccccc 填充内存只是帮助调试,并不是你真正应该依赖或检查的东西。
  • 是的,但是 MSVC 肯定也可以在 32 位系统上运行;那有可能吗?
  • x86 是 32 位平台。在 msvc x86 long long 上是 8 个字节
猜你喜欢
  • 1970-01-01
  • 2017-09-24
  • 2016-11-09
  • 1970-01-01
  • 1970-01-01
  • 2013-09-19
  • 2016-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多