微信号:importnew

介绍:伯乐在线旗下账号,专注Java技术分享,包括Java基础技术、进阶技能、架构设计和Java技术领域动态等.

OpenJDK 里的 AsmTools 简介

2018-07-28 16:50 ImportNew

(点击上方公众号,可快速关注)


来源:hengyunabc ,

hengyunabc.github.io/openjdk-asmtools/


前言


  • https://wiki.openjdk.java.net/display/CodeTools/asmtools


在OpenJDK里有一个AsmTools项目,用来生成正确的或者不正确的java .class文件,主要用来测试和验证。


我们知道直接修改.class文件是很麻烦的,虽然有一些图形界面的工具,但还是很麻烦。


以前我的办法是用ASMifier从.class文件生成asm java代码,再修改代码,生成新的.class文件,非常麻烦。


AsmTools引入了两种表示.class文件的语法:


  • JASM


用类似java本身的语法来定义类和函数,字节码指令则很像传统的汇编。


  • JCOD


整个.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;

 

}

 

} // end Class Test


查看JCOD语法结果


java -jar asmtools.jar jdec Test.class


结果:


class Test {

  0xCAFEBABE;

  0; // minor version

  52; // version

  [] { // Constant Pool

    ; // first element is empty

    class #2; // #1

    Utf8 "Test"; // #2

    class #4; // #3

    Utf8 "java/lang/Object"; // #4

    Utf8 "<init>"; // #5

    Utf8 "()V"; // #6

    Utf8 "Code"; // #7

    Method #3 #9; // #8

    NameAndType #5 #6; // #9

    Utf8 "LineNumberTable"; // #10

    Utf8 "LocalVariableTable"; // #11

    Utf8 "this"; // #12

    Utf8 "LTest;"; // #13

    Utf8 "main"; // #14

    Utf8 "([Ljava/lang/String;)V"; // #15

    Field #17 #19; // #16

    class #18; // #17

    Utf8 "java/lang/System"; // #18

    NameAndType #20 #21; // #19

    Utf8 "out"; // #20

    Utf8 "Ljava/io/PrintStream;"; // #21

    String #23; // #22

    Utf8 "hello"; // #23

    Method #25 #27; // #24

    class #26; // #25

    Utf8 "java/io/PrintStream"; // #26

    NameAndType #28 #29; // #27

    Utf8 "println"; // #28

    Utf8 "(Ljava/lang/String;)V"; // #29

    Utf8 "args"; // #30

    Utf8 "[Ljava/lang/String;"; // #31

    Utf8 "SourceFile"; // #32

    Utf8 "Test.java"; // #33

  } // Constant Pool

 

  0x0021; // access

  #1;// this_cpx

  #3;// super_cpx

 

  [] { // Interfaces

  } // Interfaces

 

  [] { // fields

  } // fields

 

  [] { // methods

    { // Member

      0x0001; // access

      #5; // name_cpx

      #6; // sig_cpx

      [] { // Attributes

        Attr(#7) { // Code

          1; // max_stack

          1; // max_locals

          Bytes[]{

            0x2AB70008B1;

          }

          [] { // Traps

          } // end Traps

          [] { // Attributes

            Attr(#10) { // LineNumberTable

              [] { // LineNumberTable

                0  2;

              }

            } // end LineNumberTable

            ;

            Attr(#11) { // LocalVariableTable

              [] { // LocalVariableTable

                0 5 12 13 0;

              }

            } // end LocalVariableTable

          } // Attributes

        } // end Code

      } // Attributes

    } // Member

    ;

    { // Member

      0x0009; // access

      #14; // name_cpx

      #15; // sig_cpx

      [] { // Attributes

        Attr(#7) { // Code

          2; // max_stack

          1; // max_locals

          Bytes[]{

            0xB200101216B60018;

            0xB1;

          }

          [] { // Traps

          } // end Traps

          [] { // Attributes

            Attr(#10) { // LineNumberTable

              [] { // LineNumberTable

                0  5;

                8  6;

              }

            } // end LineNumberTable

            ;

            Attr(#11) { // LocalVariableTable

              [] { // LocalVariableTable

                0 9 30 31 0;

              }

            } // end LocalVariableTable

          } // Attributes

        } // end Code

      } // Attributes

    } // Member

  } // methods

 

  [] { // Attributes

    Attr(#32) { // SourceFile

      #33;

    } // end SourceFile

  } // Attributes

} // end class Test


从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


链接


  • https://wiki.openjdk.java.net/display/CodeTools/Appendix+A JASM Syntax

  • https://wiki.openjdk.java.net/display/CodeTools/Appendix+B JCOD Syntax


【关于投稿】


如果大家有原创好文投稿,请直接给公号发送留言。


① 留言格式:
【投稿】+《 文章标题》+ 文章链接

② 示例:
【投稿】《不要自称是程序员,我十多年的 IT 职场总结》:http://blog.jobbole.com/94148/

③ 最后请附上您的个人简介哈~



看完本文有收获?请转发分享给更多人

关注「ImportNew」,提升Java技能

 
ImportNew 更多文章 深入学习 Java 线程池 你需要学好知识图谱----用 AI 技术连接世界 JDK 11 已处于特性冻结状态,看看 Java 11 API 变更 Spring 中获取 request 的几种方法,及其线程安全性分析 详解 equals() 方法和 hashCode() 方法
猜您喜欢 MySQL online create index实现原理 回顾 | 技术沙龙Kotlin专场总结 2017余额仅剩1\/2!这些热门技术你学到了几成? etcd:从应用场景到实现原理的全方位解读 GoHackers社群的这半年