前言
在OpenJDK里有一个AsmTools项目,用来生成正确的或者不正确的java .class文件,主要用来测试和验证。
我们知道直接修改.class文件是很麻烦的,虽然有一些图形界面的工具,但还是很麻烦。
以前我的办法是用ASMifier从.class文件生成asm java代码,再修改代码,生成新的.class文件,非常麻烦。
AsmTools引入了两种表示.class文件的语法:
重要的是两种语法的文件都是可以和.class互相转换的。
构建AsmTools
官方文档: https://wiki.openjdk.java.net/display/CodeTools/How+to+build+AsmTools
需要有jdk8和ant。
-
clone代码
hg clone http://hg.openjdk.java.net/code-tools/asmtools
-
编绎
cd asmtools/build
ant
打包出来的zip包里有一个asmtools.jar。
也可以在这里下载我构建的:https://github.com/hengyunabc/hengyunabc.github.io/files/2188258/asmtools-7.0.zip
测试简单的java类
public class Test {
public static void main(String[] args) {
System.out.println("hello");
}
}
先用javac来编绎:
javac Test.java
查看JASM语法结果
java -jar asmtools.jar jdis Test.class
结果:
super public class Test
version 52:0
{
public Method "<init>":"()V"
stack 1 locals 1
{
aload_0;
invokespecial Method java/lang/Object."<init>":"()V";
return;
}
public static Method main:"([Ljava/lang/String;)V"
stack 2 locals 1
{
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "hello";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
return;
}
}
查看JCOD语法结果
java -jar asmtools.jar jdec Test.class
结果:
class Test {
0xCAFEBABE;
0;
52;
[] {
;
class #2;
Utf8 "Test";
class #4;
Utf8 "java/lang/Object";
Utf8 "<init>";
Utf8 "()V";
Utf8 "Code";
Method #3 #9;
NameAndType #5 #6;
Utf8 "LineNumberTable";
Utf8 "LocalVariableTable";
Utf8 "this";
Utf8 "LTest;";
Utf8 "main";
Utf8 "([Ljava/lang/String;)V";
Field #17 #19;
class #18;
Utf8 "java/lang/System";
NameAndType #20 #21;
Utf8 "out";
Utf8 "Ljava/io/PrintStream;";
String #23;
Utf8 "hello";
Method #25 #27;
class #26;
Utf8 "java/io/PrintStream";
NameAndType #28 #29;
Utf8 "println";
Utf8 "(Ljava/lang/String;)V";
Utf8 "args";
Utf8 "[Ljava/lang/String;";
Utf8 "SourceFile";
Utf8 "Test.java";
}
0x0021;
#1;
#3;
[] {
}
[] {
}
[] {
{
0x0001;
#5;
#6;
[] {
Attr(#7) {
1;
1;
Bytes[]{
0x2AB70008B1;
}
[] {
}
[] {
Attr(#10) {
[] {
0 2;
}
}
;
Attr(#11) {
[] {
0 5 12 13 0;
}
}
}
}
}
}
;
{
0x0009;
#14;
#15;
[] {
Attr(#7) {
2;
1;
Bytes[]{
0xB200101216B60018;
0xB1;
}
[] {
}
[] {
Attr(#10) {
[] {
0 5;
8 6;
}
}
;
Attr(#11) {
[] {
0 9 30 31 0;
}
}
}
}
}
}
}
[] {
Attr(#32) {
#33;
}
}
}
从JASM/JCOD语法文件生成类文件
因为是等价表达,可以从JASM生成.class文件:
java -jar asmtools.jar jasm Test.jasm
同样可以从JCOD生成.class文件:
java -jar asmtools.jar jcoder Test.jasm
更多使用方法参考: https://wiki.openjdk.java.net/display/CodeTools/Chapter+2#Chapter2-Jasm.1
链接