20

什么是字节溢出?

当我从 C 程序生成的 LLVM 中间表示中转储 x86 ASM 时,会出现大量溢出,通常为 4 字节大小。我无法弄清楚它们为什么会发生以及它们取得了什么成就。

他们似乎“切断”了堆栈的一部分,但以一种不同寻常的方式:

## this fragment comes from a C program right before a malloc() call to a struct.
## there are other spills in different circumstances in this same program, so it
## is not related exclusively to malloc()
...
sub ESP, 84
mov EAX, 60
mov DWORD PTR [ESP + 80], 0
mov DWORD PTR [ESP], 60
mov DWORD PTR [ESP + 60], EAX # 4-byte Spill
call malloc
mov ECX, 60
...
4

1 回答 1

19

寄存器溢出就是当您拥有比寄存器更多的局部变量时发生的事情(这是一个类比 - 真正的意思是它们必须保存到内存中)。该指令正在保存 EAX 的值,可能是因为 EAX 被 malloc 破坏了,并且您没有另一个备用寄存器来保存它(无论出于何种原因,编译器都决定稍后在寄存器中需要常量 60)。

从表面上看,编译器当然可以省略mov DWORD PTR [ESP + 60], EAX并重复mov EAX, 60它本来应该使用的位置mov EAX, DWORD PTR [ESP + 60]或使用的任何偏移量,因为此时 EAX 的保存值不能超过 60。但是,不能保证编译是完美的。

还要记住,在 之后sub ESP, 84,堆栈大小不会被调整(当然调用返回地址的调用指令除外)。以下说明使用 ESP 作为内存偏移量,而不是目标。

于 2013-05-09T03:02:11.617 回答