前言

转自:http://hengyunabc.github.io/openjdk-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。

  1. clone代码

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

    1
    2
    cd asmtools/build
    ant

    打包出来的zip包里有一个asmtools.jar

也可以在这里下载我构建的:https://github.com/hengyunabc/hengyunabc.github.io/files/2188258/asmtools-7.0.zip

测试简单的java类

1
2
3
4
5
public class Test {
public static void main(String[] args) {
System.out.println("hello");
}
}

先用javac来编绎:

1
javac Test.java

查看JASM语法结果

1
java -jar asmtools.jar jdis Test.class

结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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语法结果

1
java -jar asmtools.jar jdec Test.class

结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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文件:

1
java -jar asmtools.jar jasm Test.jasm

同样可以从JCOD生成.class文件:

1
java -jar asmtools.jar jcoder Test.jasm

更多使用方法参考: https://wiki.openjdk.java.net/display/CodeTools/Chapter+2#Chapter2-Jasm.1

链接

OpenJDK里的AsmTools简介的更多相关文章

  1. linux里的进程简介

    /sbin/init         内核启动的第一个用户级进程,引导用户空间服务    [kthreadd]         内核线程管理[migration/0]      用于进程在不同的CPU ...

  2. [转帖]PG里面的Citus简介----找时间学习一下.

    1. Citus是什么 是PostgreSQL的扩展,可以同PG一同安装,之后通过SQL命令加入到数据库中. [相关操作] ? 1 2 #创建Citus扩展: CREATE EXTENSION cit ...

  3. OpenJDK和JDK区别

    OpenJDK和JDK区别 OpenJDK与JDK的区别分析 Sun的JDK7.OpenJDK及IcedTea释疑 简介(ps): 简单来说jdk从7开始,弄出一个可以自由使用的公共版本(openjd ...

  4. AsmTools

    前言 https://wiki.openjdk.java.net/display/CodeTools/asmtools 在OpenJDK里有一个AsmTools项目,用来生成正确的或者不正确的java ...

  5. OracleJDK与OpenJDK的区别和联系

    OpenJDK原是SunMicrosystems公司为Java平台构建的Java开发环境(JDK)的开源版本,完全自由,开放源码.OracleJDK里面包含的JVM是HotSpotVM,HotSpot ...

  6. Cocos2d-js官方完整项目教程翻译:六、添加Chipmunk物理引擎在我们的游戏世界里

    添加Chipmunk物理引擎在我们的游戏世界里         一.简介                   cocos2d JS能给我们力量来创造令人印象深刻的游戏世界.但缺乏某种现实.       ...

  7. Python Sklearn.metrics 简介及应用示例

    Python Sklearn.metrics 简介及应用示例 利用Python进行各种机器学习算法的实现时,经常会用到sklearn(scikit-learn)这个模块/库. 无论利用机器学习算法进行 ...

  8. 从字节码层面,解析 Java 布尔型的实现原理

    最近在系统回顾学习 Java 虚拟机方面的知识,其中想到一个很有意思的问题:布尔型在虚拟机中到底是什么类型? 要想解答这个问题,我们看 JDK 的源码是无法解决源码的,我们必须深入到 class 文件 ...

  9. 线程崩溃为什么不会导致 JVM 崩溃

    大家好,我是坤哥 网上看到一个很有意思的据说是美团的面试题:为什么线程崩溃崩溃不会导致 JVM 崩溃,这个问题我看了不少回答,但都没答到根本原因,所以决定答一答,相信大家看完肯定会有收获,本文分以下几 ...

  10. GitHub管理代码-随笔

    公司一直用的SVN进行项目管理,平时便自己折腾了下Git,这里做下GitHub的最简单的记录... 在git上创建仓库等就免谈了,网上也有好多教程,直接从创建之后记录: 在github的readme文 ...

随机推荐

  1. 2023-07-18:给你一个正整数数组 nums,请你移除 最短 子数组(可以为 空), 使得剩余元素的 和 能被 p 整除。 不允许 将整个数组都移除。 请你返回你需要移除的最短子数组的长度,如果

    2023-07-18:给你一个正整数数组 nums,请你移除 最短 子数组(可以为 空), 使得剩余元素的 和 能被 p 整除. 不允许 将整个数组都移除. 请你返回你需要移除的最短子数组的长度,如果 ...

  2. 2023年CCPC河南省程序设计竞赛 mjh

    首先,很荣幸有机会参加此次ccpc,虽然成绩很一般... 这次ccpc一共过了两道签到题.比赛开始就找到了a题,考察字符串的回文判断,通过调用c++库函数过了.第二道签到题类似于数学题.通过类似于找规 ...

  3. 前端Vue自定义开屏启动广告组件,点击广告图跳转广告详情

    随着技术的发展,开发的复杂度也越来越高,传统开发方式将一个系统做成了整块应用,经常出现的情况就是一个小小的改动或者一个小功能的增加可能会引起整体逻辑的修改,造成牵一发而动全身. 通过组件化开发,可以有 ...

  4. Centos7中Oracle占用CPU过高(解决方案)

    Centos7中Oracle占用CPU过高(解决方案) 前言: 99%的问题几乎都是SQL的问题,一般SQL可能会出现以下几种情况: 相关SQL搜索条件没有加索引 索引失效 联合查询过多 数据量过大 ...

  5. Oracle分区表设置详解

    Oracle分区表详解 Oracle建议单表超过2G就需要进行分表,一万数据大概3MB,单表最多分区为1024*1024-1个分区,我感觉够我们使用了哈 废话不多说,上示例,Oracle分表具体sql ...

  6. 【技术积累】Vue中的核心概念【四】

    Vue的生命周期 Vue中的生命周期是指组件从创建到销毁的整个过程中,会触发一系列的钩子函数 Vue2中的生命周期 Vue2中的生命周期钩子函数是在组件的不同阶段执行的特定函数.这些钩子函数允许开发者 ...

  7. Cannot use v-for on stateful component root element because it renders multiple elements.

    <template name:trailerStars> <image v-for="yellow in yellowScore" src="../st ...

  8. 线性关系和非线性关系在.net中的应用

    在数学中,线性关系和非线性关系是描述两个变量之间函数关系的两种不同类型. 线性关系是指两个变量之间可以用一条直线来表示的关系.具体来说,如果存在一个一次函数 y = kx + b,其中k和b是常数,使 ...

  9. MIT6.s081/6.828 lectrue4:page tables 以及 Lab3 心得

    不管是计算机组成还是操作系统,虚拟内存都是其中的重要内容,所以这一节我会结合 CSAPP 第九章:虚拟内存 来一起复习(顺便一说,CSAPP 这一节的 lab 是要求设计一个内存分配器,也是很有意思的 ...

  10. C++函数参数匹配规则

    C++ 函数参数匹配 1 单个参数匹配 void f(); //f1 void f(int); //f2 void f(int, int); //f3 void f(double, double=3. ...