strcpy漏洞分析

前段时间发现一个有趣的代码:

	char str[1];
	strcpy(str, "wwwwwwwwwwwwwwwwwwwww"); 
	printf("%s", str);
	getchar();

运行结果:

大家可以看到,我使用strcpy向一个长度为1的数组赋一个长度为21的字符,并且被赋值了,还被打印了出来!

那么下面来解释一下为什么会产生这样的原因!

在CPU看来内存是连续的,是一组线性的地址空间!

而C++编译器是不会检查越界问题的,这里我使用的是VSC++编译器(VS是根据后缀名调用不同的编译器)

strcpy属于标准C库代码,这个函数也不会去检查越界问题,这个函数会直接将内存中的值更改!

我们可以断点调试看一下内存:

首先先将数组的首地址打印出来:

printf("%p", str);

最后下断点

运行结果:

在选择VS自带的内存视窗

注意此选项只有在断点调试阶段才有效

将地址输入进去:

可以看到这个地址空间里有很多字节,有的字节是有数据的,这些数据可能是没有被初始化的随机数也可能是已经分配好了数据的字节,也有基于内存对齐而分配的地址空间,可以看到上面有很多数据为00的字节,这些都是基于内存对齐而分配的,刚刚的str数组并没有被初始化,但是它只占一个字节,所以可以确定第一个字节即使它的内存空间

注意此时断点在strcpy处,也就是说此时这个函数还没有被执行

我们按F10调试运行

走了一步此时在看地址空间:

可以看到strcpy把不属于str的地址空间给改掉了,上面说过内存中地址是连续的,strcpy把连在str后面的地址空间里的内存给改掉了!

由此可以知道strcpy函数的编写思路是将一个地址开始的空间修改,修改大小为数值大小,且不会去检查数值大小是否超出变量空间大小!

要知道,操作系统允许程序随意修改访问自己进程空间下的内存,那么有可能会造成,其他变量内存数据混乱的现象,如果你数值在给大一点儿超出进程下的空间大小,访问到其他进程里去了,那么操作系统会就给杀掉,因为在虚拟内存的保护模式下!

那么在来解释一下,为什么printf打印时会将其打印出来,printf也不会检查边界,它只看内存中\0,也就是说,它的编写思路是:从内存中的某个地址开始读取数据,直到遇到\0结尾!

我们数组默认也是有\0的就像上面的str[1],这个数组是无法赋值的,因为它只能存储一个\0!

我们来赋值试试

看,我们明明赋予了一个d的字节,却告诉我们,我们赋予了两个字节的数据,也就是说编译器默认的给我们增加了一个\0在后面!

所以我们定义字符数组变量时,即使给予了256个大小字节空间实际只能访问255个,因为最后一个用于结尾!

所以这也是为什么printf能打印出来的原因,我们来修改一下赋值,在中间一行加入\0试试:

运行结果:

可以看到printf在地址空间里不停的打印数据,直到遇到了\0

当我们在编程时很多IDE都会检查一些字符后面是否带有\0,一旦没有编译器可能会给你自动加上,也可能会报错,不然的话printf会把整个内存里的东西根据占位符的格式都给打印出来!

char *指针在分配时末尾的一个字节,也会隐式的被修改为\0

从上分析可以得出,strcpy和printf是不安全的所以微软公司推出了strcpy_s和printf_s函数,当然也有很多其他的函数,凡是微软测试出来认为不安全的函数都会被重写,其次微软默认是不允许我们使用这些不安全的函数的,需要增加一些宏开关才行!

这里我们将strcpy改成strcpy_s

在运行一下:

直接报中断,越界错误!

 

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

17岁boy想当攻城狮

感谢打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值