assembly - 为什么堆栈充满了0xCCCCCCCC

标签 assembly disassembly

我目前正在反汇编一些在 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 语句,但我只是想知道为什么它们被放置在原来的位置。如果其背后有任何逻辑的话。

谢谢。

最佳答案

当您使用/RTC 选项时,您只会看到 MSVC 编译器生成的代码。它启用运行时检查,默认情况下在调试版本中打开。值 0xcccccccc 很神奇,当您使用未初始化的指针时,它非常很容易导致程序崩溃。或者生成一个奇怪的 int 值。或者当你的代码变得疯狂并开始像代码一样执行数据时,你的代码就会崩溃。 0xcc 是 INT 3 的 x86 指令,它调用调试器中断。

“为什么这个地方”是您从/RTC 获得的诊断信息的一部分。它使编译器在分配局部变量时在它们之间留出额外的空间。充满了那种神奇的值(value)。这使得诊断由缓冲区溢出引起的堆栈损坏变得非常简单,它只需要检查函数返回时魔术值是否仍然存在。

关于assembly - 为什么堆栈充满了0xCCCCCCCC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17644418/

相关文章:

c - 将程序计数器 (PC) 修改为已保存的地址

assembly - 将汇编代码转换为C代码

c++ - 在什么条件下,MSVC C++编译器有时会在从函数操作符new []返回的指针之前直接写入数组大小?

c - 堆栈在 32 位和 64 位处理器中有何不同

assembly - gdb 反汇编中的地址到底是什么?

汇编将指针传递给函数

assembly - 按功能分类的 x86 指令引用

c++ - 演示制作者如何获得超小文件大小?

c - 程序集 64 位无效有效地址

linux - mov 0x8(%r14,%r15,8),%rax 是什么意思