栈溢出原理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Eira_H/article/details/81006142

什么是缓冲区溢出

缓冲区溢出就是在大缓冲区中的数据向小缓冲区复制的过程中,由于没有注意到小缓冲区的边界,“撑爆”了较小的缓冲区,从而冲掉了和小缓冲区相邻内存区域的其他数据而引起的内存问题。

栈帧

C语言中,每个栈帧对应着一个未运行完的函数。栈帧中保存了该函数的返回地址和局部变量。每一个函数独占自己的栈帧空间,当前正在运行的栈帧总是在栈顶。函数栈帧的大小不固定,一般与其对应函数的局部变量的多少有关,函数运行中,其栈帧大小也是在不停变化的。在函数栈帧中一般包含以下几类重要信息:

  • 局部变量:为函数局部变量开辟的内存空间。
  • 栈帧状态值:保存前栈帧的底部,用于在本帧被弹出后恢复出上一个栈帧。
  • 函数返回地址:保存当前函数调用前的“断点”信息,也就是调用前的指令位置,以便在函数返回时能够恢复到函数被调用前的代码区中继续执行指令。

ESP:栈指针寄存器,其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。
EBP:基址指针寄存器 ,其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。
EIP:指令寄存器,其内存放着一个指针,该指针永远指向下一条等待执行的指令地址。

我们这里认为EBP和ESP之间的部分当作一个栈帧,也就是栈帧底部是前栈帧的EBP,顶部是返回地址。

常见栈溢出手法

修改邻接变量

函数的局部变量在栈中一个挨着一个排列,如果这些局部变量中有数组之类的缓冲区,并且程序中存在数组越界的缺陷,那么越界的数组元素就有可能破坏栈中相邻变量的值,甚至破坏栈帧中所保存的EBP值和返回地址等重要数据。
优点:有效
缺点:这种漏洞利用对代码环境的要求比较严苛。

修改函数返回地址

返回地址用于在当前函数返回时重定向程序的代码。在函数返回的“retn”指令执行时,栈顶元素是返回地址,“retn”指令会把这个返回地址弹入EIP寄存器,之后跳转到这个地址去执行。

代码植入

在buffer中包含我们自己想要执行的代码,然后通过返回地址让程序跳转到系统栈里执行。

猜你喜欢

转载自blog.csdn.net/Eira_H/article/details/81006142