一、栈溢出原理
什么是栈溢出?栈溢出就是缓冲区溢出的一种。 由于缓冲区溢出而使得有用的存储单元被改写,往往会引发不可预料的后果。程序在运行过程中,为了临时存取数据的需要,一般都要分配一些内存空间,通常称这些空间为缓冲区。如果向缓冲区中写入超过其本身长度的数据,以致于缓冲区无法容纳,就会造成缓冲区以外的存储单元被改写,这种现象就称为缓冲区溢出。缓冲区长度一般与用户自己定义的缓冲变量的类型有关。(PS:摘自百度百科)
简单来说,就是程序没有检查用户输入的数据长度,导致攻击者覆盖栈上不是程序希望写入的地方,比如说返回地址。(PS:本人是这么理解的,如有问题,还请斧正)
在x86中,对于调用一个函数,栈的变化如下:首先,将被调用的函数的参数从右到左依次压入栈中,然后将被调用的函数的返回地址压入栈中,然后跳转到被调用函数的地址去,在被调用的函数中,首先将ebp(这时的ebp是调用者的ebp)压入栈中,最后,将此时的栈顶esp赋值给ebp寄存器(此时的ebp便是被调用函数的栈底了)
以一个实际程序为例,源码如下所示:
对于进入test函数后,栈的变化情况如下图所示:
接着利用gdb调试验证栈的情况如上图所示,首先在test函数处打下断点,然后start命令将程序运行到main函数开头处,查看一下此时的ebp寄存器的值和call test指令后下一条指令的地址,这里可以看到此时ebp寄存器的值为0xffffd1d8,call test指令后的下一条指令地址为0x565561f2,如下图所示:
然后运行r命令,进入test函数内部,使用x命令查看此时的栈情况,可以发现栈的情况如上图示意图一样,如下图所示:
在test函数内部,有个ver字符数组,在上面的源码中,我们对其进行了手动赋值,假如该数组通过strcpy等函数完成赋值,并且赋值的字符串由用户输入,那么在用户输入的字符串超过12个字节大小之后,ver数组就会接着往高地址增长,在这其中,可以覆盖掉tes
支付5UD,阅读全文
还有更多的精彩内容,作者设置为付费后可见