次のことを高レベルで実行するJVMTIエージェントを作成しました。
onClassLoadHookは、ロードされたクラスのバイトコードを、ASMを使用してクラスをインストルメント化する別のJavaプロセスに送信します
バイトコードを取り戻し、それらをロードします
ロードされたJavaクラスをインストルメント化する別のJavaプロセスでは、次のことを行います。
...。
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();
}
}
}
Java Decompilerを使用して、このインストルメンテーションの後に記述されたクラスを逆コンパイルしようとすると、次の逆コンパイルされた関数が間違っていることがわかります。
public void func1(int arg1, int arg2)
{
int b;
Tester.callTestStatic3(???);
System.out.println("arg = " + a + " b = " + b);
}
私の関数は実際には次のようになっているためです:
public void func1(int a, int b)
{
System.out.println("arg = " +a + " b = " +b);
}
私がここで何か間違ったことをしたかどうか誰かに教えてもらえますか?私の唯一の手がかりは、関数に引数としてTHISポインターを渡す代わりに、プリミティブ型を渡すと、すべてがうまくいくということです。私が管理する必要があるこのポインターについて何か特別なことはありますか?バイトコードを比較し、ASMIFIERを使用して、適切なバイトコードを生成するために使用する必要のあるステートメントに関する手がかりを得ました。