前言

转自: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. Magick.NET跨平台压缩图片的用法

    //首先NuGet安装:Magick.NET.Core,Magick.NET-Q16-AnyCPUusing ImageMagick; /// <summary> /// 压缩图片 /// ...

  2. Numpy,一篇足以

    numpy 用于数值计算 ndarray, 一个有效的多维数组,能提供以数组为导向的快速数值计算和灵活的广播功能(broadcasting) 便利的数学函数 用于读取/写入(reading/writi ...

  3. 医疗知识图谱问答 ——Neo4j 基本操作

    前言 说到问答机器人,就不得不说一下 ChatGPT 啦.一个预训练的大预言模型,只要是人类范畴内的知识,似乎他回答得都井井有条,从写文章到写代码,再到解决零散琐碎的问题,不光震撼到我们普通人,就百度 ...

  4. 洛谷 P1336 最佳课题选择 题解

    P1336 最佳课题选择 题解 状态:考虑\(f_{i,j}\)表示前\(i\)种论文里面,一共写了\(j\)篇,的最少花费时间. 转移策略:我们一次考虑每一种论文写多少篇.假设写\(k\)篇,\(k ...

  5. IDA的使用-1

    IDA的使用-1 主要收集我自己需要掌握的或者以前不知道的 开始界面 重载文件 在我们逆向过程中被文件修改过,这个时候需要我们重载一下,比如说开发过程中加点代码之类的 下面是加载额外文件,这个文件和我 ...

  6. .NET周刊【8月第3期 2023-08-20】

    国内主题 抓的是周树人,与我鲁迅有什么关系? https://www.cnblogs.com/JulianHuang/p/17642511.html 问题:作者看到了一个关于Dictionary.Cl ...

  7. 如何使用API接口获取Lazada商品详情数据

    随着电商市场的不断发展壮大,越来越多的人开始选择在网上购买商品.其中,东南亚地区的Lazada电商平台备受欢迎.如果您是一名电商从业者,或者打算在Lazada上开店,那么获取商品详情信息将是一个非常重 ...

  8. QA|requests接口请求失败而postman请求成功原因排查|Requests

    requests接口请求失败而postman请求成功原因 代码如下 1 def ihrm_login(login_data, url1): 2 """login_data ...

  9. QA|外部调用类方法总报错missing 1 required positional argument:'self'|UI自动化

    外部调用类方法总报错missing 1 required positional argument:'self' 原因:实例化这个类 实例化错了,少了括号() 解决:改成如下就可以了 参考学习:调用类方 ...

  10. Frida环境配置

    目录 安装Linux客户端 配置Android服务端 测试运行效果 官方手册 安装Linux客户端 github地址:https://github.com/frida/frida pip instal ...