简单的缓冲区溢出实验

在VS2008中进行的缓冲区溢出实验

其中代码如下所示:

在代码中,没有任何地方调用了why_here函数,但是该程序的执行结果如下图所示:

image

可以看到,why_here函数被执行了,我们来看看调试过程中反汇编的结果:

在程序的执行过程中,我们在监视窗口中,查看如下变量的值:

image

通过汇编代码我们可以看到,进入main函数后,堆栈操作过程如下:

1.将ebp压栈:push ebp

2.将ebp指向esp的位置:mov ebp, esp

3.将esp减去0xCCh字节:sub esp, 0CCh

4.将ebx, esi, edi 压栈:push ebx; push esi; push edi;

5.将ebp和esp+8的位置初始化为:0xCCCCCCCCh: 汇编代码9~12行

进入main函数过后的堆栈变化如下图所示:

image

通过上图可以发现,&buff[3]的地址就是main函数的返回地址eip存放的地方,我们在C代码的18行将buff[3]赋值为why_here的地址,所以eip就被修改成了why_here的地址,

这样在main函数返回的时候,就会跳转到why_here执行。如果这段代码的是恶意代码,那么将会对系统造成严重的损害。

总结:

一直都很懒,不想记录技术心得,今天又把缓冲区溢出拿出来学习了一下,虽然很简单,感觉还是受益匪浅。一定要理清楚x86堆栈的结构,要学会使用vs进行调试,在看C语言不行的时候就要进行反汇编。

这个程序,以前直接将buff[0]~buff[0x3d]的位置都赋值为why_here的地址,这样的话vs2008在运行的时候就会报错,说检查到堆栈溢出,这应该是ebp也被破坏了的原因。还有个问题就是:

我直接对buff[3]=(int)why_here;赋值或者对buff[3]=0x41111d;赋值都可以跳转到why_here的函数体。C语言代码的18行。

刚开始,我一直不明白,把why_here赋值给buff[3]其实得到的值也是0x41111d,这样就出现了将0x41111d和0x004113c0赋值给buff[3]都可以跳转到why_here的情况,即一个函数对应了两个地址。这让我非常的疑惑。

让我们来看看汇编代码的0x41111d和0x004113c0分别存放了什么,如下图所示:

0x41111d存放的是一条跳转指令,这条指令的目标地址是why_here的实际地址,即0x4113c0.

image

0x4113c0存放的是why_here的实际地址:

image

我们注意到0x41111d位置处,其实是一个函数的跳转表,

当我们去某个函数的名字,如why_here的时候,我们得到的是这个跳转表中某一项的地址,而不是函数的实际地址。

至于为什么这样做,我觉得应该和编译器有关,个人猜想:

1.把函数都放到一个跳转表中,只要跳转表的地址不变,那么函数实际存放的位置即使变了也无所谓,只需要修改jmp指令的目标地址就行了。

2.用户把函数名赋值给一个整形变量,得到的是跳转表中的地址,而不是实际存放函数的地址,如果怀有恶意的程序员修改了这个地址的话比直接修改实际地址带来的危害应该更小。

link:http://www.cnblogs.com/justinzhang/archive/2011/09/21/2184093.html

注:图片会被自动加水印 大家若觉得看的不舒服 可以去上方的LINK查看原文

本文由网络安全攻防研究室(www.91ri.org)信息安全小组收集整理,转载请注明出处。