2009-08-11 8 views
1

J'ai créé un agent JVMTI qui effectue les opérations suivantes à un niveau élevé:ASM instrumentation bytecode pour l'entrée de la méthode/sortie

  • onClassLoadHook envoyer le bytecode pour la classe chargée d'un processus Java distinct qui instrument la classe en utilisant ASM

  • obtenir le bytecode en arrière et de les charger

Dans mon processus java séparé que les instruments de la classe Java chargée que je fais e e suit:

.. ..

cr = new ClassReader(inBytes, offset, inLen); 
    cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); 

    ClassAdapter ca = new ClassAdapter(cw) { 
    .. 
    .. 

     @Override 
     public MethodVisitor visitMethod(final int access, 
             final String name, 
             final String desc, 
             String signature, 
             String[] exceptions) { 

      return new MethodAdapter(mv) { 

       @Override 
       public void visitCode() { 

        mv.visitVarInsn(Opcodes.ALOAD, 0); 
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/amir/Tester", "callTestStatic3", "(Ljava/lang/Object;)V"); 
        mv.visitCode(); 

       } 

      } 
     } 

Lorsque je tente de décompiler la classe qui est écrit après cette instrumentation en utilisant Java Decompiler - Je vois que la fonction décompilé suivante que je sais est faux:

public void func1(int arg1, int arg2) 
    { 
    int b; 
    Tester.callTestStatic3(???); 
    System.out.println("arg = " + a + " b = " + b); 

    } 

parce que ma fonction ressemble en fait comme ceci:

public void func1(int a, int b) 
{ 

    System.out.println("arg = " +a + " b = " +b); 

} 

Quelqu'un peut-il me dire si j'ai fait quelque chose de mal ici? Mon seul indice est que si au lieu de passer en argument à ma fonction le pointeur CE, si je passe en types primitifs, tout finie finie. Y at-il quelque chose de spécial à propos du pointeur CE que je dois gérer? J'ai comparé les bytecodes, et j'ai utilisé ASMIFIER pour avoir une idée des instructions que je dois utiliser pour générer les bons bytecodes.

Répondre

1

Il semble que votre code soit correct, avec mv.visitCode(). javap affiche les bytecodes attendus. Je suppose que votre décompilateur d'origine ne faisait tout simplement pas la bonne chose.

+0

Merci pour la réponse. Il se trouve que vous avez raison, le décompilateur est libre et pas le meilleur indicateur. Depuis l'écriture de ce fil d'origine, j'ai commencé à utiliser JAD Decompiler, qui semble fiable. –

1

Peut-être que ce n'est pas grave, mais ne devriez-vous pas appeler super.visitCode()?

@Override 
public void visitCode() { 
    super.visitCode(); 
    ... 

j'utiliser TraceClassVisitor pour vérifier exactement ce qui a été généré.

+0

J'ai l'appel super.visitCode() - j'ai juste oublié de l'ajouter à l'exemple. Bonne prise. D'autres idées? Quand je lance le code instrumenté ça marche, ça décompile mal. Merci pour la réponse. –

+0

Je fais un mv.visitCode, pas un super.visitCode. Je ne pense pas que c'est un problème. –

+0

Autre découverte: DJ Decompiler signale le code décompilé correct. –