修复缓冲区溢出问题
2009-03-07 20:02:33 来源:WEB开发网当 David LeBlanc 和我确定《Writing Secure Code》一书的目录时,我们明确地意识到必须着重介绍缓冲区溢出问题,因为已经有太多的开发人员在编写代码时犯了太多的此类错误,这些错误导致了可被人利用的缓冲区溢出的出现。在本文中,我将集中介绍为什么会出现缓冲区溢出及其修复的方法。为什么会出现缓冲区溢出
出现缓冲区溢出需要具备很多条件,包括:
使用非类型安全的语言,如 C/C++。
以不安全的方式访问或复制缓冲区。
编译器将缓冲区放在内存中关键数据结构旁边或邻近的位置。
现在我们来仔细看看以上每种条件。
首先,缓冲区溢出主要出现在 C 和 C++ 中,因为这些语言不执行数组边界检查和类型安全检查。C/C++ 允许开发人员创建非常接近硬件运行的程序,从而允许直接访问内存和计算机寄存器。其结果可以获得优异的性能;很难有任何应用程序能象编写得很好的 C/C++ 应用程序运行得那样快。其他语言中也会出现缓冲区溢出,但很少见。如果出现这种错误,通常不是由开发人员造成的,而是运行时环境的错误。
其次,如果应用程序从用户(或攻击者)那里获取数据,并将数据复制到应用程序所维护的缓冲区中而未考虑目标缓冲区的大小,则可能造成缓冲区溢出。换句话说,代码为缓冲区分配了 N 个字节,却将多于 N 个字节的数据复制到该缓冲区中。这就象向 12 盎司的玻璃杯中注入 16 盎司的水一样。那么多出的 4 盎司水到哪里去了呢?全溢出去了!
最后一点,也是最重要的一点,编译器通常将缓冲区放在“令人感兴趣的”数据结构旁边。例如,当某个函数的缓冲区紧邻堆栈,则在内存中该函数的返回地址紧靠在缓冲区之后。这时,如果攻击者可以使该缓冲区发生溢出,他就可以覆盖函数的返回地址,从而在返回函数时,返回到攻击者定义的地址。其他令人感兴趣的数据结构包括 C++ V 表、异常处理程序地址、函数指针等等。
赞助商链接