2010-10-09 2 views
38

Сейчас я пытаюсь найти лучший Java Decompiler, я нашел эти:Выбрать и тест Java Decompiler

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

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 Java 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 {}?

+2

Если вы на OS X, я бы также дал Jar Inspector выстрел: http://www.codeland.org/ –

+1

@Brent Nash, к сожалению Jar Inspector больше не поддерживается и не работает под OSX Snow Leopard :( –

+1

Обратите внимание, что java.decompiler.free.fr больше не будет работать, проект теперь находится на http://jd.benow.ca/ –

ответ

23

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

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

1

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

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

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

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

Удачи.

+0

Локальные переменные назначаются прямо в слот стека. – EJP

5

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

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

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

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

4

Для информации JD поддерживает переключатель (enum), switch (string), assert assert и for-each.

О -g (JAVAC) варианте,

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

Вы имеете в виду JD? Как в http://java.decompiler.free.fr/? Если это так, я не могу найти вариант -g вообще, и он не поддерживает переключатель (enum) без него. – mjaggard

5

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

7

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

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

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

0

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

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

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

+4

другой аргумент для использования источника управления ... –

Смежные вопросы