Domanda

Ho creato un agente JVMTI che fa quanto segue a un livello elevato:

  • onClassLoadHook inviare i bytecode per la classe caricata a un processo Java separato che sarà strumento della classe utilizzando ASM

  • ottenere il bytecode indietro e caricarli

Nel mio processo java separata che gli strumenti della classe Java caricata faccio la seguente:

.. ..

    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();

                }

            }
        }

Quando si tenta di decompilare la classe che viene scritto dopo questa strumentazione utilizzando Java Decompiler - vedo la seguente funzione decompilato che so essere sbagliato:

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

  }

perché la mia funzione cerca in realtà in questo modo:

public void func1(int a, int b) 
{

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

}

Qualcuno può dirmi se ho fatto qualcosa di sbagliato qui? Il mio unico indizio è che se invece di passare come argomento per la mia funzione il puntatore this, se mi passate in tipi primitivi, tutto funziona finie. C'è qualcosa di speciale per il puntatore QUESTO che ho bisogno di gestire? Ho confrontato il bytecode, e ho usato ASMIFIER per ottenere un indizio su quello che le dichiarazioni che ho bisogno di utilizzare per generare il bytecode di destra.

È stato utile?

Soluzione

Sembra che il codice è corretto, con mv.visitCode (). javap mostra i bytecode attesi. Credo che il tuo decompilatore originale solo che non stava facendo la cosa giusta.

Altri suggerimenti

Forse non importa, ma non dovrebbe essere chiamata super.visitCode()?

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

TraceClassVisitor controllare esattamente ciò che è stato generato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top