注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

多多的爹

 
 
 

日志

 
 

防止缓冲区溢出——GS开关  

2006-07-03 16:14:39|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

缓冲区溢出是计算机界最臭名昭著的BUG之一。黑客们可以利用这个BUG,修改程序的执行流程,进行一些非法的操作,导致各种各样的危害:小到本进程,大到危害机器,甚至是网络上的其它计算机。如果进程拥有管理员的权限,则能产生更多更广泛的危害。最近几年非常著名的几个病毒,比如Code Red Blaster worms,就是钻了缓冲区溢出的的空子。

什么是缓冲区溢出?

缓冲区溢出是一个非常简单的程序错误:将一段内存从一个区域拷贝到另一个区域的时候,目标区域太小以至无法容纳源区域,目标区域后面的内容也将被改变。举个例子:

       char* source = "A reasonably long string";

       char dest[10];

       ::strcpy(dest, source);

在这个例子中,源字符串占25个字节(包括最后的空字符),目标空间在栈上仅仅申请了10个字节。当程序运行完strcpy后,栈就被会破坏,从而产生一个access violation的错误。由于源数据可以来自其它的未知的代码,所以无法确切的保证申请的目标空间足够使用,一旦申请的空间不足,就有可以造成缓冲区溢出。

 

缓冲区溢出的原因

       C/C++中,当一个函数被调用的时候,这个函数的返回地址被放在了栈上,当函数执行完毕后,处理器找到这个返回地址,将回到这个地址继续执行程序。因此,当出现缓冲区溢出的时候,溢出的代码非常有可能覆盖掉函数的返回地址,这样处理器就无法找到原来的地址了,只会按照新的地址进行跳转。通常被覆盖的内容是一个无效地址,所以处理器会报access violation的错误。但是如果遇到别有用心的攻击者,他们就会利用这个缺陷修改函数的返回地址,跳转到一段有危害的代码中。

函数参数

返回地址

异常处理函数

代码和缓冲区

早期的栈

 

如何编写安全的代码

       最简单的防止缓冲区溢出的方法,就是限制被拷贝的内存长度。当源数据长于目标区域时,源数据被截断,只拷贝目标区域能容纳的那部分数据。虽然这种方法看上去比较弱智,但是实际上,他能解决非常多的潜在的问题。并且我们看到,现在许多高级程序语言,比如Java.NET,都是使用的这种技术。

 

Visual C++ 7.0

       当然缓冲区溢出的根本原因,是由于函数返回地址函数内申请的内存都位于栈上导致的,这实际上是编译器搞的鬼。因此Vc++开发组想出了一个好的办法还防止缓冲区溢出。在Visual C++7.0中,他们在函数返回地址下面插入了一个cookie(一个确定值的内存块)。当函数返回的时候,首先会检测这个cookie是否被改变,如果发生了改变,那么就认为返回地址已经不可信任了,这时就会产生一个_SECERR_BUFFER_OVERRUN异常。以下是一个简单的内存分布示意图:

函数参数

返回地址

Cookie

异常处理函数

代码和缓冲区

Visual C++7.0的栈

 

Visual C++ 7.1

       Visual C++7.1增强了Visual C++ 7.0的做法。实际上,在返回地址和代码区间,还存在一个异常处理函数区域。当产生缓冲区溢出时,调用的异常处理函数地址也有可能是错误的。因此,在Visual C++7.1中,异常处理函数被移到了整个栈的最后位置。

函数参数

返回地址

Cookie

代码和缓冲区

异常处理函数

Visual C++7.1的栈

 

使用/GS保护缓冲区

       使用缓冲区保护是一个很简单的事情,只要打开编译器的/GS开关就可以了。通常在编译Release版本时,需要打开这个开关。

  评论这张
 
阅读(10)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017