为什么堆栈会被填充为0xCCCCCCCC?

18

我目前正在反汇编一些使用Visual Studio 2012 Express制作的小型C程序,我注意到这些二进制文件中存在一种趋势。

在主函数中执行的第一组指令总是:

SUB ESP,154                       ; Doesn't have to be 0x154.
.....
.....
.....
LEA EDI,DWORD PTR SS:[EBP-154]
MOV ECX,55                        ; Also doesn't have to be 0x55.
MOV EAX,CCCCCCCC
REP STOS DWORD PTR ES:[EDI]

那么,为什么机器要用0xCCCCCCCC填充堆栈?我读到过它被VC++或其他东西用作未初始化空间的标记?

然后假设我要在我的缓冲区中放置一些东西...编译器或处理器决定将其放置在这个空间的某个随机点,但我不明白为什么会把它放在那里...

EBP-90   > CCCCCCCC  ÌÌÌÌ
EBP-8C   > CCCCCCCC  ÌÌÌÌ
EBP-88   > CCCCCCCC  ÌÌÌÌ
EBP-84   > 00000001  ...  ; Why this place?
EBP-80   > CCCCCCCC  ÌÌÌÌ
EBP-7C   > CCCCCCCC  ÌÌÌÌ
EBP-78   > 41414141  AAAA ; Why this far from both the top and bottom of the stack?
EBP-74   > CCCCCC00  .ÌÌÌ
EBP-70   > CCCCCCCC  ÌÌÌÌ
EBP-6C   > CCCCCCCC  ÌÌÌÌ

而...

EBP-14   > CCCCCCCC  ÌÌÌÌ
EBP-10   > CCCCCCCC  ÌÌÌÌ
EBP-C    > 00000000  ....  ; Why here?
EBP-8    > CCCCCCCC  ÌÌÌÌ
EBP-4    > 7EA7D069  iЧ~  ; I think this is some stack cookie stuff.
EBP ==>  >/0017FEA8  ¨þ.   ; Saved EBP.

虽然这里存储1和0是因为某些if语句,但我只想知道它们放在那里的逻辑。谢谢。


如果你是一个调试编译器,你能想象出这样的“可预测模式”可能有什么用处吗? - Kerrek SB
@KerrekSB 那我怎么知道该把东西放在哪里? - Volatile
1
请参阅https://dev59.com/GnVC5IYBdhLWcg3w-mZO中的答案,了解有关0xcccccccc的更多信息,并从被接受的答案中的维基百科链接中了解:“CC类似于x86处理器上INT 3调试断点中断的操作码。” - Logan Pickup
@Volatile:这跟什么有关系?你把东西放在栈指针告诉你要放的地方就行了... - Kerrek SB
@KerrekSB 我理解那部分。我问的是决定覆盖到堆栈上的值(比如AAAA)去哪里的因素。此外,我很确定我的示例用C填充了55个DWORD,而不是55个字节。 - Volatile
显示剩余8条评论
2个回答

30

当您使用/RTC选项时,您只会看到由MSVC编译器生成的代码。该选项启用运行时检查,在调试构建中默认开启。值为0xcccccccc是非常神奇的,当您使用未初始化的指针或生成奇怪的int值时,它非常擅长崩溃您的程序。或者在代码疯狂地开始将数据执行为代码时崩溃。 0xcc是INT 3的x86指令,它会调用调试器断点。

"为什么这个位置"是/RTC提供的诊断信息的一部分。它使编译器在本地变量之间分配额外空间,并填充了那个神奇的值。当函数返回时,这使得诊断由缓冲区溢出引起的堆栈损坏非常简单,只需检查魔术值是否仍然存在即可。


非常好,谢谢!但是你所指的奇怪整数值是什么? - Volatile
2
每当你在调试器中看到3435973836或-858993460时,你会想,“这很奇怪,这不是人类输入的值。”但实际上确实如此。 - Hans Passant
1
是的,像这样的东西对于调试非常有用。 - James Bedford

4
我不能代表Visual Studio发言,但我编写代码的一些环境有意地将堆栈填充了预定值(例如0xcccccccc)。这样做是为了可以扫描堆栈(从底部开始),以确定未被使用的内存量。在嵌入式系统中,内存量可能相当有限,在开发过程中这是非常有用的,以便优化内存使用。

希望这可以帮到你。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接