2009-08-11 4 views
1

Я создал агент JVMTI, который делает следующее на высоком уровне:ASM байткод приборы для записи методы/выход

  • onClassLoadHook отправить байткоды для загруженного класса в отдельном процесс Java, который будет инструмент класс с использованием ASM

  • получить байткоды назад и загружать их

В моем отдельном процессе 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); 

} 

Может ли кто-нибудь сказать мне, что я сделал что-то не так? Моя единственная подсказка заключается в том, что если вместо того, чтобы передавать в качестве аргумента моей функции ЭТОЙ указатель, если я передаю примитивные типы, все работает в финале. Есть ли что-то особенное в этом указателе, которым мне нужно управлять? Я сравнивал байт-коды, и я использовал ASMIFIER, чтобы получить представление о том, какие инструкции мне нужно использовать для генерации правильных байт-кодов.

ответ

1

Похоже, что ваш код верен, с mv.visitCode(). javap показывает ожидаемые байткоды. Я предполагаю, что ваш оригинальный декомпилятор просто не поступил правильно.

+0

Спасибо за ответ. Оказывается, вы правы, декомпилятор свободен, а не самый высокий показатель. Начиная с написания этого исходного потока, я начал использовать декомпилятор JAD, который кажется надежным. –

1

Возможно, это не имеет значения, но не следует ли звонить super.visitCode()?

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

Я хотел бы использовать TraceClassVisitor, чтобы проверить точно, что генерируется.

+0

У меня есть вызов super.visitCode() - я просто забыл добавить его к примеру. Хороший улов. Любые другие идеи? Когда я запускаю инструментальный код, он работает, он просто декомпилирует плохо. Спасибо за ответ. –

+0

Я делаю mv.visitCode, а не super.visitCode. Я не думаю, что это проблема. –

+0

Другое открытие - DJ Decompiler сообщает правильный декомпилированный код. –