Java 直接编辑.class文件,使用操作码

Java 直接编辑.class文件,使用操作码,java,jvm,bytecode,Java,Jvm,Bytecode,今天,我只是尝试在编译的java类文件中使用一些操作码。插入后 iinc 1,1 java虚拟机响应为: Exception in thread "main" java.lang.ClassFormatError: Truncated class file at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoade

今天,我只是尝试在编译的java类文件中使用一些操作码。插入后

iinc 1,1
java虚拟机响应为:

Exception in thread "main" java.lang.ClassFormatError: Truncated class file
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
        at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Could not find the main class: Test.  Program will exit.
这是我的示例源代码:

public class Test {

    public static void main(String[] args) {
        int i = 5;
        i++;
        i++;
        i++;
        System.out.println("Number: " + i + "\n");
    }
}
增量的操作码是0x84+2字节(操作数)。 结果类文件中只有一个部分,其中包含0x84:

[..] 8401 0184 0101 8401 01[..]
因此,我将其翻译为:

iinc 1,1
iinc 1,1
iinc 1,1
对应于我的i++;i++;i++

然后,我尝试只追加840101以再次递增变量,但这不起作用,并导致ClassFormatError

类文件是否有类似校验和的内容? 我在中查找了类文件的格式,但找不到任何指向某类字节的类文件。我也不明白为什么错误是“截断类文件”,因为我确实附加了一些东西:-)


我知道直接编辑类文件不是一个好主意,但我只是对这里的VM内部结构感兴趣。我建议使用字节码操纵库,比如,或者比较前后,然后你就会知道如何自己做这件事了

至于您当前的问题,请确保文件的其余部分保持不变。

(免责声明:我没有分解您的示例。)

如果查看类格式的结构,您将看到
method\u info
的属性
code\u attributes
(4.7.3)中包含
code\u长度


由于您的编辑,您首先违反了声明的长度,其次当然,您修改的方法之后的任何后续数据现在都将处于不同的偏移量。

您应该注意,类文件应该尊重大量的结构约束(您可以了解这些约束),并且您的编辑确实违反了其中一个约束(您应该已经更新了代码长度属性)


对于使用漂亮的GUI快速编辑类文件,我建议。否则,您可以使用字节码操纵库以编程方式修改类文件。我一直在使用,但其他库确实存在。

如我所述:“我知道直接编辑类文件不是一个好主意,但我只对这里的VM内部结构感兴趣。”无论如何,谢谢你的建议。我不知道这意味着你不想使用字节码操作工具-这也是一种直接操作:)对;-)也许我可以用一个框架进行操作,然后检查生成的类文件的差异,但这并不能向我解释vm机制,它会抛出错误。:-)@echox:我认为通过工具来做会有很大帮助,即使这不是您想要做的,因为之前/之后的比较会非常有趣。@echox我很确定,理解类文件的文件格式不会让您了解VM的意图。这是一个虚拟环境,需要进行大量的翻译/编译,才能将一个类转换为VM使用它所做的事情。RE:“我知道这不是一个好主意…”在生产代码中有很多事情是不好的,但都是很好的学习方法。这听起来像是其中之一