strumentazione bytecode ASM per l'ingresso metodo / uscita
-
13-09-2019 - |
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.
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.