Java 如何使用asm向类文件添加简单的invoke语句

Java 如何使用asm向类文件添加简单的invoke语句,java,bytecode,java-bytecode-asm,jvm-bytecode,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方法和用于添加简单print语句的ldc。 [![在此处输入图像描述][1][1] for(Object me

假设我有这个java程序

public class Main {
        public static void main(String []args){
        String a = "Dad";      
        System.out.println(a);
}
现在我有了一个ASM代码来遍历方法节点,并可以访问方法中的指令。假设我添加了invoke方法和用于添加简单print语句的ldc。 [![在此处输入图像描述][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语句之后添加encodeinvoke stmt。
如何实现这一点?

因此您必须使用字符串arg调用encode方法。
首先,您必须编写方法:
publicstaticstringencode(stringarg){/*somecode*/}

然后通过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);

您的第一个代码段和第二个代码段之间以及它们与您在最后描述的内容之间的关系是什么?嘿,我有一个疑问。因此,假设我有一个像debug(“abc”,z)这样的调用函数,并且想要转换为debug(“abc”,encrypt(z)),我应该怎么做?
il.add(newvarinsnnode(opcode.ALOAD,1);
在索引1处加载局部变量(非静态函数中的第一个变量)。
il.add(newmethodinsnnode(opcode.INVOKESTATIC,“full/path/to/Class”,“encode”(Ljava/lang/String;)Ljava/lang/String;“,false);
调用静态函数encode,该函数应该在full.path.to.class
il.add类中(new methodInNode(INVOKEVIRTUAL,“java/io/PrintStream”,“println”,“Ljava/lang/String;)V”);methodNode.insertBefore(abstractNode,il);
调用println函数哪里有问题?