美文网首页
Java字节码校验

Java字节码校验

作者: 0x70e8 | 来源:发表于2018-04-12 22:21 被阅读0次

    记录一下修改class文件以及使用命令行执行class文件

    • 参考《Java核心技术 卷2》

    1. 编写代码

    在包jdk.test.classLoader下创建类VerifyTest,对应磁盘目录是D://workspace/Test/jdk.test.classloader

    package jdk.test.classLoader;
    
    public class VerifyTest {
        static int fun() {
    
            int m, n;
            m = 1;
            n = 2;
            return m + n;
        }
    
        public static void main(String[] args) {
            System.out.println(fun());
        }
    }
    

    2. 编译

    javac VerifyTest.java;

    3.反编译看字节码

    $ javap -c VerifyTest.class
    Compiled from "VerifyTest.java"
    public class jdk.test.classLoader.VerifyTest {
      public jdk.test.classLoader.VerifyTest();
        Code:
           0: aload_0
           1: invokespecial #8                  // Method java/lang/Object."<init>":()V
           4: return
    
      static int fun();
        Code:
           0: iconst_1
           1: istore_0
           2: iconst_2
           3: istore_1
           4: iload_0
           5: iload_1
           6: iadd
           7: ireturn
    
      public static void main(java.lang.String[]);
        Code:
           0: getstatic     #21                 // Field java/lang/System.out:Ljava/io/PrintStream;
           3: invokestatic  #27                 // Method fun:()I
           6: invokevirtual #29                 // Method java/io/PrintStream.println:(I)V
           9: return
    }
    
    

    把方法fun的助记符的字节码(16进制找到)

      static int fun();
        Code:
           0: iconst_1  04
           1: istore_0  3B
           2: iconst_2  05  
           3: istore_1  3C
           4: iload_0   1A
           5: iload_1   1B
           6: iadd      60
           7: ireturn   AC
    
    

    修改字节码文件

    把3C改成3B,这样第一个局部变量就被初始化两次,而第二个变量没有被初始化(这是虚拟机不接受的)
    再反编译一下:

    $ javap -c VerifyTest.class
    Compiled from "VerifyTest.java"
    public class jdk.test.classLoader.VerifyTest {
      public jdk.test.classLoader.VerifyTest();
        Code:
           0: aload_0
           1: invokespecial #8                  // Method java/lang/Object."<init>":()V
           4: return
    
      static int fun();
        Code:
           0: iconst_1
           1: istore_0
           2: iconst_2
           3: istore_0   //此处变了
           4: iload_0
           5: iload_1
           6: iadd
           7: ireturn
    
      public static void main(java.lang.String[]);
        Code:
           0: getstatic     #21                 // Field java/lang/System.out:Ljava/io/PrintStream;
           3: invokestatic  #27                 // Method fun:()I
           6: invokevirtual #29                 // Method java/io/PrintStream.println:(I)V
           9: return
    }
    
    
    

    执行

    到包的根目录下执行

    $ pwd
    /d/workspace/Test/bin
    $ java -classpath . jdk.test.classLoader.VerifyTest
    java.lang.VerifyError: Bad local variable type
    Exception Details:
      Location:
        jdk/test/classLoader/VerifyTest.fun()I @5: iload_1
      Reason:
        Type top (current frame, locals[1]) is not assignable to integer
      Current Frame:
        bci: @5
        flags: { }
        locals: { integer }
        stack: { integer }
      Bytecode:
        0x0000000: 043b 053b 1a1b 60ac
    
            at java.lang.Class.getDeclaredMethods0(Native Method)
            at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
            at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
            at java.lang.Class.getMethod0(Class.java:3018)
            at java.lang.Class.getMethod(Class.java:1784)
            at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
            at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
    Error: A JNI error has occurred, please check your installation and try again
    Exception in thread "main"
    
    

    不验证:

    $ java -noverify jdk.test.classLoader.VerifyTest
    2
    

    相关文章

      网友评论

          本文标题:Java字节码校验

          本文链接:https://www.haomeiwen.com/subject/pwfqkftx.html