基于数组越界的缓冲区溢出

文章来源:blog.seclibs.com/基于数组越界的缓冲区溢…程序员

上一篇文章说了函数调用时候的堆栈变化,这里就基于这个内容来验证一下基于数组越界的缓冲区溢出。数组

在c语言中,数组必须是静态的,也就是在定义的时候必须明确数组的大小,在根本上来讲,这个是堆栈提高的缘由,只有在数组的大小肯定的时候,才能明确堆栈到底要提高多少,若是数组的大小是动态变化的,就极容易发生缓冲区溢出;并且c语言也不具有Java等语言中静态分析的功能,不会去检测数组是否有上溢或者下溢,其边界的检验是有程序员负责的,因此这就形成了一些问题,咱们能够经过数组越界来改变一些内容。函数

首先来看一下此次的实验程序3d

正常来讲,test1函数并无被调用,因此是不会打印出12345的,而实际的状况却不是这样的cdn

形成这样的状况,就是因为数组越界而形成的缓冲区溢出,这其中还有一个编译器的坑,在后面再解释。blog

咱们直接在数组处下断点,前面的提高堆栈等操做就不细说了,前一篇文章已经走过一边流程了,这里直接给出到这一步的堆栈图。get

而后咱们看一下编译器是如何处理数组赋值的内容的编译器

通过这段赋值操做,此时堆栈已经变成了下图,这里单独从中拎出来10行方便观看。博客

经过堆栈图咱们能够很清晰的看到,明明只有8个数,它确是从ebp-24h开始排的,也就是说ebp-4的位置是没有使用的,这个也就是前面所说的坑,通过查询资料,发现从vs2010开始,ebp-4就都没有使用,具体是用来作什么的,暂时还不清楚,因此若是这里你使用的是vc6.0的话,这里就是从ebp-4开始排的。it

好了说了上面那个坑,接着回来讲堆栈图,在上一篇文章里咱们已经很清楚函数在调用的时候会先把call语句的下一行地址压入栈中,因此图中b[10]的位置也就表明了ret返回地址的位置,在vc6.0中此处应该是b[9],若是咱们将这个地址替换为咱们想让程序到达的位置,也就能够控制程序的运行轨迹了。

在后面的操做就是将test1函数的地址赋给了b[10],也就代替了以前函数的返回地址,这个函数在执行完成后便会返回test1函数的位置081137Ah。

也就达到了缓冲区溢出的效果。

文章首发公众号和我的博客

公众号:无意的梦呓(wuxinmengyi)

博客:blog.seclibs.com/

相关文章
相关标签/搜索