为什么在Java进行字节码校验?

Why is bytecode verification performed in Java?

据我目前的理解this article作者写的主要目的是检查是否有人更改了字节码。因为"a class file generated by a compiler for the Java programming language always passes verification"。这是我们拥有字节码验证器以防止其他人恶意更改我们的字节码的唯一原因吗?

另一个原因是检查字节码确保这实际上是 jvm 可以 运行 有效的字节码,它防止 jvm 运行ning 无效代码,这可能会导致一些不可预测的结果.通过禁用字节码验证,您表示您相信 所有 类 您加载的字节码级别没有错误。

有用article

当你有一个有很多依赖项的大项目时,你通常不能确定是否在这个项目的某个地方或其依赖项中生成了一些 类,即使你确定现在这些地方,你也不能确保那里没有错误。生成这些 类 的代码可能存在错误,您最终可能会得到无效的字节码。

此外,即使是 javac 也可能存在一些错误,因此即使它也会产生无效的 类 作为输出。

因为您通常不是您在程序中使用的 classes 的唯一提供者。您可以使用第三方库,也可以使用第三方 class 代,例如一些自定义 Java 编译器而不是官方编译器。或者官方 Java 编译器可能只有一个没有人注意到的错误。

如果您使用的 classes 之一导致访问从未正确定义的变量,那么这违反了 Java 语言和 Java 平台保证,并且 Java 不能再保证程序的任何其他部分将按承诺运行。

因此验证器会检查您是否处于这种情况,如果是,则通知您而不是让您的程序表现得完全出乎意料,是的,有潜在危险,而不是让您蒙在鼓里。

a class file generated by a compiler for the Java programming language always passes verification

在那种形式下,陈述是不正确的。当然,编译器是软件,软件可能有错误。因此,无法保证编译器为 Java 编程语言生成的 class 文件始终正确。

此外,class 的正确性取决于它与之交互的其他 classes。自编译以来,这些 class 不能以不兼容的方式更改,因此如果您用于编译的环境与您尝试执行代码的环境不同,这些不匹配可能会导致代码被拒绝由验证者,即使编译器做的一切都是正确的。

这已经向您指出了一个问题,即除了有意的恶意修改之外,还可能存在非恶意错​​误引入的代码不兼容问题。验证者还可以防止这种情况发生,我想,这种情况发生的频率远远超过真正的故意攻击。