Как добавить простое выражение invoke в файл класса, используя asm - PullRequest
0 голосов
/ 06 июня 2018

Предположим, у меня есть эта Java-программа.

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

Теперь у меня есть код ASM для обхода узлов метода и я могу получить доступ к инструкции в методе.Скажем, я добавил метод invoke и 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, то есть использование переменной, яЯ хочу вызвать функцию кодирования так, чтобы переменная кодировалась во время использования. Поэтому я планирую добавить кодирование invoke stmt после оператора ALOAD.Как этого добиться?

1 Ответ

0 голосов
/ 31 января 2019

Таким образом, вы должны вызвать метод кодирования со строкой arg.
Прежде всего вы должны написать метод: 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);
...