鱼C论坛

 找回密码
 立即注册
查看: 1200|回复: 10

[已解决]数组越界为什么不能覆盖掉栈区的数据?

[复制链接]
发表于 2021-1-30 17:54:13 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
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[10]{};
        do
        {
                i3[i] = a();
                i2 =i2+ i3[i];
                
        } while (i3[i++]);
        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([0])
10008    2    EAX([1])
1000C    3    EAX([2])
10020    4    EAX([3])
10024    5    EAX([4])
10028    6    EAX([5])
1002C    7    EAX([6])
10030    8    EAX([7])
10034    9    EAX([8])
10038   10   EAX([9])
1003C   11   输入的值
10040   12   和
10044   13   循环的次数
10048   14   CALL前的EBP
1004C   15   CALL返回的地址
最佳答案
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[10];
        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[i] << "]";
                i3[i] = a();
                i2 =i2+ i3[i];
                
        } while (i3[i++]);
        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;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-1-30 19:50:32 | 显示全部楼层
用vc6.0的调试界面为你讲解。见图。

未命名.JPG

未命名1.JPG
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-1-30 20:05:52 | 显示全部楼层
接上楼,如果你在第12次循环的时候输入11会怎么样?那么计数器 i  的值变成 11,i++后变成12
接下来继续循环两次,就先把 [EBP] 的值覆盖了,然后就可以覆盖 [返回地址] 了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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函数。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

我想到的是第15次输入ADD的地址,然后0结束,它就会ret到ADD的地址上去,然后运行了ADD,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-1-30 22:36:55 From FishC Mobile | 显示全部楼层
2736946915 发表于 2021-1-30 21:55
我想到的是第15次输入ADD的地址,然后0结束,它就会ret到ADD的地址上去,然后运行了ADD,

如果你的分析是对的。你在覆盖循环计数i的时候输入的是13,++i后是14,因此在第14次循环时就覆盖了返回地址。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

第十四个就崩溃了大佬能加下扣么,我没权限发消息
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-1-30 23:08:33 From FishC Mobile | 显示全部楼层
本帖最后由 xieglt 于 2021-1-31 09:12 编辑
2736946915 发表于 2021-1-30 23:07
第十四个就崩溃了大佬能加下扣么,我没权限发消息


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-1-30 23:19:14 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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[10];
        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[i] << "]";
                i3[i] = a();
                i2 =i2+ i3[i];
                
        } while (i3[i++]);
        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;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-1-31 09:13:10 | 显示全部楼层
运行结果
无标题.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-12 01:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表