OpenJDK里的AsmTools简介

简介: 前言https://wiki.openjdk.java.net/display/CodeTools/asmtools 在OpenJDK里有一个AsmTools项目,用来生成正确的或者不正确的java .class文件,主要用来测试和验证。

前言

在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。

  1. clone代码

    hg clone http://hg.openjdk.java.net/code-tools/asmtools
  2. 编绎

    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

链接

相关文章
|
Java
Mac下安装JDK11(国内镜像)
Mac下安装JDK11(国内镜像)
7593 0
|
并行计算 异构计算
CUDA streamCUDA流的基本概念
CUDA streamCUDA流的基本概念
2477 0
CUDA streamCUDA流的基本概念
|
9月前
|
SQL 缓存 关系型数据库
如何解决MySQL 的深度分页问题?
在构建高性能Web应用程序时,数据库查询性能至关重要。本文深入探讨了MySQL中`LIMIT ... OFFSET ...`语法的性能瓶颈,并介绍了一种更高效的分页方法——游标分页(Cursor Pagination)。通过记录每页最后一个记录的唯一标识,游标分页能显著提升查询效率,将时间复杂度从O(n + m)降低到O(log n + m),特别适用于大规模数据的分页查询场景。此外,文章还介绍了其他优化方法,如覆盖索引分页、分区表、缓存和基于时间戳的分页,并提供了实践中的最佳建议,帮助开发者选择最适合的分页策略,提升系统性能和用户体验。
561 9
|
9月前
|
存储 人工智能 运维
首批!阿里云飞天企业版率先通过中国信通院一云多算能力评估
阿里云飞天企业版率先参加中国信通院组织的首批一云多算系列标准的评估,并成功通过该标准的验收测试与专家评审。
222 2
首批!阿里云飞天企业版率先通过中国信通院一云多算能力评估
|
人工智能 搜索推荐 机器人
AppFlow无代码轻松搭建模型Agent
使用钉钉,现在每个人都能轻松创建自己的AI助手。通过结合各种插件,如天气、机票查询和地图,你可以定制个性化的工作助手。利用AppFlow,即使没有编程经验也能搭建AI Agent。步骤包括:1) 在钉钉开放平台创建应用,获取凭证;2) 在钉钉卡片平台创建AI卡片实例;3) 在AppFlow配置连接流,添加所需插件;4) 创建钉钉机器人,设置HTTP消息接收并关联AppFlow的Webhook。完成这些步骤后,你就可以在钉钉群中与你的AI助手互动了。
52161 13
|
11月前
鸿蒙原生开发手记:02-服务卡片开发
服务卡片是桌面小组件,分为静态和动态两类。本文介绍如何在 DevEco 中创建静态服务卡片,并实现点击事件传参和参数接收。创建时需选择支持的卡片大小,使用 FormLink 实现跳转,参数在 `entryability` 的生命周期方法中接收。注意:服务卡片不支持热重载。
435 1
鸿蒙原生开发手记:02-服务卡片开发
|
机器学习/深度学习 人工智能 自然语言处理
【深度学习】python之人工智能应用篇--跨模态生成技术
跨模态生成技术是一种将不同模态的数据(如文本、图像、音频、视频等)进行融合和转换的技术。其目标是通过将一个模态的数据作为输入,生成与之对应的另一个模态的输出。这种技术对于突破单一模态的局限性,提高信息处理的准确性和丰富性具有重要意义。跨模态生成技术主要依赖于深度学习和生成模型,通过学习和模拟不同模态之间的映射关系来实现模态间的转换。
424 1
|
存储 安全 Linux
Linux命令sync详解
`sync`命令在Linux中用于将内存缓冲区的数据强制写入磁盘,保证数据持久性和一致性。它在关机、重启或重要文件操作前后使用,以防数据丢失。工作原理是强制将内存中的数据同步到磁盘,特点是阻塞式执行且通常无需参数。常见用法包括安全关机、数据备份和配置文件修改后确保更改生效。应注意,过度使用可能影响性能,应适时使用`fsck`检查文件系统一致性。
[C++&OpenCv] 两点距离、三点角度的计算
[C++&OpenCv] 两点距离、三点角度的计算
313 0
|
数据安全/隐私保护 计算机视觉 Python
Python批量图片去水印,提高工作效率
Python批量图片去水印,提高工作效率
513 0