缓冲区溢出原理

缓冲区溢出的原因是由于字符串处理函数(gets等)没有对数组的越界加以监视和限制,结果覆盖了老的堆栈数据。

程序在内存中的存储如图所示:程序是从内存低端向内存高端按顺序执行的,堆栈的生长方向与内存的生长方向相反,因

此在堆栈中压入的数据超过预先给堆栈分配的容量时,就会出现堆栈溢出,从而使得程序运行失败;

如果发生栈溢出的是大型程序还有可能会导致系统崩溃。


看一段简单程序的执行过程中对堆栈的操作和溢出的产生过程。

#include <stdio.h>
int main()
{
char name[16];
gets(name);
for(int i=0;i<16&&name[i];i++)
printf(,name[i]); 
}

编译上述代码,输入“hello world!”结果会输出hello
world!,其中对堆栈的操作是先在栈底压入返回地址,接着
将栈指针EBP入栈,此时EBP等于现在的ESP,之后ESP减
16,即向上增长16个字节,用来存放name[]数组


执行完gets(name)之后,堆栈中的内容如见图


最后,从main返回,弹出ret里的返回地址并赋值给EIP,CPU继续执行EIP所指向的命令。

如果我们输入的字符串长度超过16个字节,例如输入:hello world!AAAAAAAAAAA,则当执行完gets(name)之
后,堆栈的情况如图


由于输入的字符串太长,name数组容纳不下,只好向堆栈的底部方向继续写‘A’。这些‘A’覆盖了堆栈的老
的元素,从图4可以看出,EBP,ret都已经被‘A’覆盖了。从main返回时,就必然会把‘AAAA’的ASCII码——
0x41414141视作返回地址,CPU会试图执行0x41414141处的指令,结果出现难以预料的后果,这样就产

生了一次堆栈溢出。假如使用的操作系统为Win9X的话,会得到那个经典的“该程序执行了非法操作”的对话框。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值