• 简单理解栈溢出

    今天,发现了一个简单的程序(其实也不简单哈),首先,拿到了这个程序,是exe的,能在win运行,这点应该没问题,都是对未知的探索,然后,就点开了它,它的效果如下:

    helloworld

    这,????,怎么全是“Hello Word”,盲猜,这个程序的作者写了一个无限的循环语句,当然,先关闭这个程序。

    分析

    把它拖到IDA中,反编译,查看一下它的伪代码,很快,就找到了Hello World的输出地方

    for

    的确啊,很快可以看出,Hello Word是从for循环puts函数输出的,可是,为啥它会无限输出,不应该当i的数值通过i++到7就结束了吗?为何不会是预期效果。

    首先,理解一下程序,了解一下这个程序的目的,从根源上找到这个问题的原因。

    • 第一行声明了一个int类型的数组arr,声明里面有6个元素
    • 第二行就是简单的声明了一个int类型的i,整型
    • 第六至十一行代码的作用是逐个对数组arr的下标为0-5的元素,分别赋值为0,1,2,3,4,5
    • 第12到17行,就是一个for循环的代码块,并且第12行对for的循环做出了条件限制,
      1. 设置i的数值为0
      2. 条件是i的大小 小于等于7的时候就执行循环语句
      3. 每一次循环以后对i的数值加一
    • 在for的代码块里,每一次循环,将数组的下标为i的元素的值改为0,并且输出Hello World

    问题

    了解了这个函数的代码,可它到底有啥问题呢?

    其实也很简单:

    • 它声明了一个数组,但是只设置了6个元素的容纳空间
    • for循环里,i的数值能够通过++i6,7,然后再对arr的第6,7的元素赋值为0
    • 问题就是arr数组的空间只有6个,对下标元素为1至6赋值为0没有问题,可是对第7个元素赋值呢
    • 简单点来说,就是对一个不存在的元素赋值,并且设置为0,代码赋值成功了

    对于这个不存在的7号元素赋值,事实上是不存在的,赋值到哪里去了呢?

    这也不难,答案是赋值给了i,就是说,用

    1
    arr[7]=0;

    然而,结果却是

    1
    i=0;

    要知道,这个i在第7次循环中,它的数值是7,在执行了arr[i]=0后,i就等于0了,然后i在下一次的for循环的判断i<=7就满足条件,进而开启了下一次,再下一次的循环,输出无限的Hello World

    原因

    解释一下原因

    声明函数里面的变量,都是从高地址到低地址建立的,

    c

    由此先后入栈,而题目的arri,也是遵循这个原理,不过数组声明了它的长度,也就是6个,可是for循环超出了6,用arr[7]=0向arr写入数据,但是写到了与arr相邻的i上面,从而表现出了数据从arr的高地址,溢出到了与arr相邻的低地址i,所以数据溢出后,i就变成了0,而不是arr的第7个元素变成了0。内存中没有第7个元素存在,与第6个元素相邻的就是它的下一个变量i对应的地址。

    adress

    图中的arr与i的地址是相邻的,所以数据超出了arr的6的范围,就溢出到了i

    然后就是开始图示的无限的Hello World 的循环。

    最后

    本文如有问题,请指正。

    程序来源:道格安全

    本文by:qiukes@88.com

    上一篇:
    python自动android操作
    下一篇:
    一招解决Android上Z3的安装问题
    本文目录
    本文目录