《深入理解Java虚拟机》-(实战)练习修改class文件,
分享于 点击 1441 次 点评:99
《深入理解Java虚拟机》-(实战)练习修改class文件,
这是一篇修改class文件的文章。注释并不完全,要抓住这次练习的目的:
boolean在虚拟机中是以何种方式解读的
好的,开始我的表演
1.安装asmtools.jar(本文尾部有步骤)
2.编写一个java文件,并编译,执行 2.1 Foo.java
2.2 编译并运行
[root@localhost tmp]# javac Foo.java [root@localhost tmp]# java Foo Hello, Java! Hello, JVM!
3.查看编译后的java文件,class (注意看黄色部分的变化)

4.使用asmtools.jar修改class文件
[root@localhost tmp]# java -jar ../asmtools.jar jdis Foo.class > Foo.jasm.1 [root@localhost tmp]# ls Foo.class Foo.jasm.1 Foo.java [root@localhost tmp]# java -cp ../asmtools.jar org.openjdk.asmtools.jdis.Main Foo.class > Foo.jasm.1 [root@localhost tmp]# awk 'NR==1,/iconst_1/{sub(/iconst_1/,"iconst_2")} 1' Foo.jasm.1 > Foo.jasm [root@localhost tmp]# ls Foo.class Foo.jasm Foo.jasm.1 Foo.java [root@localhost tmp]# java Foo Hello, Java! Hello, JVM!
5.再次编译,执行
[root@localhost tmp]# java -jar ../asmtools.jar jasm Foo.jasm [root@localhost tmp]# java Foo Hello, Java! [root@localhost tmp]# ls Foo.class Foo.jasm Foo.jasm.1 Foo.java
6.查看修改后的class文件
[root@localhost tmp]# javap -verbose Foo Classfile /usr/local/asmtools-7.0-build/binaries/lib/tmp/Foo.class Last modified Aug 12, 2019; size 431 bytes MD5 checksum 18cfb8b8b7d9d49e9ffce213e70c8898 Compiled from "Foo.jasm" public class Foo minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = String #10 // Hello, Java! #2 = String #11 // Hello, JVM! #3 = Fieldref #27.#12 // java/lang/System.out:Ljava/io/PrintStream; #4 = Methodref #8.#17 // java/lang/Object."<init>":()V #5 = Methodref #13.#30 // java/io/PrintStream.println:(Ljava/lang/String;)V #6 = Utf8 (Ljava/lang/String;)V #7 = Utf8 out #8 = Class #9 // java/lang/Object #9 = Utf8 java/lang/Object #10 = Utf8 Hello, Java! #11 = Utf8 Hello, JVM! #12 = NameAndType #7:#23 // out:Ljava/io/PrintStream; #13 = Class #15 // java/io/PrintStream #14 = Utf8 ([Ljava/lang/String;)V #15 = Utf8 java/io/PrintStream #16 = Utf8 main #17 = NameAndType #29:#20 // "<init>":()V #18 = Utf8 SourceFile #19 = Utf8 println #20 = Utf8 ()V #21 = Utf8 StackMapTable #22 = Utf8 Foo.jasm #23 = Utf8 Ljava/io/PrintStream; #24 = Utf8 Code #25 = Class #26 // Foo #26 = Utf8 Foo #27 = Class #28 // java/lang/System #28 = Utf8 java/lang/System #29 = Utf8 <init> #30 = NameAndType #19:#6 // println:(Ljava/lang/String;)V { public Foo(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #4 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=2, args_size=1 0: iconst_2 //载入常量2入栈 1: istore_1 //把栈顶值存储到局部变量表下标为1的位置,即flag =2; 2: iload_1 //取局部变量表中下标为1的变量压栈 3: ifeq 14 6: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 9: ldc #1 // String Hello, Java! 11: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 14: iload_1 //取局部变量表中下标为1的变量压栈 15: iconst_1 //常量1入栈 16: if_icmpne 27 //比较栈顶两个值,如果不相等,则跳转到27 19: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 22: ldc #2 // String Hello, JVM! 24: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 27: return StackMapTable: number_of_entries = 2 frame_type = 252 /* append */ offset_delta = 14 locals = [ int ] frame_type = 12 /* same */ } SourceFile: "Foo.jasm"
附:asmtools.jar的安装(centos 6/7)
0.先cd进入需要安装到的目录地址 1. Mercurial是一种轻量级分布式版本控制系统,采用Python语言实现。yum install hg
2. 版本是2.6.2,发现不是最新版,去官方下载centos 7最新版3.9.2
wget https://www.mercurial-scm.org/release/centos7/RPMS/x86_64/mercurial-3.9.2-1.x86_64.rpm
3.升级2.6.2 到3.9.2 (centos 6 我就没有用这一步。。)
rpm -Uvh mercurial-3.9.2-1.x86_64.rpm
4.安装ASMTOOLS.jar
hg clone http://hg.openjdk.java.net/code-tools/asmtools/ asmtools cd asmtools/build/ yum install ant ant //编译生成asmtools.jar
5.生成的jar位置:
[root@localhost lib]# ls asmtools.jar [root@localhost lib]# pwd /usr/local/asmtools-7.0-build/binaries/lib
相关文章
- 暂无相关文章
用户点评