如何使用asm将简单的invoke语句添加到类文件中

时间:2018-06-06 18:50:10

标签: java bytecode java-bytecode-asm jvm-bytecode

考虑一下我有这个java程序。

public class Main {
        public static void main(String []args){
        String a = "Dad";      
        System.out.println(a);
}

现在我有一个ASM代码遍历方法节点并可以访问方法中的指令。假设我添加了invoke方法和ldc来添加简单的print语句。 [![在此处输入图像说明] [1]] [1]

    for(Object methodNodeObj : classNode.methods) { 
        MethodNode methodNode = (MethodNode)methodNodeObj;  
        for(AbstractInsnNode abstractInsnNode : methodNode.instructions.toArray()) { 
        }
        InsnList il = new InsnList();
        il.add(new FieldInsnNode(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
        il.add(new LdcInsnNode("Works!"));
        il.add(new MethodInsnNode(INVOKEVIRTUAL, "java/io/PrintStream", "encode", "(Ljava/lang/String;)V"));
         methodNode.instructions.insertBefore(abstractNode, il);

这有助于打印声明...... 假设我有一个ALOAD语句,有一个变量用法,我想调用encode函数调用,以便在使用过程中对变量进行编码。 所以我的计划是在ALOAD语句之后添加encode invoke stmt。 怎么做到这一点?

1 个答案:

答案 0 :(得分:0)

因此,您必须使用字符串arg调用encoding方法。
首先,您必须编写方法:public static String encode(String arg) { /* Some code */ }
比您可以通过asm调用该方法

il.add(new FieldInsnNode(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
// 1 - first variable in non-static function
// 0 - first variable in static funcnion. Choose wisely.
il.add(new VarInsnNode(Opcodes.ALOAD, 1);
// itf must be true if full.path.to.Class is interface
il.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "full/path/to/Class", "encode", "(Ljava/lang/String;)Ljava/lang/String;", false); 
il.add(new MethodInsnNode(INVOKEVIRTUAL, "java/io/PrintStream", "encode", "(Ljava/lang/String;)V"));
     methodNode.instructions.insertBefore(abstractNode, il);