• java ASM

    2016-08-16

    Java ASM
    我們知道Java是靜態語言,而pythonruby是動態語言Java程序一旦寫好很難在運行時更改類的行為,而pythonruby可以。
    不過基于bytecode層面上我們可以做一些手腳,來使Java程序多一些靈活性和MagicASM就是這樣一個應用廣泛的開源庫。

    ASM is a Java bytecode manipulation framework. It can be used to dynamically generate stub classes or other proxy classes,
    directly in binary form, or to dynamically modify classes at load time, i.e., just before they are loaded into the Java
    Virtual Machine.

    ASM
    完成了
    BCELSERP同樣的功能,但ASM
    只有30k,而后兩者分別是350k150kapache真是越來越過氣了。

    讓我們來看一個ASM的簡單例子Helloworld.java,它生成一個Example類和一個main方法,main方法打印"Hello world!"語句:

    Java代碼

    1. import java.io.FileOutputStream;   
    2. import java.io.PrintStream;   
    3.   
    4. import org.objectweb.asm.ClassWriter;   
    5. import org.objectweb.asm.MethodVisitor;   
    6. import org.objectweb.asm.Opcodes;   
    7. import org.objectweb.asm.Type;   
    8. import org.objectweb.asm.commons.GeneratorAdapter;   
    9. import org.objectweb.asm.commons.Method;   
    10.   
    11. public class Helloworld extends ClassLoader implements Opcodes {   
    12.   
    13.   public static void main(final String args[]) throws Exception {   
    14.   
    15.     // creates a ClassWriter for the Example public class,   
    16.     // which inherits from Object   
    17.   
    18.      ClassWriter cw = new ClassWriter(0);   
    19.      cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);   
    20.      MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null,   
    21.         null);   
    22.      mw.visitVarInsn(ALOAD, 0);   
    23.      mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");   
    24.      mw.visitInsn(RETURN);   
    25.      mw.visitMaxs(1, 1);   
    26.      mw.visitEnd();   
    27.      mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main",   
    28.         "([Ljava/lang/String;)V", null, null);   
    29.      mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out",   
    30.         "Ljava/io/PrintStream;");   
    31.      mw.visitLdcInsn("Hello world!");   
    32.      mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",   
    33.         "(Ljava/lang/String;)V");   
    34.      mw.visitInsn(RETURN);   
    35.      mw.visitMaxs(2, 2);   
    36.      mw.visitEnd();   
    37.     byte[] code = cw.toByteArray();   
    38.      FileOutputStream fos = new FileOutputStream("Example.class");   
    39.      fos.write(code);   
    40.      fos.close();   
    41.      Helloworld loader = new Helloworld();   
    42.      Class exampleClass = loader   
    43.          .defineClass("Example", code, 0, code.length);   
    44.      exampleClass.getMethods()[0].invoke(null, new Object[] { null });   
    45.   
    46.     // ------------------------------------------------------------------------   
    47.     // Same example with a GeneratorAdapter (more convenient but slower)   
    48.     // ------------------------------------------------------------------------   
    49.   
    50.      cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);   
    51.      cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);   
    52.      Method m = Method.getMethod("void <init> ()");   
    53.      GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null,   
    54.          cw);   
    55.      mg.loadThis();   
    56.      mg.invokeConstructor(Type.getType(Object.class), m);   
    57.      mg.returnValue();   
    58.      mg.endMethod();   
    59.      m = Method.getMethod("void main (String[])");   
    60.      mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, null, null, cw);   
    61.      mg.getStatic(Type.getType(System.class), "out", Type   
    62.          .getType(PrintStream.class));   
    63.      mg.push("Hello world!");   
    64.      mg.invokeVirtual(Type.getType(PrintStream.class), Method   
    65.          .getMethod("void println (String)"));   
    66.      mg.returnValue();   
    67.      mg.endMethod();   
    68.      cw.visitEnd();   
    69.      code = cw.toByteArray();   
    70.      loader = new Helloworld();   
    71.      exampleClass = loader.defineClass("Example", code, 0, code.length);   
    72.      exampleClass.getMethods()[0].invoke(null, new Object[] { null });   
    73.    }   
    74. }  

    import java.io.FileOutputStream;

    import java.io.PrintStream;

     

    import org.objectweb.asm.ClassWriter;

    import org.objectweb.asm.MethodVisitor;

    import org.objectweb.asm.Opcodes;

    import org.objectweb.asm.Type;

    import org.objectweb.asm.commons.GeneratorAdapter;

    import org.objectweb.asm.commons.Method;

     

    public class Helloworld extends ClassLoader implements Opcodes {

     

      public static void main(final String args[]) throws Exception {

     

        // creates a ClassWriter for the Example public class,

        // which inherits from Object

     

        ClassWriter cw = new ClassWriter(0);

        cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);

        MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null,

            null);

        mw.visitVarInsn(ALOAD, 0);

        mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");

        mw.visitInsn(RETURN);

        mw.visitMaxs(1, 1);

        mw.visitEnd();

        mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main",

            "([Ljava/lang/String;)V", null, null);

        mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out",

            "Ljava/io/PrintStream;");

        mw.visitLdcInsn("Hello world!");

        mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",

            "(Ljava/lang/String;)V");

        mw.visitInsn(RETURN);

        mw.visitMaxs(2, 2);

        mw.visitEnd();

        byte[] code = cw.toByteArray();

        FileOutputStream fos = new FileOutputStream("Example.class");

        fos.write(code);

        fos.close();

        Helloworld loader = new Helloworld();

        Class exampleClass = loader

            .defineClass("Example", code, 0, code.length);

        exampleClass.getMethods()[0].invoke(null, new Object[] { null });

     

        // ------------------------------------------------------------------------

        // Same example with a GeneratorAdapter (more convenient but slower)

        // ------------------------------------------------------------------------

     

        cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);

        cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);

        Method m = Method.getMethod("void <init> ()");

        GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null,


    天堂网