Java 究竟是如何防止缓冲区溢出的?仅仅是通过抛出“ArrayIndexOutofBounds”吗?它与 C++ 有何不同?为什么 C++ 有 bufferoverflow 而没有 Java?
3 回答
要记住的一点是,“缓冲区溢出”是用于破解系统的技巧的名称,也是常见编程错误的名称。
Java 通过在尝试访问超出其边界的数组时始终抛出异常来保护程序员免受称为“缓冲区溢出”的常见编程错误的影响。ArrayIndexOutofBounds
Java通过确保访问分配内存边界之外的尝试不会导致内存损坏来保护系统免受称为“缓冲区溢出”的常见黑客技术的影响。
C 和 C++ 容易受到称为“缓冲区溢出”的黑客技术的攻击,因为它们允许访问未分配的内存并且仅声明此活动的效果是undefined
.
当程序违反 Java 编程语言的语义约束时,Java 虚拟机会将此错误作为异常通知给程序。
此类违规的一个示例是尝试在数组边界之外进行索引。...
我的重点。
这两种语言有不同的哲学基础:
引用 Bjarne Stroustrup的话,“C++ 精益求精。基本原则是不用为不用的东西付费。” 这意味着如果您不想进行边界检查(例如,出于性能原因),则不必为此付费。
Java 的早期设计目标之一是实现不受信任的代码的安全执行。这需要对数组访问进行边界检查,因为越界访问是一个潜在的攻击向量。
当您尝试将数据写入固定大小缓冲区的末尾时,会发生缓冲区溢出。
在像 Java 这样进行边界检查的语言中,尝试写入超过缓冲区的末尾会引发异常。根据程序处理异常的方式,这可能意味着它完全恢复(拒绝溢出缓冲区的数据),或者变得不稳定(如果程序员没有计划异常)。
在像 C 这样的语言中,它希望程序员知道他/她的缓冲区有多长,写超过缓冲区的末尾会默默地破坏程序中其他地方使用的数据。更糟糕的是,在代码和数据之间没有硬分离的系统(例如,Windows-95)中,缓冲区溢出可能会破坏可执行代码。如果一个人研究过这个程序,他/她可以小心地构建一个缓冲区溢出,让他/她用其他东西替换原始程序代码——也许是在系统上安装了病毒,无法防止缓冲区溢出.
因此,虽然 Java(和其他管理语言)可以防止损坏数据的缓冲区溢出类型(并且现代操作系统可以防止允许恶意代码的类型),但它们并不能防止导致程序不稳定的(尝试的)缓冲区溢出类型。这取决于正确处理越界异常的程序员。