为什么会发生字节溢出以及它们实现了什么?

d0r*_*ife 14 c memory x86 assembly llvm

什么是字节溢出?

当我从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
...
Run Code Online (Sandbox Code Playgroud)

Fal*_*mot 14

寄存器溢出就是当你有更多的局部变量而不是寄存器时会发生什么(这是一个类比 - 实际上意思是它们必须保存到内存中).该指令正在保存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作为内存偏移,而不是目标.