如何在JVM中验证字节码?

Ton*_*ony 14 java jvm bytecode

如何在JVM中验证字节码?

pax*_*blo 19

甲骨文本身有它如何工作的一个小片段页面在这里.

基本上,JRE不信任JDK.那是因为它不知道哪个JDK编译器创建了类文件.在验证之前,它会将类文件视为敌对文件.

在此基础上,字节码验证是防止Sun称之为"恶意编译器"的必要步骤.Sun自己的Java编译器确保Java源代码不违反安全规则,但是当应用程序导入代码片段时,它实际上并不知道代码片段是否遵循Java语言规则以确保安全.换句话说,代码可能不是由值得信赖的Java编译器生成的.

在这种情况下,计算机上的Java运行时系统必须假定片段是坏的并使其进行字节码验证.

在完成此验证过程之前,Java虚拟机甚至不会看到字节码.在加载字节码时执行此操作还具有以下优点:每次执行代码时都不需要执行大量的运行时检查.因为它已被验证为正确,所以一旦它开始运行,它可以比其他方式运行得更快.

链接图的再现如下:

                    <<<=== Unsafe / Safe ===>>>
                                  \
+---------------+        +-------------------+
|  Java source  |   +--> |   Class loader    | --+
+---------------+   |    | Bytecode verifier |   |
        |           |    +-------------------+   |
        V           |             /              |
+---------------+   |             \              V
| Java compiler |  Network        /    +-------------------+
+---------------+   |             \    |      JVM/JIT      |
        |           |             /    +-------------------+
        V           |             \              |
+---------------+   |             /              V
| Java bytecode | --+             \    +-------------------+
+---------------+                 /    | Operating system  |
                                  \    +-------------------+
                                  /              |
                                  \              V
                                  /    +-------------------+
                                  \    |     Hardware      |
                                  /    +-------------------+
                                  \
                    <<<=== Unsafe / Safe ===>>>
Run Code Online (Sandbox Code Playgroud)


Jon*_*eet 9

最好的信息来源可能是JVM规范中的相关部分,4.10类文件的验证.

有关详细信息,请参阅链接,但广泛地说:

链接时验证可以提高解释器的性能.可以消除否则必须执行的昂贵检查以在运行时验证每个解释指令的约束.Java虚拟机可以假定已经执行了这些检查.例如,Java虚拟机已经知道以下内容:

  • 没有操作数堆栈溢出或下溢.
  • 所有本地变量使用和存储都是有效的.
  • 所有Java虚拟机指令的参数都是有效类型.

验证程序还执行验证,无需查看代码属性的代码数组(第4.7.3节)即可完成验证.执行的检查包括以下内容:

  • 确保最终类不是子类,并且不会覆盖最终方法(第5.4.5节).
  • 检查每个类(除外Object)是否具有直接超类.
  • 确保常量池满足记录的静态约束; 例如,CONSTANT_Class_info常量池中的每个结构在其name_index项中包含结构的有效常量池索引CONSTANT_Utf8_info.
  • 检查常量池中的所有字段引用和方法引用是否具有有效名称,有效类和有效类型描述符.