导读-- 数组边界检查能防止所有的缓冲区溢出的产生和攻击。这是因为只要数组不能被溢出,溢出攻击也就无从谈起。为了实现数组边界检查,则所有的对数组的读写操作都应当被检查以确保对数组的操作在正确的范围内...
四.3 数组边界检查 数组边界检查能防止所有的缓冲区溢出的产生和攻击。这是因为只要数组不能被溢出,溢出攻击也就无从谈起。为了实现数组边界检查,则所有的对数组的读写操作都应当被检查以确保对数组的操作在正确的范围内。最直接的方法是检查所有的数组操作,但是通常可以采用一些优化的技术来减少检查的次数。目前有以下的几种检查方法:
1、 Jones & Kelly: C的数组边界检查
Richard Jones和Paul Kelly开发了一个gcc的补丁,用来实现对C程序完全的数组边界检查。由于没有改变指针的含义,所以被编译的程序和其它的gcc模块具有很好的兼容性。更进一步的是,他们由此从没有指针的表达式中导出了一个“基”指针,然后通过检查这个基指针来侦测表达式的结果是否在容许的范围之内。
当然,这样付出的性能上的代价是巨大的:对于一个频繁使用指针的程序,比如向量乘法,将由于指针的频繁使用而使速度比本来慢30倍。这个编译器目前还很不成熟;一些复杂的程序还不能在这个上面编译,执行通过。
2、 Compaq C 编译器
Compaq公司为Alpha CPU开发的C编译器支持有限度的边界检查(使用check_bounds参数)。这些限制是:
只有显式的数组引用才被检查,比如“a[3]”会被检查,而“*(a+3)”则不会。
由于所有的C数组在传送的时候是指针传递的,所以传递给函数的的数组不会被检查。
带有危险性的库函数如strcpy不会在编译的时候进行边界检查,即便是指定了边界检查。
由于在C语言中利用指针进行数组操作和传递是如此的频繁,因此这种局限性是非常严重的。通常这种边界检查用来程序的查错,而且不能保证不发生缓冲区溢出的漏洞。
3、 Purify:
内存存取检查