首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

关于缓冲区溢出的一段代码,该如何处理

2013-10-27 
关于缓冲区溢出的一段代码我已经大概知道了了缓冲区溢出的原理了。有下面一段代码:#include stdio.h#incl

关于缓冲区溢出的一段代码
我已经大概知道了了缓冲区溢出的原理了。有下面一段代码:
#include <stdio.h>
#include <string.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
int i=1;
char buf[2]={'a','b'};

printf("&i is:%p\n",&i);
printf("&buf[0] is:%p\n",&buf[0]);
printf("&buf[1] is:%p\n",&buf[1]);

strcpy(buf,"xy");

printf("buf[0] is:%c\n",buf[0]);
printf("buf[1] is:%c\n",buf[1]);
printf("i is:%d\n",i);
return 0;
}运行之后,在内存中
&i is:0022FF44 
&buf[0] is:0022FF42 
&buf[1] is:0022FF43
buf[0]变成了x,buf[1]变成了y,字符串截断符覆盖了i,改写了i的值。
我想问的是:为什么i会变成0,这个0是怎么算出来的?

如果把strcpy(buf,"xy");改成strcpy(buf,"xyz"),输出结果i是122,这个122又是怎么算出来的?
我就是不知道计算方法,谁能够详细给我解释一下。
谢谢。
[解决办法]
不是简单的122+122,而是第一个字节为122,第二个字节为122,而一个字节是8bits,所以:
i = 122 
[解决办法]
 (122 << 8)
相当于,
i = 122 + 122 * 256 = 31354

引用:
还有,如果像你所说:strcpy(buf,"xyz"); 最后两个字符z\0,把i中的1给覆盖了, z的ascii码为122,所就是变成122了,
如果我把xyz改成xyzz,那就是最后3个字符zz\0把i中的1给覆盖了,那结果就应该是122+122,可我的输出结果是31354.这是为什么。

是按照ascii码来算的吗?

[解决办法]
int型变量i的十六进制表示为0x00 00 00 01,但在内存中采用地位存储低地址的方式,也就是内存中从低位到高位依次存储的是01 00 00 00(十六进制表示),然后字符串截断符‘\0’,内存表示为00(十六进制表示),会覆盖掉01,然后int型变量i的在内存中就变成了00 00 00 00(32位十六进制表示),也就是0x00 00 00 00,也就是0。
[解决办法]
char buf[2]={'a','b'};
你这里的字符数组不是字符串,没有NUL结束符
strcpy(buf,"xy");实际上是这样
buf[0] = 'x'
buf[1] = 'y'
buf[2] = '\0'

编译器将buf先入栈,然后再将i栈,所以i的位置就是buf[2],这样 i的值就变为了'\0'等于0

同理strcpy(buf,"xyz"),
buf[0] = 'x';
buf[1] = 'y'
buf[2] = 'z'
buf[3] = '\0'
i的内存是这样存储的(小顶端机)
0x 01 00 00 00

经过strcpy(buf,"xyz"),之后,i的存储变为了
0x 7a 00 00 00
所以i的值变为了i = 0x0000007a = 122

如果是
strcpy(buf,"xyzz")的话
i的存储变为了
0x 7a 7a 00 00
所以i的值变为了i = 0x00007a7a = 31354

热点排行