美文网首页
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编译过程 源文件—>java编译器—>字节码文件—>(类装载器—>字节码校验器—>解释器)—>系统平台 字...

  • Java字节码校验

    记录一下修改class文件以及使用命令行执行class文件 参考《Java核心技术 卷2》 1. 编写代码 在包j...

  • 字节码引用检测原理与实战

    一、字节码与引用检测 1.1 Java字节码 本章中的字节码重点研究Java 字节码,Java字节码(Java b...

  • Proguard摘要

    Proguard流程 Proguard可对Java字节码文件进行压缩,优化,混淆及预校验。 shrink:检测和移...

  • JVM知识精粹

    1.jvm执行字节码文件 流程:jvm通过类加载器加载字节码文件----字节码校验器---翻译字节码(解释执行,反...

  • 程序员练级攻略(2018):Java底层知识

    Java 字节码相关 首先,Java 最黑科技的玩法就是字节码编程,也就是动态修改或是动态生成 Java 字节码。...

  • Java并发机制的底层原理

    Java程序执行:Java代码→Java字节码→字节码被类加载器加载到JVM里,JVM执行字节码→转化为汇编指令在...

  • DVM执行 java 程序的工具

    jvm 执行字节码原理:java 程序运行时,是由一个 java 虚拟机来解释 java 字节码的,它将这些字节码...

  • Java字节码

    参考链接:一文让你明白Java字节码 Java字节码 Java虚拟机字节码指令 Java号称是一门“一次编译到处运...

  • Javassist指引(一)

    原文链接 [TOC] 1. 读写字节码 1.1概述 Javassist是一个Java字节码类库。Java的字节码是...

网友评论

      本文标题:Java字节码校验

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