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