用途:转换过程 “.class文件 -> 字节码指令(类似汇编语言)文件 -> .class文件”,只需要修改“字节码指令(类似汇编语言)文件”就能改变一个“.class文件”的运行结果。
下载url:https://ci.adoptopenjdk.net/view/Dependencies/job/asmtools/lastSuccessfulBuild/artifact/
Foo.java
package org.example; public class Foo { static boolean boolValue; public static void main(String[] args) { boolValue = true; // 将这个true替换为2或者3,再看看打印结果 if (boolValue) System.out.println("Hello, Java!"); if (boolValue == true) System.out.println("Hello, JVM!"); } }1)编译成.class文件后,运行命令反编译成字节码指令文件:
~/Demo/jvm_learning/ch2/target/classes/org/example$ java -cp ~/Downloads/asmtools.jar org.openjdk.asmtools.jdis.Main Foo.class > Foo.jasm生成的字节码指令文件Foo.jasm内容如下:
// class version 51.0 (51) // access flags 0x21 public class org/example/Foo { // compiled from: Foo.java // access flags 0x8 static Z boolValue // access flags 0x1 public <init>()V L0 LINENUMBER 3 L0 ALOAD 0 INVOKESPECIAL java/lang/Object.<init> ()V RETURN L1 LOCALVARIABLE this Lorg/example/Foo; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 1 // access flags 0x9 public static main([Ljava/lang/String;)V L0 LINENUMBER 6 L0 ICONST_1 PUTSTATIC org/example/Foo.boolValue : Z L1 LINENUMBER 7 L1 GETSTATIC org/example/Foo.boolValue : Z IFEQ L2 GETSTATIC java/lang/System.out : Ljava/io/PrintStream; LDC "Hello, Java!" INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V L2 LINENUMBER 8 L2 FRAME SAME GETSTATIC org/example/Foo.boolValue : Z ICONST_1 IF_ICMPNE L3 GETSTATIC java/lang/System.out : Ljava/io/PrintStream; LDC "Hello, JVM!" INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V L3 LINENUMBER 9 L3 FRAME SAME RETURN L4 LOCALVARIABLE args [Ljava/lang/String; L0 L4 0 MAXSTACK = 2 MAXLOCALS = 1 }2)运行gedit Foo,jasm,将26行代码ICONST_1改成ICONST_2后保存。
3)再运行命令编译成字节码文件Foo.class:
~/Demo/jvm_learning/ch2/target/classes/org/example$ java -cp ~/Downloads/asmtools.jar org.openjdk.asmtools.jasm.Main Foo.jasm此时运行Foo.class的结果没有输出:
~/Demo/jvm_learning/ch2/target/classes$ java org.example.Foo ~/Demo/jvm_learning/ch2/target/classes$再重复上述步骤1)~3),其中将26行代码 ICONST_2改成ICONST_3,此时运行Foo.class的结果输出是:
~/Demo/jvm_learning/ch2/target/classes$ java org.example.Foo Hello, Java! Hello, JVM! ~/Demo/jvm_learning/ch2/target/classes$
