一、实验目的

(1)了解程序调入内存中的分段情况
(2)掌握堆、栈、BSS段缓冲区溢出的原理
(3)了解缓冲区溢出的常见攻击手段

二、实验原理

在一个堆栈里边申请两块存储空间,处于低地址的buf1和处于高地址的buf2。在buf2当中,存储了一个名为myoutfile的字符串,用来存储文件名;buf1用来接收输入,同时将这些输入字符写入到buf2存储的文件名myoutfile所指向的文件中。通过malloc函数,在内存中申请了两个堆的存储空间。接着定义了diff变量,它记录了buf1和buf2之间的地址距离,也就是说buf1和buf2之间还有多少存储空间。fopen语句将buf2指向的文件打开,打开的形式是追加行,用了关键字“a”。即打开这个文件后,如果这个文件是以前存在的,那么写入的文件就添加到已有的内容之后;如果是以前不存在,用fprint语句将buf1中已经获得的语句写入到这个文件里,然后关闭文件。

三、实验过程

(1)输入71个数字,因c语言默认会在字符串后面加入\0结束符来表示字符串输入结束,所以相当于占用了72个字节空间。那么buf1全部使用完毕,并存储在名称为myoutfile的文件里。windows堆溢出实验

(2) 输入72个数字,因c语言默认会在字符串后面加入“\0”结束符来表示字符串输入结束。所以相当于占用了73个字节空间。那么buf1全部使用完毕,并且最后一个“\0”因buf1的内存空间用完,按内存地址增加的顺序存入下一个字节空间,即buf2的第一个字节空间存储了“\0”。当程序打开buf2变量所指定的文件名时,读到第一字节为“\0”,表示读取结束。程序读到值为空,出错。windows堆溢出实验

(3)输入75个数字,因c语言默认会在字符串后面加入“\0”结束符来表示字符串输入结束。所以相当于占用了76个字节空间。那么buf1全部使用完毕,并且 “234\0”因buf1的内存空间用完,按内存地址增加的顺序存入下一个字节空间,即buf2的前四个字节空间存储了“234\0”。当程序打开buf2变量所指定的文件名时,读到为“234/0”,表示读取结束。程序buf2存储的文件名被覆盖为234。windows堆溢出实验

从内存分配来看,buf1填充了大于72个字节的字符串,余下的”345\0”就扩展到了buf2的空间之中。同样,字符串要以\0表示结束。但是原先的buf2中的内容也有一个\0表示字符串的结束,但是这个\0落在了”345\0”的后边,所以系统当看到”345”后边的\0时就认为字符串结束了,所以输出的是345。而读取buf1的内容时候,到存储空间结束也没有遇到\0,那么它就继续往下读,直到遇见了\0,所以它读取的长度已经超过了它本身分配的存储空间的长度。这样就构造了一个新的文件名覆盖了原先的内容,从而输出到一个我们定制的文件中,产生了基于堆的溢出。

相关文章: