首页 > 为什么直接修改java的.class文件会导致程序崩溃

为什么直接修改java的.class文件会导致程序崩溃

是这样的。
有一次,hardcode了ip地址在代码里,由于懒得重新编译。
强行用记事本打开.class文件,发现里面已经面目全非了,但是数字还是原来的样子。
于是直接改了.class文件里的数字,换了个ip地址,结果运行时是直接崩溃的。
为什么呢?是有什么检查机制吗?

-------补充--------------

不好意思 描述不太准确啊
补充个例子
1)我先新建了一个.java

public class Test {
    public Test() {
    }

    public static void main(String[] args) {
        String ip = "172.18.81.111";
        System.out.println(ip);
    }
}

然后
javac Test.java

运行java Test

结果正常
输出 172.18.81.111

2)然后我用vim修改.class文件

Êþº¾^@^@^@4^@^]
^@^F^@^O^H^@^P  ^@^Q^@^R
^@^S^@^T^G^@^U^G^@^V^A^@^F<init>^A^@^C()V^A^@^DCode^A^@^OLineNumberTable^A^@^Dmain^A^@^V([Ljava/lang/String;)V^A^@
SourceFile^A^@  Test.java^L^@^G^@^H^A^@^M172.18.81.111^G^@^W^L^@^X^@^Y^G^@^Z^L^@^[^@^\^A^@^DTest^A^@^Pjava/lang/Object^A^@^Pjava/lang/System^A^@^Cout^A^@^ULjava/io/PrintStream;^A^@^Sjava/io/PrintStream^A^@^Gprintln^A^@^U(Ljava/lang/String;)V^@!^@^E^@^F^@^@^@^@^@^B^@^A^@^G^@^H^@^A^@      ^@^@^@^]^@^A^@^A^@^@^@^E*·^@^A±^@^@^@^A^@
^@^@^@^F^@^A^@^@^@^D^@  ^@^K^@^L^@^A^@  ^@^@^@+^@^B^@^B^@^@^@^K^R^BL²^@^C+¶^@^D±^@^@^@^A^@
^@^@^@^N^@^C^@^@^@^H^@^C^@
^@
^@^K^@^A^@^M^@^@^@^B^@^N
~
~

上面的.class文件中明显有一串数字,直接修改之。
然后再运行java Test

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.ClassFormatError: Unknown constant tag 49 in class file Test
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)

为什么修改个数字就会崩溃呢?


查看ClassFormatError文档 https://docs.oracle.com/javase/7/docs/api/java/lang/ClassFormatError.html

Thrown when the Java Virtual Machine attempts to read a class file and
determines that the file is malformed or otherwise cannot be
interpreted as a class file.

翻译过来的意思是

当Java虚拟机尝试读取class文件时,发现文件是畸形的或者是无法作为class文件解释的,就会抛出ClassFormatError错误。

错误名称『ClassFormatError』,顾名思义是class文件格式化错误,并根据上述内容猜测应该是虚拟机读取class文件时需要interpreted(解释)和格式化时产生的错误。具体过程不得而知。


事实上是可以的。。javassist这类的软件可以做到。
或者其他16进制编辑器也是可以的。
windows自带的记事本文件是不行了.
引用一楼记住不要用windows自带的记事本打开文本文件!

ultraedit打开编辑之后正常运行。

注意

编辑的时候文字长度一定要和原来一样,否则会出现错误。

附图


vim修改后保存的格式与之前的.class文件格式不一样吧,毕竟是字节码文件。


记住不要用windows自带的记事本打开文本文件!
记住不要用windows自带的记事本打开文本文件!
记住不要用windows自带的记事本打开文本文件!
不要随意改数字,有可能你改的是魔术数字。
此文件已废。


你保存的时候文件属性已经变了


class文件是javac在对java源文件经过词法分析、语法分析、语义分析生成的字节码文件。直接修改会破坏文件的结构,一般不要随便修改生成的class文件。


题主 可以去了解下class文件结构,合适的编辑器是可以修改的,前提是要了解所改位置具体值的范围和意义


用notepad++ 修改 这个有hex编辑模式 exe/dll中的常量都是集中存储的,原来的很多游戏作弊器就是直接修改游戏的金钱数, 立马进入无敌模式


虽然已经答过了 我还是想说一下 windows 自带 的 会有bom头,讨厌啊

【热门文章】
【热门文章】