ASM

作者: 抽筋的狗狗 | 来源:发表于2021-08-31 15:50 被阅读0次

    一、ASM版本:

    我们常用的java版本是java8和java11,针对java 8我们需要使用ASM5.0版本,对于java11我们需要使用ASM7.0版本。当然我们可以尽量使用较高的ASM版本


    image.png

    二、ASM能做什么

    •程序分析,范围从简单的语法分析到完整的语义分析,可用于发现应用程序中的潜在错误,
    检测未使用的代码,对代码进行反向工程等。
    •在编译器中使用程序生成。这包括传统编译器,但也包括用于分布式编程的存根或框架编译器、
    即时编译器等。
    •程序转换可用于优化或混淆程序,要在应用程序中插入调试或性能监视代码,用于面向方面编程等。


    image.png

    三、ASM的两个组成部分

    从组成结构上来说,ASM分成两部分,Core API Tree API
    - 其中,Core API包括asm.jar,asm-util.jar和asm-commons.jar
    - 其中,Tree API包括asm-tree.jar和asm-analysis.jar

    四、使用ASM

    4.1. 预期目标

    我们的预期目标是,生成一个HelloWorld类,它对应的Java代码如下:

    package sample;
    
    public class HelloWorld {
        @Override
        public String toString() {
            return "This is a HelloWorld object.";
        }
    }
    

    注意,我们不需要去写这样一个sample/HelloWorld.java文件,只是生成的HelloWorld类和这里的Java代码是一样的效果。

    4.2. 编码实现

    package com.example;
    
    import org.objectweb.asm.*;
    
    public class HelloWorldDump implements Opcodes {
    
        public static byte[] dump() {
            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
    
            cw.visit(V1_8, ACC_PUBLIC | ACC_SUPER, "sample/HelloWorld", null, "java/lang/Object", null);
    
            {
                MethodVisitor mv1 = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
                mv1.visitCode();
                mv1.visitVarInsn(ALOAD, 0);
                mv1.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
                mv1.visitInsn(RETURN);
                mv1.visitMaxs(1, 1);
                mv1.visitEnd();
            }
            {
                MethodVisitor mv2 = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
                mv2.visitCode();
                mv2.visitLdcInsn("This is a HelloWorld object.");
                mv2.visitInsn(ARETURN);
                mv2.visitMaxs(1, 1);
                mv2.visitEnd();
            }
            cw.visitEnd();
    
            return cw.toByteArray();
        }
    }
    

    4.3. 验证结果

    package com.example;
    
    public class MyClassLoader extends ClassLoader {
        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            if ("sample.HelloWorld".equals(name)) {
                byte[] bytes = HelloWorldDump.dump();
                Class<?> clazz = defineClass(name, bytes, 0, bytes.length);
                return clazz;
            }
    
            throw new ClassNotFoundException("Class Not Found: " + name);
        }
    }
    
    package com.example;
    
    public class HelloWorldRun {
        public static void main(String[] args) throws Exception {
            MyClassLoader classLoader = new MyClassLoader();
            Class<?> clazz = classLoader.loadClass("sample.HelloWorld");
            Object instance = clazz.newInstance();
            System.out.println(instance);
        }
    }
    

    运行之后的输出结果:

    This is a HelloWorld object.
    

    相关文章

      网友评论

          本文标题:ASM

          本文链接:https://www.haomeiwen.com/subject/wsiniltx.html