对于大多数的博友来说,hs_strcpy一定会很陌生,因为这个hs_strcpy这个关键字和我的工作有挂钩。本来目前就职于恒生电子,hs_strcpy是中间件中公司定义的字符串拷贝方法,在工作业余之余,看过了一篇缓冲区溢出的文章,处于好奇心就看了一下公司内部的底层代码,发现了hs_strcpy这个函数的实现,突然发现原来这个还是其实也是存在缓冲区溢出的。什么是缓冲区溢出、如何防止缓冲区溢出,是我写这篇文章的真正目的。小编自称菜鸟,如果有写的不对的地方,请多多批评。
专有名字解释
在看下文之前,我们还是先看一下专有的名词解释吧,这样可以更好的带大家全面的了解本文的核心内容。
1.缓冲溢出(Buffer overflow),是指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量,使得溢出的数据覆盖在合法数据上,理想的情况是程序检查数据长度并不允许输入超过缓冲区长度的字符,但是绝大多数程序都会假设数据长度总是与所分配的储存空间相匹配,这就为缓冲区溢出埋下隐患。操作系统所使用的缓冲区又被称为"堆栈".。在各个操作进程之间,指令会被临时储存在"堆栈"当中,"堆栈"也会出现缓冲区溢出。[1]
2. 栈(操作系统):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。[2]
3. ESP(Extended stack pointer)是指针寄存器的一种(另一种为EBP)。用于堆栈指针。[3]
4. 扩展基址指针寄存器(extended base pointer) 其内存放一个指针,该指针指向系统栈最上面一个栈帧的底部。[4]
5. 栈帧也叫过程活动记录,是编译器用来实现过程/函数调用的一种数据结构。[5]
开门见山
随着IDE工具的越来越发达,越来越多的程序员开始疏忽缓冲区溢出,甚至一些开发程序员从未听说过此专有名词。当然如果真的发生了缓冲溢出,那还是非常可怕的,虽然光大的乌龙指并非缓冲溢出所为,但是缓冲区可以再次创造光大的乌龙指。所以我们开发人员不可以忽视我们程序的缓冲区溢出问题。
那到底什么是缓冲区溢出呢?顾名思义,缓冲区溢出的含义是为缓冲区提供了多于其存储容量的数据,打个比方,我有一个100ml的水杯,但是我倒入了120ml的水,那么20ml的水就会溢出杯子,造成一些想不到的后果。
strcpy和hs_strcpy
我们先来看一下微软为我们开发人员提供的strcpy这个api函数的实现源码(参考百度百科):
/********************** * C语言标准库函数strcpy的一种典型的工业级的最简实现 *返回值:目标串的地址。 *对于出现异常的情况ANSI-C99标准并未定义,故由实现者决定返回值,通常为NULL。 *参数: * strDestination 目标串 * s /* GNU-C中的实现(节选): */ char* strcpy(char *d, const char *s) { char *r=d; while((*d++=*s++)); return r; } /* while((*d++=*s++)); 的解释:赋值表达式返回左操作数,所以在复制NULL后,循环停止ֹ */ 在比较一下恒生公司自定义开发的源码(本人在服务器的文件中找到了定义和实现的整个代码): int hs_strcpy(char *d_dest,const char *s_src) { if (isnull(s_src) == 0) { d_dest[0] = '