Выбрать и протестировать jcom-декомпилятор

Теперь я пытаюсь найти лучший декомпилятор java, я нашел их:

С помощью этих декомпиляторов я обрабатываю байтовый код этого класса:

public class ss
{
public static void main(String args[])
{
  try{
   System.out.println("try");

  }
  catch(Exception e)
  {
   System.out.println("catch");
  }
  finally
  {System.out.println("finally");}
}
}

и я получил следующие результаты:

fernflower:

public class ss {

   public static void main(String[] var0) {
      try {
         System.out.println("try");
      } catch (Exception var5) {
         System.out.println("catch");
      } finally {
         System.out.println("finally");
      }

   }
}

DJ Decompiler:

import java.io.PrintStream;

public class ss
{

    public ss()
    {
    }

    public static void main(String args[])
    {
        System.out.println("try");
        System.out.println("finally");
        break MISSING_BLOCK_LABEL_50;
        Exception exception;
        exception;
        System.out.println("catch");
        System.out.println("finally");
        break MISSING_BLOCK_LABEL_50;
        Exception exception1;
        exception1;
        System.out.println("finally");
        throw exception1;
    }
}

cavaj:

import java.io.PrintStream;

public class ss
{

    public ss()
    {
    }

    public static void main(String args[])
    {
        System.out.println("try");
        System.out.println("finally");
        break MISSING_BLOCK_LABEL_50;
        Exception exception;
        exception;
        System.out.println("catch");
        System.out.println("finally");
        break MISSING_BLOCK_LABEL_50;
        Exception exception1;
        exception1;
        System.out.println("finally");
        throw exception1;
    }
}

http://java.decompiler.free.fr/:

import java.io.PrintStream;
public class ss
{
  public static void main(String[] paramArrayOfString)
  {
    try
    {
      System.out.println("try");
    }
    catch (Exception localException)
    {
      System.out.println("catch");
    }
    finally {
      System.out.println("finally");
    }
  }
}

Я вижу, что лучший результат в декомпиляторе: http://java.decompiler.free.fr/

Чтобы проверить, я написал очень простой код. Как вы думаете, какой код писать для тестирования декомпиляторов? Может быть, идея лучше, чем попробовать {} catch() {} finally {}?

Ответ 1

Код, который вы используете для тестирования, должен проверять доступные функции в JDK для компиляции целевого класса. Например, если вы знаете, что ваша цель написана на Java 1.5, разумно предположить, что код может включать generics, поэтому вы захотите убедиться, что ваш выбранный декомпилятор правильно их обрабатывает. По моему опыту, свободно доступные декомпиляторы, как правило, отстают от выпусков JDK с точки зрения функций, которые они поддерживают в 1-2 выпусках.

Основываясь на личной пробной версии и ошибке, JD имеет тенденцию делать лучшую работу в целом. Однако, если вы декомпилируете код, написанный в 1.3 или ниже, я также предлагаю вам попробовать JODE.

Ответ 3

Я долгое время использовал http://java.decompiler.free.fr/ и нашел, что это лучший. В частности, я использовал его для декомпиляции сторонней банки, и мне также удалось изменить исходный код.

Прост в использовании, а пользовательский интерфейс также является аккуратным и чистым.

Обновление: Java Decompiler больше не доступен на http://java.decompiler.free.fr/. Он имеет новую ссылку http://jd.benow.ca/, откуда она может быть загружена.

Ответ 4

Похоже, что fernflower и JD Java Decompiler создают декомпилированный код, который настолько хорош, насколько это возможно для данного тестового теста. Другие два не делают хорошую работу, ИМО.

Как вы думаете, какой код писать для тестирования декомпиляторов?

  • Напишите более сложный код, используя все доступные конструкции.
  • Попробуйте использовать какой-нибудь реальный код.
  • Попробуйте использовать какой-нибудь реальный код, который был запутан.

При тестировании кода, который вы компилируете из источника, экспериментируйте с разными параметрами "-g" и с различными компиляторами Java.

Ответ 5

Если вы ожидаете получить какие-либо значимые результаты, вам действительно нужно протестировать несколько более нетривиальный код. Fernflower был создан с целью обработки необычного и запутанного байт-кода. Таким образом, декомпиляция таких простых фрагментов не имеет большого значения. Кстати, если вы заинтересованы в тестировании автономной версии Fernflower, напишите мне на декомпилятор fernflower (dot) decompiler (at) gmail (dot) com. Версия 0.8.4 теперь находится в полу-публичной бета-версии (однако пока недоступна на веб-сайте).

Ответ 6

Для информации JD поддерживает switch (enum), switch (string), assert assert и для каждого цикла.

О параметрах -g (javac),

  • Если вы опускаете номера строк, JD может не восстанавливать исходный поток инструкции: типы циклов могут не быть определенным, множественное привязки не могут быть восстановлены, и алгоритм, используемый для перестройки источника код не может работать.
  • если вы опустите локальные переменные данные, JD не может, когда-нибудь, определите точный диапазон переменных. Это проблематично.

Ответ 8

Хорошо, это написано на моем мобильном телефоне, так что несите меня.

В первую очередь, каждый код java файла скомпилирован в байт-коде в соответствующем файле .class. Это означает, что константы хранятся AS IS (поэтому строки могут быть легко извлечены), а переменные назначаются регистру, который затем ставится на выполнение программы стека, когда JVM обрабатывает файл класса.

Причина, по которой ваш блок исключения не возвращается к исходному коду, который вы написали, объясняется тем, как javac скомпилировал и перевел код в java-байт-код.

Если вы хотите узнать, какой декомпилятор работает лучше всего, напишите все известные Java-выражения (для цикла, if statement, while loop) с некоторыми выражениями и посмотрите, что лучше всего представляет ваш исходный код.

Удачи.

Ответ 9

Это было какое-то время, так как любая обратная связь с этой веткой. Однако, так как я нашел его и серьезно воспринял ввод, я считаю важным дать обновление.

Я использовал Java Decompiler Free с хорошим успехом. Тем не менее, в последнее время я случайно удалил довольно много кода производственного J2EE-приложения. предположил, что JD Free справится с этим, но он вообще не обрабатывает дженерики. Плюс был код, в котором он полностью обрабатывал переменную инициализацию. То, что я закончил, было полным беспорядком.

Там может быть ничего, что будет правильно работать. В моем случае это просто еще один урок в резервном копировании, резервном копировании, резервном копировании. Мне нужен декомпилятор, который правильно обрабатывает дженерики, чтобы сделать массовое восстановление. Но некоторая точность обработки переменных также поможет. Слишком много, чтобы попросить инструмент выплюнуть исходный код. Но то, что я видел до сих пор, будет компилироваться, но не будет функционировать должным образом, дженерики в стороне. Поэтому я предполагаю, что это будет долгая неделя перед Рождеством!