C中strcpy漏洞

来源:互联网 发布:mac os qq 远程协助 编辑:程序博客网 时间:2024/05/16 14:16

C、C++】strcpy应用中出现的问题转自:http://hi.baidu.com/raoxj/item/37e6bb22c0c46f3394f62b7b

#include <iostream>
#include <stdio.h>
int main(void)
{
    char s[] = "123456789";
    char d[] = "123";
    strcpy(d,s);
    printf ("%s,\n%s",d,s);
    return 0;
}

输出是:

123456789,

56789

======>


原因:当开辟出s[]和d[]两个数组的内存单元时,内存是连续的,存放的方式如下:

s数组地址:0x0012ff74,存的值:123456789(隐含值'\0')

d数组地址:0x0012ff70,存的值:123(隐含值'\0')

即内存中的情况是:123\0123456789\0,strcpy以后就变成了123456789\07890

而此时,s和d的地址是没变的 依次指向:

1 2 3 \0 1 2 3 4 5 6 7 8 9 \0            ====>         1 2 3 4 5 6 7 8 9 \0 7 8 9 0

d           s                                                         d         s

无论输出d数组还是s数组都是遇到'\0'结束,因此输出自然是123456789和56789啦~~

知识链接:

微软的strcpy函数是这么写的:

char *cdecl strcpy(char *dst, const char * src)

{

    char *cp = dst;

    while(*cp++ = * src++)

    ;

    return (dst);

}

       分析可知,这样安全漏洞太多了,所以用这个函数必须小心,给目标字符串分配足够的空间才行~~

从上面我们可以看到这样的代码有问题有:

  1.没有检查输入的两个指针是否有效。

  2.没有检查两个字符串是否以NULL结尾。

  3.没有检查目标指针的空间是否大于等于原字符串的空间。






后续思考:

       牛人这么多的微软,怎么就没想到这个小小的拷贝函数会造成这么大的安全隐患呢?答案很简单:为了提高性能,减去那些啰嗦的安全检查是必要的。而且,程序员应该知道哪些条件会发生访问违例。这种做法就是把责任推给了程序员,让他来决定安全与性能的取舍(摘自程序员面试宝典)。我想,这也就是C,C++和java等语言的最大区别吧。。真的很深奥又很美好的一门语言啊。

一个拷贝函数的完整的标准写法是这样滴:

#include <stdio.h>
#include <cassert>
#include <malloc.h>
void stringcopy(char *to, const char *from)
{
    assert(to != NULL && from != NULL);
    while(*from != '\0')
    {
        *to ++ = *from++;
    }
    *to = '\0';
}
int main(void)
{
    char *f;
    f = (char *) malloc (15);
    stringcopy (f, "hello stringcopy!");
    printf ("%s\n",f);
    return 0;
}

       但是这里有个疑问,严重的疑问。既然是一个完整的标准写法,应该涉及到检查to也就是目标字符串的可预存空间,并只能将值赋在这个空间内,不可越界,这才是真正的安全吧。。。那就涉及到要给stringcopy函数传一个目标字符串预存空间的大小值了。。哦哦,是不是又太麻烦呢。。欢迎各位指正~


原创粉丝点击