C语言整型溢出会怎样 |
您所在的位置:网站首页 › c语言内存溢出是什么 › C语言整型溢出会怎样 |
整型溢出有点老生常谈了,bla, bla, bla… 但似乎没有引起多少人的重视。整型溢出会有可能导致缓冲区溢出,缓冲区溢出会导致各种黑客攻击,比如最近OpenSSL的heartbleed事件,就是一个buffer overread的事件。在这里写下这篇文章,希望大家都了解一下整型溢出,编译器的行为,以及如何防范,以写出更安全的代码。 什么是整型溢出C语言的整型问题相信大家并不陌生了。对于整型溢出,分为无符号整型溢出和有符号整型溢出。 对于unsigned整型溢出,C的规范是有定义的——“溢出后的数会以2^(8*sizeof(type))作模运算”,也就是说,如果一个unsigned char(1字符,8bits)溢出了,会把溢出的值与256求模。例如: 1 2 unsigned char x = 0xff; printf("%dn", ++x); 上面的代码会输出:0 (因为0xff + 1是256,与2^8求模后就是0) 对于signed整型的溢出,C的规范定义是“undefined behavior”,也就是说,编译器爱怎么实现就怎么实现。对于大多数编译器来说,算得啥就是啥。比如: 1 2 signed char x =0x7f; //注:0xff就是-1了,因为最高位是1也就是负数了 printf("%dn", ++x); 上面的代码会输出:-128,因为0x7f + 0×01得到0×80,也就是二进制的1000 0000,符号位为1,负数,后面为全0,就是负的最小数,即-128。 另外,千万别以为signed整型溢出就是负数,这个是不定的。比如: 1 2 3 4 signed char x = 0x7f; signed char y = 0x05; signed char r = x * y; printf("%dn", r); 上面的代码会输出:123 相信对于这些大家不会陌生了。 整型溢出的危害下面说一下,整型溢出的危害。 示例一:整形溢出导致死循环1 2 3 4 5 6 7 8 ... ... ... ... short len = 0; ... ... while(len< MAX_LEN) { len += readFromInput(fd, buf); buf += len; } 上面这段代码可能是很多程序员都喜欢写的代码(我在很多代码里看到过多次),其中的MAX_LEN 可能会是个比较大的整型,比如32767,我们知道short是16bits,取值范围是-32768 到 32767 之间。但是,上面的while循环代码有可能会造成整型溢出,而len又是个有符号的整型,所以可能会成负数,导致不断地死循环。 示例二:整形转型时的溢出1 2 3 4 5 6 7 8 9 10 11 12 13 int copy_something(char *buf, int len) { #define MAX_LEN 256 char mybuf[MAX_LEN]; ... ... ... ... if(len > MAX_LEN){ // 0) { response = xmalloc(nresp*sizeof(char*)); for (i = 0; i < nresp; i++) response[i] = packet_get_string(NULL); } 上面这个代码中,nresp是size_t类型(size_t一般就是unsigned int/long int),这个示例是一个解数据包的示例,一般来说,数据包中都会有一个len,然后后面是data。如果我们精心准备一个len,比如:1073741825(在32位系统上,指针占4个字节,unsigned int的最大值是0xffffffff,我们只要提供0xffffffff/4 的值——0×40000000,这里我们设置了0×4000000 + 1), nresp就会读到这个值,然后nresp*sizeof(char*)就成了 1073741825 * 4,于是溢出,结果成为了 0×100000004,然后求模,得到4。于是,malloc(4),于是后面的for循环1073741825 次,就可以干环事了(经过0×40000001的循环,用户的数据早已覆盖了xmalloc原先分配的4字节的空间以及后面的数据,包括程序代码,函数指针,于是就可以改写程序逻辑。关于更多的东西,你可以看一下这篇文章《Survey of Protections from Buffer-Overflow Attacks》)。 示例四:缓冲区溢出导致安全问题1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int func(char *buf1, unsigned int len1, char *buf2, unsigned int len2 ) { char mybuf[256]; if((len1 + len2) > 256){ // |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |