zoukankan      html  css  js  c++  java
  • 基于数组越界的缓冲区溢出

    文章来源:https://blog.seclibs.com/基于数组越界的缓冲区溢出/

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

    在c语言中,数组必须是静态的,也就是在定义的时候必须明确数组的大小,在根本上来说,这个是堆栈提升的原因,只有在数组的大小确定的时候,才能明确堆栈到底要提升多少,如果数组的大小是动态变化的,就极容易发生缓冲区溢出;而且c语言也不具备Java等语言中静态分析的功能,不会去检测数组是否有上溢或者下溢,其边界的检验是有程序员负责的,所以这就造成了一些问题,我们可以通过数组越界来改变一些内容。

    首先来看一下这次的实验程序

    正常来说,test1函数并没有被调用,所以是不会打印出12345的,而实际的情况却不是这样的

    造成这样的情况,就是由于数组越界而造成的缓冲区溢出,这其中还有一个编译器的坑,在后面再解释。

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

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

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

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

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

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

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

    文章首发公众号和个人博客

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

    博客:https://blog.seclibs.com/

  • 相关阅读:
    求X的N次乘方
    用辗转相除法求两个正整数的最大公约数
    求两、三个数中较大者的函数
    电文加密问题
    C#纯数学方法递归实现货币数字转换中文
    查找二维数组的查找之杨氏矩阵
    IT公司笔经面经
    排序2计数排序,桶排序
    windows Concurrency Runtimewindows的并行编程模型
    <c++ primer>第五部分 高级主题
  • 原文地址:https://www.cnblogs.com/wuxinmengyi/p/12315263.html
Copyright © 2011-2022 走看看