sprintf 使用不当越界修改内存
2016-01-28 10:57
176 查看
sprintf “%02X” 导致越界修改内存
使用sprintf 中二进制转换16进制(“%02X”)时,传入参数要在char型的范围内;同理,在做其他的转换时,对应的参数要在合理的范围内,否则可能发生内存的改写,影响附近内存块的数据安全。前言
二进制转换为16进制字符串表示时,1 Byte 的二进制需要2 Byte的char型存储空间。C语言中,二进制转换为16进制,一般采用类似下面这样的语句:... unsigned char chbuf[4] ={0}; int a =23534; memcpy(chbuf,&a,4); char hexStr[9]={0}; /*转换*/ for(int i=0; i<4; i++) { sprintf(hexStr+i*2,"%02X",chbuf[i]); } //输出 ...
这时,在sprintf中, “%02X” 对应的参数应为1Byte的数据类型变量(如:unsigned char)。
发现问题
如果将上面的sprintf中, “%02X” 对应的参数应为1Byte的数据类型变量,传入一个存储空间大于1Byte类型的变量(如:int),会怎么样呢?事实是,传入int类型也是可以的,如传入一个叫 iValue的变量,只有当0< iValue <255 时,转换后存储空间存入数据正常;
下图是一个错误的内存信息(其中一次转换的结果):
从调试信息可以看出,在temp等于 -28 时,一次转换后buf里的内存有8Byte都被改写了(图中内存 红色 数字为本次内存被修改的数据)。正常时一次buf里写入2Byte数据,也就是说有6Byte内存空间被意外改写。
测试确认
下面为用VS2010环境里写的测试该问题的小程序(用随机数生成UUID):#include<iostream> #include <ctime> using namespace std; int main(){ unsigned char buf1[4] ={0}; int a =23534; memcpy(buf1,&a,4); char buf[33]={0}; char bufStr[10]={0}; srand(time(0)); int temp; //越界测试 for (int num = 0; ;num++) { for (int i =0;i<16;i++) { /*正确用法*/ //sprintf(bufStr+i*2,"%02X",buf1[i]); /*传参值大于“%02X”的合理值 会导致越界写数据*/ //范围控制不当 //temp = (1+(int)(300.0*rand()/(RAND_MAX+2.0))); //temp = (1+(int)(300.0*rand()/(RAND_MAX+2.0)))-150; temp = 1+(int)(300.0*rand()); sprintf((buf + i*2),"%02X",temp ); //范围控制正确 //sprintf((buf + i*2),"%02X", (1+(int)(255.0*rand()/(RAND_MAX+2.0)))); } int len =strlen(buf); if (len>32) { std::cout<<"NO"<< num <<": 越界(" << len << ") -> \t"<<buf<<std::endl; buf[32]='\0'; std::cout<<"NO"<< num <<": 字符串修正) -> \t"<<buf<<std::endl; system("pause"); std::cout<<std::endl; } } }
部分结果截图:
1)数值有概率性的超出范围:2)数值直接超出范围:
结论
使用sprintf 中二进制转换16进制(“%02X”)时,传入参数要在char型的范围内;同理,在做其他的转换时,对应的参数要在合理的范围内,否则可能发生内存的改写,影响附近内存块的数据安全。快速导航 >>
sprintf 02X 导致越界修改内存
前言
发现问题
测试确认
部分结果截图
结论
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 如何写好 C main 函数
- IE7降低内存和降低CPU的几个技巧
- 如何高效的使用内存
- DOS下内存的配置
- Lua和C语言的交互详解
- XP/win2003下发现1G的内存比512M还慢的解决方法
- PowerShell实现动态获取当前脚本运行时消耗的内存
- C#实现把dgv里的数据完整的复制到一张内存表的方法
- SQL语句实现查询SQL Server内存使用状况
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- C语言编程中统计输入的行数以及单词个数的方法
- C语言自动生成enum值和名字映射代码
- 使用C语言判断英文字符大小写的方法