前言
本节就来记录下我安装asmtools的过程,以及第一次使用awk的笔记。一开始我是觉得不太需要写博客记录的,无奈网上的教程都不太完整,结果只能自己看文档,并记录整个过程了。
顺便介绍一下asmtools,它可以强制修改Java编译后的.class
文件,这样就极大地方便我们做某些实验了。
另外,本文不会再提及Jdk的安装步骤,相信这种基础中的基础应该不需要我多言了。
实验环境
- 操作系统:Centos 7.4(64位)
- Java version:1.8.0_111
- Apache Ant version:1.9.14
- asmtools-7.0(GNU Awk 4.0.2)
除了jdk和操作系统,剩下的两都会记录详细步骤。
安装Apache-ant
安装asmtools需要有ant作为基础环境,下面就来安装ant。
官网下载地址:https://ant.apache.org/bindownload.cgi
我下载的是1.9.14版本的zip包,如下图:
你也可以选择你喜欢的包下载。
下载解压过程略,最终目录结构如下:
接下来就是要配置ant的环境变量了,下面我就贴出我环境变量的一部分,具体目录和写法你可以自己发挥:
> vi /etc/profile
...(略)
export PATH=$PATH:/usr/local/nginx/sbin
JAVA_HOME=/usr/local/jdk1.8.0_111;
ZOOKEEPER_HOME=/opt/softwares/zookeeper-3.4.5-cdh5.3.6;
ANT_HOME=/root/asmtools/apache-ant-1.9.14;
export PATH=$PATH:$JAVA_HOME/bin
export PATH=$PATH:/usr/local/node/bin
export PATH=$PATH:$ZOOKEEPER_HOME/bin
export PATH=$PATH:$ANT_HOME/bin
export PATH=$PATH:
保存退出后,不要忘了刷新环境变量:
> source /etc/profile
到这里,正常来说已经安装完成了,验证方法如下:
> ant -version
Apache Ant(TM) version 1.9.14 compiled on March 12 2019
当上面这条命令返回版本号,就证明安装成功了。
有了ant的基础环境后,接下来就可以开始安装asmtools了。
安装asmtools
官网下载地址:http://hg.openjdk.java.net/code-tools/asmtools/
选择你喜欢的包下载:
下载、解压过程略,看看解压后目录结构:
再看看上级目录:
进入build目录:
> cd (你的目录)/asmtools-版本号/build
在build目录里面执行ant
:
> ant
然后控制台就balabala的输出日志,看到如下日志输出BUILD SUCCESSFUL
就证明安装完成了:
此时返回到asmtools的同级目录,就能看见构建后的代码了:
构建完成之后,我们还得记住asmtools.jar的位置:
> cd (你的目录)/asmtools-7.0-build/binaries/lib
进入lib后,就能看到asmtools.jar了,记住它现在的位置,后面执行awk的时候会用上:
OK,现在ant和asmtools都安装好了,接下来就可以用awk命令做个简单的实验了。
使用awk
先创建实验代码:
Hello.java
public class Hello {
public static void main(String[] args){
boolean flag = true;
if (flag) System.out.println("Hello, Java!");
if (flag == true) System.out.println("Hello, JVM!");
}
}
先原始编译,然后执行:
> javac Hello.java
> java Hello
输出结果:
Hello, Java!
Hello, JVM!
在java虚拟机规范,以及java编译器中,true编译后只能是整数1,false编译后只能是整数0。而现在,我们需要用awk强制改变编译后的.class文件。继续执行如下命令:
> java -cp /root/asmtools-7.0-build/binaries/lib/asmtools.jar org.openjdk.asmtools.jdis.Main Hello.class > Hello.jasm.1
- asmtools.jar请改成你自己的路径。
执行完上述命令后,会发现当前代码的目录多个个Hello.jasm.1文件,这个文件你可以当做是反编译后的一种格式,awk就是按照格式约定去修改这个文件的。有兴趣的可以看看文件内容长什么样,由于比较长我就不贴出来了。
下面使用awk去修改上面生成的文件,把原本flag转换成的1改成2:
> awk 'NR==1,/iconst_1/{sub(/iconst_1/, "iconst_2")} 1' Hello.jasm.1 > Hello.jasm
再执行如下命令完成修改.class文件:
> java -cp /root/asmtools-7.0-build/binaries/lib/asmtools.jar org.openjdk.asmtools.jasm.Main Hello.jasm
现在尝试再次执行Hello:
> java Hello
输出结果:
Hello, Java!
因为flag已经被我们强制改成2了,所以flag == true就相当于0 == 1,返回结果当然是fasle,最终导致不会再输出第二段结果。
2怎么变成0了?因为2转为二进制就是
10
,而HotSpot中存储boolean只用一字节,只取最后一位,即取到0。不信的话你可以改成iconst_3,会发现flag == true返回true,因为3的二进制是11
。