漫花馨雨吧 关注:2贴子:113
  • 1回复贴,共1页
堆栈是一个在计算机科学中经常使用的抽象数据类型。堆栈中的物体具有一个特性: 最后一个放入堆栈中的物体总是被最先拿出来,
这个特性通常称为后进先处(LIFO)队列. 堆栈中定义了一些操作. 两个最重要的是PUSH和POP。 PUSH操作在堆栈的顶部加入一 个元素。POP操作相反,
在堆栈顶部移去一个元素, 并将堆栈的大小减一。


1楼2012-07-29 10:24回复

    堆栈溢出就是不顾堆栈中分配的局部数据块大小,向该数据块写入了过多的数据,导致数据越界,结果覆盖了老的堆栈数据。 或者解释为
    在长字符串中嵌入一段代码,并将过程的返回地址覆盖为这段代码的地址,这样当过程返回时,程序就转而开始执行这段自编的代码了。
      比如如下这段程序:
      #include<stdio.h>
      int main()
      {
      char name[8];
      printf("Please type your name:");
      gets(name);
      printf("Hello.%s!",name);
      return 0;
      }
      编译并且执行,输入ipxodiAAAAAAAAAAAAAAAA,执行完gets(name)之后,堆栈如下:
      内存底部 内存顶部
      name EBP ret
      <-------[ipxodiAA][AAAA][AAAA]............
      ^&name
      堆栈顶部 堆栈顶部
      由于我们输入的name字符串太长,name数组容纳不下,只好向内存顶部继续写'A'。由于堆栈的生长方向与内存的生长方向相反,这些'A’覆盖了堆栈的老的元素。'EBP
    ret’都被'A'覆盖了。在main返回的时候,就会把'AAAA'的ASCII码:0x41414141作为返回地址,CPU会试图执行0x41414141处的指令,结果出现错误。这就是一次堆栈溢出!
    


    2楼2012-07-29 10:25
    回复