缓冲区溢出简单原理与实现。
实验环境:Windows XP 实验工具:VC++6.0、OD、IDA Pro 7
首先通过VC++6.0编写简单程序。

使用Win32 Debug模式进行编译。
找到对应生成的.exe程序,查看是否可正常运行。

重新编写并生成Test2.exe。


Test1与Test2的区别仅仅只有对buffer数组长度定义不同,前者为10,可容纳字符“huanchong”,而后者仍未是,字符为“huanchongchuanchong”,超出定义长度。
Test1运行后回车可结束程序,而Test2运行后回车则出现错误。

对两者进行分析。
将Test1分别拖入OD和IDA中。


使用IDA查找main函数位置,为401010。

返回OD,查找主函数所在位置,并进行断点标注。

返回IDA,在main函数位置处使用交叉引用查找上一级跳转,寻找call语句。寻找call语句,因分析main函数前后栈空间的变化。

在OD中查找401694位置并设置断点。

在OD中使程序运行至call语句位置。

可看到call语句所在位置为401694,下一位置为401699。
程序在进入每一个call之前,都会将它的下一条语句地址入栈,然后在执行call语句。当call语句执行完后,再将地址出栈,这个地址也称为“返回地址”。
执行call语句,观察前后的栈的变化情况。


可见,401699地址已入栈,程序也运行至main函数位置。
接下来继续运行程序,查看程序在进行分配空间时,栈变化情况。

栈空间出现两个字符串,地址为401031,从IDA中可得知,401031为strcpy函数位置。栈内12FF1C与12FF20分别时buffer和name参数。而下方的12FF84和12FF80分别是返回地址和父函数EBP。
程序中定义了数组变量空间,因此需为其分配相应的空间,地址401013为分配空间地址。

继续运行,当程序运行至401028位置时,发现分配的栈地址空间被0xCC填满,原因是因为程序为了容错性和自身的健壮性,利用int 3断点填满区域。若出现位置程序跳转至这里,也不会发生崩溃情况。

使用IDA查找strcpy函数位置,为401031。

在OD中查看函数运行前后栈空间变化。可以看到12FF74已经被写入“huanchong”字符串。

对比一下Test2过长字符串在执行函数前后,栈空间变化情况。可发现执行前,程序中返回地址以及父函数EBP存在,执行后便被过长字符串顶掉。


继续执行至return函数位置,对比Test1与Test2。可发现Test1地址12FF84中依旧为401699返回地址,而Test2地址12FF84中却变为00676E。


继续运行Test1与Test2,查看区别。可发现Test1程序正常,而Test2程序则转向空白地址00676E。


若继续运行Test2,则出现错误。

总结,当输入的字符超过定义长度时,便造成缓冲区溢出错误。
网友评论