C语言的strcpy()函数与堆栈溢出
最近在一个帖子中看到一道题:
问:下面是一个简单的密码保护功能,你能在不知道密码的情况下将其破解吗?
#include<stdio.h>
#include<string.h> int main(int argc, char *argv[]) { int flag = 0; char passwd[10]; memset(passwd,0,sizeof(passwd)); strcpy(passwd, argv[1]); if(0 == strcmp("apple", passwd)) { flag = 1; } if(flag) printf("\n Password cracked \n"); else printf("\n Incorrect passwd \n"); return 0; }
我个人感觉这道题对于我这种C语言半瓶子水的人来说还是挺有意思的,(╯▔皿▔)╯
其实答案也不难,就是利用了strcpy()函数的漏洞:
简单来说就是用户在向passwd数组传值时没有考虑会溢出的情况。如果用户输入的passwd足够长,导致不仅溢出了passwd的空间而且还“侵犯”了flag变量的空间,造成flag的值不为0。最终也就导致了判断的失效:passwd不匹配,但是flag不为0。
在程序设计中如何避免出现此情况
——
可能有同学发现,在运行上面的程序时,如果输入的长度过长有可能会终止并报错。
这其实是有的IDE在编译时已经为你加入了一种检测堆栈溢出的机制——stack protector机制。
gcc(4.9)中提供了关于stack protector机制的多个编译选项:
-fstack-protector 启用堆栈保护,不过只为局部变量中含有 char 数组的函数插入保护代码。 -fstack-protector-all 启用堆栈保护,为所有函数插入保护代码。 stack-protector-strong 在stack-protector基础上,增加本地数组、指向本地帧栈地址空间保护。
stack-protector-explicit 在stack-protector基础上,增加程序中显式属性"stack_protect"空间。 -fno-stack-protector 禁用堆栈保护。
所以如果你的编译器默认加入了此保护机制,你需要在gcc编译时加入-fno-stack-protector,才能看到破解密码的效果(●'◡'●)
进而可以很明显的得到,要避免此种情况:
1 可以使用-fstack-protector或其它适合你的保护选项来避免堆栈的溢出。
2 从代码编写方面来看,可以更多的使用strncpy()结合strlen()的判断。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」