1

次のことを高レベルで実行する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を使用して、適切なバイトコードを生成するために使用する必要のあるステートメントに関する手がかりを得ました。

4

2 に答える 2

1

mv.visitCode() を使用して、コードが正しいようです。javap は、予想されるバイトコードを示します。元の逆コンパイラが正しいことをしていなかったと思います。

于 2009-08-22T01:05:13.410 に答える
1

おそらくそれは問題ではありませんが、電話するべきではありませんsuper.visitCode()か?

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

TraceClassVisitorを使用して、何が生成されているかを正確に確認します。

于 2009-08-11T23:12:44.163 に答える