首页 > 编程语言 >玩转java bytecode第一篇从java到asm的转换。

玩转java bytecode第一篇从java到asm的转换。

时间:2022-11-24 13:05:15浏览次数:61  
标签:lang java methodVisitor mv ICONST bytecode visitInsn asm


java源码

public class SimpleMain {
public static void main(String[] args){
System.out.println("333:");

}
}

javap反汇编​​javap -p -c -s -l TestAsmTrans.class​​​​-l​​​ 显示本地变量表 ​​-c​​ 反汇编

E:\eclipse_workspace\TestAsm\bin>javap -p -c -s -l TestAsmTrans.class

结果如下:

Compiled from "TestAsmTrans.java"
public class TestAsmTrans {
public TestAsmTrans();
descriptor: ()V
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 2: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LTestAsmTrans;

public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
Code:
0: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #22 // String 333:
5: invokevirtual #24 // Method java/io/PrintStream.println:(Ljava/lang/Stri
8: return
LineNumberTable:
line 4: 0
line 6: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 args [Ljava/lang/String;
}

E:\eclipse_workspace\TestAsm\bin>

转换为更加容易看懂的代码
eclipse下载byptecode view插件




玩转java bytecode第一篇从java到asm的转换。_js


image.png


public class TestAsmTrans {

// compiled from: TestAsmTrans.java

// access flags 0x1
public <init>()V
L0
LINENUMBER 2 L0
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
RETURN
L1
LOCALVARIABLE this LTestAsmTrans; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1

// access flags 0x9
public static main([Ljava/lang/String;)V
L0
LINENUMBER 4 L0
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "333:"
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L1
LINENUMBER 6 L1
RETURN
L2
LOCALVARIABLE args [Ljava/lang/String; L0 L2 0
MAXSTACK = 2
MAXLOCALS = 1
}

asm转换。

L0就表示​​label0​

ClassWriter classWriter = new ClassWriter(0);
FieldVisitor fieldVisitor;
MethodVisitor methodVisitor;
AnnotationVisitor annotationVisitor0;

classWriter.visit(V1_8, ACC_PUBLIC | ACC_SUPER, "test/SimpleMain", null, "java/lang/Object", null);

classWriter.visitSource("SimpleMain.java", null);

{
methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
methodVisitor.visitCode();
Label label0 = new Label();
methodVisitor.visitLabel(label0);
methodVisitor.visitLineNumber(7, label0);
methodVisitor.visitVarInsn(ALOAD, 0);
methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
methodVisitor.visitInsn(RETURN);
Label label1 = new Label();
methodVisitor.visitLabel(label1);
methodVisitor.visitLocalVariable("this", "Ltest/SimpleMain;", null, label0, label1, 0);
methodVisitor.visitMaxs(1, 1);
methodVisitor.visitEnd();
}
{
methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
methodVisitor.visitCode();
Label label0 = new Label();
methodVisitor.visitLabel(label0);
methodVisitor.visitLineNumber(9, label0);
methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
methodVisitor.visitLdcInsn("333:");
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
Label label1 = new Label();
methodVisitor.visitLabel(label1);
methodVisitor.visitLineNumber(11, label1);
methodVisitor.visitInsn(RETURN);
Label label2 = new Label();
methodVisitor.visitLabel(label2);
methodVisitor.visitLocalVariable("args", "[Ljava/lang/String;", null, label0, label2, 0);
methodVisitor.visitMaxs(2, 1);
methodVisitor.visitEnd();
}
classWriter.visitEnd();

return classWriter.toByteArray();
}
}

调用顺序

* visit visitSource? visitOuterClass? ( visitAnnotation | visitAttribute )*( visitInnerClass | visitField |
* visitMethod )*
* visitEnd

更多操作

java

class TestIntByte {
@Test
public void test() {
System.out.println(new int[]{133333333, 66663, 4666663, 533333, 633333333});
}

@Test
public void testCharByInt() {
System.out.println(new char[]{(char) 5, (char) 6, (char) 7, (char) 333});
}

@Test
public void testChar1() {
System.out.println(new char[]{'b', 'd', 'n', 'a'});
}

@Test
public void testLong() {
System.out.println(new long[]{100l,600l,15550l,3330l});
}


@Test
public void testFloat() {
System.out.println(new float[]{100.0f,600f,15550f,3330f});
}
}

asm

F:\src\git_project\RXJavaStudy\tools\asm-all-6.0_BETA>java -cp asm-6.0.jar org.objectweb.asm.util.ASMifier TestIntByte.class
import java.util.*;
import org.objectweb.asm.*;
public class TestIntByteDump implements Opcodes {

public static byte[] dump () throws Exception {

ClassWriter cw = new ClassWriter(0);
FieldVisitor fv;
MethodVisitor mv;
AnnotationVisitor av0;

cw.visit(V1_8, ACC_SUPER, "TestIntByte", null, "java/lang/Object", null);

{
mv = cw.visitMethod(0, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "test", "()V", null, null);
{
av0 = mv.visitAnnotation("Lorg/junit/Test;", true);
av0.visitEnd();
}
mv.visitCode();
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitInsn(ICONST_5);
mv.visitIntInsn(NEWARRAY, T_INT);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_0);
mv.visitLdcInsn(new Integer(133333333));
mv.visitInsn(IASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_1);
mv.visitLdcInsn(new Integer(66663));
mv.visitInsn(IASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_2);
mv.visitLdcInsn(new Integer(4666663));
mv.visitInsn(IASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_3);
mv.visitLdcInsn(new Integer(533333));
mv.visitInsn(IASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_4);
mv.visitLdcInsn(new Integer(633333333));
mv.visitInsn(IASTORE);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/Object;)V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(5, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "testCharByInt", "()V", null, null);
{
av0 = mv.visitAnnotation("Lorg/junit/Test;", true);
av0.visitEnd();
}
mv.visitCode();
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitInsn(ICONST_4);
mv.visitIntInsn(NEWARRAY, T_CHAR);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_0);
mv.visitInsn(ICONST_5);
mv.visitInsn(CASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_1);
mv.visitIntInsn(BIPUSH, 6);
mv.visitInsn(CASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_2);
mv.visitIntInsn(BIPUSH, 7);
mv.visitInsn(CASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_3);
mv.visitIntInsn(SIPUSH, 333);
mv.visitInsn(CASTORE);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "([C)V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(5, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "testChar1", "()V", null, null);
{
av0 = mv.visitAnnotation("Lorg/junit/Test;", true);
av0.visitEnd();
}
mv.visitCode();
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitInsn(ICONST_4);
mv.visitIntInsn(NEWARRAY, T_CHAR);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_0);
mv.visitIntInsn(BIPUSH, 98);
mv.visitInsn(CASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_1);
mv.visitIntInsn(BIPUSH, 100);
mv.visitInsn(CASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_2);
mv.visitIntInsn(BIPUSH, 110);
mv.visitInsn(CASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_3);
mv.visitIntInsn(BIPUSH, 97);
mv.visitInsn(CASTORE);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "([C)V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(5, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "testLong", "()V", null, null);
{
av0 = mv.visitAnnotation("Lorg/junit/Test;", true);
av0.visitEnd();
}
mv.visitCode();
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitInsn(ICONST_4);
mv.visitIntInsn(NEWARRAY, T_LONG);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_0);
mv.visitLdcInsn(new Long(100L));
mv.visitInsn(LASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_1);
mv.visitLdcInsn(new Long(600L));
mv.visitInsn(LASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_2);
mv.visitLdcInsn(new Long(15550L));
mv.visitInsn(LASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_3);
mv.visitLdcInsn(new Long(3330L));
mv.visitInsn(LASTORE);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/Object;)V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(6, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "testFloat", "()V", null, null);
{
av0 = mv.visitAnnotation("Lorg/junit/Test;", true);
av0.visitEnd();
}
mv.visitCode();
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitInsn(ICONST_4);
mv.visitIntInsn(NEWARRAY, T_FLOAT);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_0);
mv.visitLdcInsn(new Float("100.0"));
mv.visitInsn(FASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_1);
mv.visitLdcInsn(new Float("600.0"));
mv.visitInsn(FASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_2);
mv.visitLdcInsn(new Float("15550.0"));
mv.visitInsn(FASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_3);
mv.visitLdcInsn(new Float("3330.0"));
mv.visitInsn(FASTORE);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/Object;)V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(5, 1);
mv.visitEnd();
}
cw.visitEnd();

return cw.toByteArray();
}
}

更多技巧使用 官网的工具​​https://asm.ow2.io/javadoc/overview-summary.html​

可以方便快捷的查看,可惜,我当时在公司研究忘记上传github了,当时是做了一个脚本来着
可以边写边预览源代码。


标签:lang,java,methodVisitor,mv,ICONST,bytecode,visitInsn,asm
From: https://blog.51cto.com/u_15458814/5883456

相关文章

  • javascript:void() 和 herf="#" 区别
    javascript:void(0)和herf="#"区别本文内容参考菜鸟教程(大部分都是原文内容)原文地址javascript:void(0)的含义我们经常会使用到javascript:void(0)这样的代码......
  • Java 设计模式:装饰器模式
    目录装饰器模式(DecoratorPattern)概述实现业界实践装饰器模式(DecoratorPattern)概述所属:结构型模式,作为现有的类的一个包装。适用时机:扩展某个类的时候。不使用子类继......
  • DAY06_Java方法
    d06Java方法(p45-p50)1.什么是方法?System.out.println() 类.对象.方法()调用系统类System中的标准输出对象out中的println()方法Java方法是语句的集合,它们在一起执......
  • Java工具类
    BeanUtils.copyProperties排除null属性的copyimportcom.hourumiyue.system.SpringUtil;importorg.springframework.beans.BeanUtils;importorg.springframework.b......
  • Java对象拷贝原理剖析及最佳实践
    作者:宁海翔1前言对象拷贝,是我们在开发过程中,绕不开的过程,既存在于Po、Dto、Do、Vo各个表现层数据的转换,也存在于系统交互如序列化、反序列化。Java对象拷贝分为深拷贝......
  • java.lang.IllegalArgumentException: Invalid character found in the request targe
    摘要:文件下载时,出现如下异常信息:2020-08-2416:18:35:136ErrorparsingHTTPrequestheaderNote:furtheroccurrencesofHTTPrequestparsingerrorswillbelogged......
  • 易语言toJava 集合类
    易语言toJava集合类.版本2.程序集集合Map类,,公开,不允许键存在.程序集变量mContentValueMap,Map,,"0".程序集变量mSplit,文本型,,,&分割符.程序集变量mK......
  • 力扣81(java&python)-搜索旋转排序数组 II(中等)
    题目:已知存在一个按非降序排列的整数数组nums,数组中的值不必互不相同。在传递给函数之前,nums在预先未知的某个下标k(0<=k<nums.length)上进行了旋转,使数组变为[......
  • Java重点 | 抽象
    抽象抽象的概念抽象方法和抽象类的格式抽象方法:就是加上abstract关键字,然后去掉大括号,直接分号结束。抽象类:抽象方法所在的类,必须是抽象类才行。在class之前写上abs......
  • Spring-纯Java创建一个SSM【webapp】
    纯Java搭建webappQuickStart使用纯Java来搭建一个SSM环境,即在项目中,不存在任何XML配置,包括web.xml1创建一个Maven工程引入依赖<!--TODO【Java创建SSM】1......