2736946915 发表于 2021-1-30 17:54:13

数组越界为什么不能覆盖掉栈区的数据?

void add()
{
        std::cout << "add"<<std::endl;
}

int a()
{
        int integer{};
        std::cout << "请输入一个整数:";
        std::cin >> integer;
        return integer;
}

int b()
{
        int i{};
        int i2{};
        int i3{};
        do
        {
                i3 = a();
                i2 =i2+ i3;
               
        } while (i3);
        return i2;
}

int main()
{
       
        std::cout << "\n    add地址 \n\n " << add << std::endl;
        std::cout << "\n    b地址 \n\n " << b << std::endl;
        std::cout << "\n    a地址 \n\n " << a<< std::endl;
        std::cout << b();
}

00A61063 83 EC 34             sub         esp,34h


大佬们帮忙看看,要利用b()来调用add函数,利用数组越界第15次输入地址为什么还不能覆盖call返回的地址?下面是我的分析的数据,汇编太多就算了。

10000
10004    1    EAX()
10008    2    EAX()
1000C    3    EAX()
10020    4    EAX()
10024    5    EAX()
10028    6    EAX()
1002C    7    EAX()
10030    8    EAX()
10034    9    EAX()
10038   10   EAX()
1003C   11   输入的值
10040   12   和
10044   13   循环的次数
10048   14   CALL前的EBP
1004C   15   CALL返回的地址

xieglt 发表于 2021-1-30 19:50:32

用vc6.0的调试界面为你讲解。见图。



xieglt 发表于 2021-1-30 20:05:52

接上楼,如果你在第12次循环的时候输入11会怎么样?那么计数器 i的值变成 11,i++后变成12
接下来继续循环两次,就先把 的值覆盖了,然后就可以覆盖 [返回地址] 了

2736946915 发表于 2021-1-30 21:53:08

xieglt 发表于 2021-1-30 20:05
接上楼,如果你在第12次循环的时候输入11会怎么样?那么计数器 i的值变成 11,i++后变成12
接下来继续循 ...

是多循环了2次啊,循环里面一共13个参数,10个数组的值输入完后,第11个把数据库的值覆盖,第12个把和覆盖,第13个把循环次数覆盖,第14个就是push ebp的值覆盖,第15个就是地址,但是会报错,没有调用ADD函数。。。

2736946915 发表于 2021-1-30 21:55:39

xieglt 发表于 2021-1-30 20:05
接上楼,如果你在第12次循环的时候输入11会怎么样?那么计数器 i的值变成 11,i++后变成12
接下来继续循 ...

我想到的是第15次输入ADD的地址,然后0结束,它就会ret到ADD的地址上去,然后运行了ADD,

xieglt 发表于 2021-1-30 22:36:55

2736946915 发表于 2021-1-30 21:55
我想到的是第15次输入ADD的地址,然后0结束,它就会ret到ADD的地址上去,然后运行了ADD,

如果你的分析是对的。你在覆盖循环计数i的时候输入的是13,++i后是14,因此在第14次循环时就覆盖了返回地址。

2736946915 发表于 2021-1-30 23:07:37

xieglt 发表于 2021-1-30 22:36
如果你的分析是对的。你在覆盖循环计数i的时候输入的是13,++i后是14,因此在第14次循环时就覆盖了返回地 ...

{:10_266:}第十四个就崩溃了{:10_266:}大佬能加下扣么,我没权限发消息

xieglt 发表于 2021-1-30 23:08:33

本帖最后由 xieglt 于 2021-1-31 09:12 编辑

2736946915 发表于 2021-1-30 23:07
第十四个就崩溃了大佬能加下扣么,我没权限发消息

3533050047 发表于 2021-1-30 23:19:14

{:10_277:}

xieglt 发表于 2021-1-31 09:12:37

2736946915 发表于 2021-1-30 23:07
第十四个就崩溃了大佬能加下扣么,我没权限发消息

#include <iostream>
#include <string.h>

void add()
{
        int i;
        std::cout << "Hello,World"<<std::endl;
        std::cin >> i;
}

int a()
{
        int integer;
        std::cout << "请输入一个整数:";
        std::cin >> integer;
        return integer;
}

int b()
{
        //调整变量定义顺序,把数组定义在前面,不会在越界的时候覆盖计数器 i
        int i3;
        int i = 0;
        int i2 = 0;
        int * p = i3 +10;

        std::cout << "栈内容:" <<std::endl ;
       
        //把栈的内容输出,以便找到函数返回地址
        for(i=0 ; i< 5 ; i++)
        {
                std::cout << "[" << p << "]" << (int*)*p << std::endl;
                p++;
        }
       
        i = 0;

        do
        {
                //输出数组地址,与前面输出对比,确认你要覆盖的是返回地址
                std::cout << "[" << &i3 << "]";
                i3 = a();
                i2 =i2+ i3;
               
        } while (i3);
        return i2;
}

int main()
{
        //输出十进制函数地址
        std::cout << "add地址:" << add << "    " << (int)add << std::endl;
        std::cout << "b地址:" << b << "    " << (int)b << std::endl;
        std::cout << "a地址:" << a << "    " << (int)a<< std::endl;
        std::cout << b();
       
        return 0;
}

xieglt 发表于 2021-1-31 09:13:10

运行结果
页: [1]
查看完整版本: 数组越界为什么不能覆盖掉栈区的数据?