小心使用strcpy函数时越界
strcpy()函数应该是我们用的比较常用的一个函数,基本功能是将一个字符串拷贝到我指定的内存空间。但是要复制的字符串长度超过这段内存空间的话,结果可能是未知的。
比如以下的程序:
#include <stdio.h>
#include <string.h> int main(int argc, char *argv[])
{
int flag = 0;
char password[5] = {'\0'}; strcpy(password, argv[1]); if(0 == strcmp("root", password))
{
flag = 1;
} if(flag)
{
printf("密码被破解了\n");
}
else
{
printf("密码破解失败\n"); }
return 0;
}
上述程序的功能是一个简单的密码破解功能,也就是判断用户输入的密码是不是”root“,如果是,则输出密码被破解了,否则提示用户密码破解失败!字符串数组argv[1]的内容已经事先设定为”123456789“。运行结果如下:
程序输出密码被破解了,说明if(0 == strcmp("root", password)) 这个语句判断通过了,将flag设为1了。但是我们的疑问是,”root“明明和”123456789“不一样啊,为什么if判断会通过呢?我们使用VC 6.0来调试下,如下:
从调试中可以看到,在执行到” if(0 == strcmp("root",
password)) “时,flag的值已经变成57了,是不是很奇怪?
仔细看调试过程,password[0]这个字符的地址是”0x0012ff74“,password[1]这个字符的地址是”0x0012ff75“,以此类推,到了flag的地址是”0x0012ff7c“。也就是说,从password[0]开始,到flag,这是一段连续的内存区域,这段内存区域一共是0x0012ff7c
- 0x0012ff75 = 9个字节大小,password数组占去了5个字节大小,也就是从地址”0x0012ff74“到地址”0x0012ff78“存放的都是password的字符。而argv[1]有”123456789“一共9个字符,将前5个字符给了password数组后,剩余的”6789“这4个字符,就存放在地址”0x0012ff79“到”0x0012ff7c“这端内存区域中。而flag的地址是”0x0012ff7c“,所以flag就存放了字符”9“,而字符”9“的ASCII码值是57,所以flag最终的值就是57。这样的话,即使用户输入的密码不是”root“,但是程序密码也被破解了,这就是使用strcpy函数的一个陷阱,即strcpy函数不会去检查第一个参数的存储区域是否容得下第二个参数的存储容量。
小心使用strcpy函数时越界的更多相关文章
- strcpy函数
不调用C/C++库函数,编写strcpy()函数. char * my_strcpy(char *strDest,const char *strSrc) { char *p=strDest; whil ...
- strcpy函数用法
字符串是数组类型,不能通过赋值运算进行,要通过strcpy进行拷贝,其中目的字符串必须是字符串变量,源字符串可以是常量,复制后源字符串保持不变. strcpy()是C中的一个复制字符串的库函数,在C+ ...
- strcpy 函数的实现
原型声明:extern char *strcpy(char *dest,const char *src); 头文件:string.h 功能:把从src地址开始且含有‘\0’结束符的字符串赋值到以d ...
- strcpy函数的实现
strcpy函数的实现 大家一般认为名不见经传strcpy函数实现不是很难,流行的strcpy函数写法是: char *my_strcpy(char *dst,const char *src) { a ...
- strcpy函数和strncpy函数的区别
strcpy函数和strncpy函数的原型介绍在我的另一篇文章中介绍了,见strcpy,strncpy,strlen等函数原型 strcpy:字串复制 原型:char *strcpy(char *de ...
- memcpy、memmove、memset及strcpy函数实现和理解
memcpy.memmove.memset及strcpy函数实现和理解 关于memcpy memcpy是C和C++ 中的内存拷贝函数,在C中所需的头文件是#include<string.h> ...
- strcpy函数的C/C++实现
2013-07-05 14:07:49 本函数给出了几种strcpy与strncpy的实现,有ugly implementation,也有good implementation.并参考标准库中的imp ...
- strcpy函数导致release版程序崩溃
最近在写一个读取模型文件的小程序.很随意的使用了strcpy函数进行char字符数组的拷贝,这个数组是需要传递给PostMessage作为WPARAM的参数.代码部分如下: char pStrCurr ...
- 第九十六题(编写strcpy 函数)
96.08 年中兴校园招聘笔试题 1.编写strcpy 函数 已知strcpy 函数的原型是 char *strcpy(char *strDest, const char *strSrc); 当中st ...
随机推荐
- 通过Chrome扩展来批量复制知乎好友
1.初始化文件 Chrome 官方扩展教程地址 新建一个文件夹 zhi-follow 下图中 1 部分为 默认的图标3种尺寸 会显示在 Chrome 中 2. 定义按钮样式 页面上会有 ...
- SQLServer 订阅过期解决方法
原文:SQLServer 订阅过期解决方法 由于分发数据库执行一个较长的事务,达到了系统预定的72小时,导致了该订阅过期,数据库分发代理已不可再启用,提示错误如下: 错误信息:已将此(这些)订阅标记为 ...
- 微信小程序把玩(二十四)toast组件
原文:微信小程序把玩(二十四)toast组件 toast消息提示框,可用在提示一些信息,比如清楚缓存给用户一个友好的提示!或操作一些请求不想让用户有什么操作,toast也可以做到因为toast显示时其 ...
- NAudio的使用说明
官方网站:http://naudio.codeplex.com/ 源码:https://github.com/naudio/NAudio NuGet安装: Install-Package NAudio ...
- UWP-磁贴初识
原文:UWP-磁贴初识 简单的磁贴内容实现,来自 Bob 的视频. 为一个按钮添加点击事件,来更新磁贴. private void ChangeTileContentButton_Click(obje ...
- JS function document.onclick(){}报错Syntax error on token "function", delete this token - CSDN博客
原文:JS function document.onclick(){}报错Syntax error on token "function", delete this token - ...
- 仿win7窗体自动顶部最大化左侧右侧半屏效果(改写nativeEvent,使用AdjustWindowRectEx)
#include "HMainWindow.h" #include <QApplication> #ifdef Q_OS_WIN #include <qt_win ...
- C#的Task、async、await关键字
Task,一个类,可以执行一个方法,构造函数需要传一个Action类型的委托,Action类型的委托是可以拥有多个参数,没有返回值的. Task<T> Task的泛型,构造函数传入一个Fu ...
- Anbox —— 在 Linux 系统中运行 Android 应用
具有以下特性: 没有限制:由于 Anbox 运行着整个 Android 系统,所以理论上任何应用都可以在其中运行 安全:Anbox 将 Android APP 放进一个密封的盒子中,无需直接访问硬件或 ...
- 使用Netty实现通用二进制协议的高效数据传输
Netty是一个高性能的NIO通信框架,提供异步的.事件驱动的网络编程模型.使用Netty可以方便用户开发各种常用协议的网络程序.例如:TCP.UDP.HTTP等等. Netty的最新版本是3.2.7 ...