2009-08-11 16 views
1

Ich habe ein JVMTI Mittel geschaffen, das die folgenden auf einem hohen Niveau tut:ASM Bytecode Instrumentierung für Verfahren Entry/Exit

  • onClassLoadHook die Bytecodes für die geladenen Klasse zu einem separaten Java-Prozess zu senden, wird Instrument die Klasse mit ASM

  • den Bytecode zurück und laden sie

In meinem separaten Java-Prozess, die Instrumente der geladene Java-Klasse-I tun th e folgend:

.. ..

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

       } 

      } 
     } 

Wenn ich versuche, um die Klasse zu dekompilieren, die nach dieser Instrumentierung mit Java Decompiler geschrieben - ich sehe die folgende dekompilierten Funktion, die ich kenne, ist falsch:

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

    } 

weil meine Funktion sieht tatsächlich wie folgt aus:

public void func1(int a, int b) 
{ 

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

} 

Kann mir jemand sagen, ob ich hier etwas falsch gemacht habe? Mein einziger Hinweis ist, dass, wenn anstatt als Argument zu meiner Funktion der This-Zeiger, wenn ich in primitiven Typen übergebe, alles funktioniert finie. Gibt es etwas Besonderes an dem THIS-Zeiger, den ich verwalten muss? Ich habe die Bytecodes verglichen, und ich habe ASMIFIER verwendet, um einen Hinweis zu bekommen, welche Anweisungen ich verwenden muss, um die richtigen Bytecodes zu erzeugen.

Antwort

1

Es scheint, dass Ihr Code korrekt ist, mit mv.visitCode(). javap zeigt die erwarteten Bytecodes. Ich nehme an, dein ursprünglicher Decompiler hat einfach nicht das Richtige getan.

+0

Danke für die Antwort. Es stellt sich heraus, dass Sie Recht haben, der Decompiler ist frei und nicht der größte Indikator. Seit ich diesen Original-Thread geschrieben habe, benutze ich den JAD-Decompiler, der zuverlässig erscheint. –

1

Vielleicht ist es egal, aber sollten Sie nicht anrufen super.visitCode()?

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

würde ich TraceClassVisitor benutzen, um genau zu überprüfen, was erzeugt wurde.

+0

Ich habe den Aufruf super.visitCode() - ich habe gerade vergessen, es zu dem Beispiel hinzuzufügen. Guter Fang. Irgendwelche anderen Ideen? Wenn ich den instrumentierten Code benutze, wird er nur schlecht dekompiliert. Danke für die Antwort. –

+0

Ich mache einen mv.visitCode, keinen super.visitCode. Ich denke nicht, dass das ein Problem ist. –

+0

Eine weitere Entdeckung - DJ Decompiler meldet den korrekten dekompilierten Code. –