Stiver (stiver_rus) wrote in ru_java,
Stiver
stiver_rus
ru_java

Categories:

Аналитический декомпилятор Fernflower

Как было обещано некоторое время назад, официально объявляю о начале открытого бета теста моего декомпилятора. Ниже следует краткое описание и ответы на основные вопросы:


1) О чем вообще речь?

Fernflower - первый аналитический декомпилятор байткода Явы. Вернее первый рабочий, если принимать во внимание такие неудавшиеся попытки, как Krakatoa (University of Arizona) и Dava (Sable Research Group). Термин "аналитический" означает в данном случае, что инструмент работает с абстрактным представлением кода и не зависит например от физической последовательности инструкций в файле. Все преобразования выполняются для наиболее общего случая, любые проблемы я пытался решить прежде всего алгоритмическим путем. Этот принцип выгодно отличает Fernflower от всех остальных известных сейчас декомпиляторов, которые применяют обыкновенный, более или менее разветвленный, pattern matching на байткоде.

2) Технические характеристики

Инструмент написан на Яве и имеет объем примерно 20 KLOC. Из них около 10 KLOC собственно ядро, остальное служит в основном приведению результата в читабельный вид. Код оптимировался пока главным образом с точки зрения логики, скорость и расход памяти в расчет особенно не принимались. Тем не менее результат вполне приличный, например на Inspiron 9400 (CoreDuo 1,83 GHz):

- rt.jar из 1.4.2_03 (9000 классов): 15 минут
- y.jar из yWorks (2000 классов, обработан yGuard): 8 минут
- rapc.jar из компилятора BlackBerry (250 классов, обработан RetroGuard): 1,5 минуты

150 MB heap space хватает во всех трех случаях. Управление с консоли, никакого GUI нет и пока не планируется, за исключением, возможно, плагина к Eclipse для внутреннего пользования.

3) Качество декомпиляции

Уже сейчас на голову выше всех аналогов. Достаточно сказать, что после рекомпиляции rt.jar (1.4.2_03) Eclipse показывает всего сотню с небольшим ошибок, три четверти которых имеют причиной или баги и экзотические "фичи" Sun'овского компилятора, под которые я пока не считаю нужным подстраиваться, или отсутствие комплексной декомпиляции (см. http://stiver-rus.livejournal.com/9139.html). Остальные ошибки я потихоньку исправляю, перерабатывая попутно алгоритмы. Например могут возникнуть проблемы с определением локальных final переменных из-за неправильного порядка действий - я сначала свожу переменные вместе, а потом сажаю final, когда надо наоборот. Тестируйте, смотрите, замеченные неполадки сообщайте.

Специальных функций деобфускации Fernflower сейчас не содержит, они будут подключаться в дальнейшем отдельными модулями. Но некоторые вещи успешно декомпилируются и так за счет аналитического подхода - например вся линейка *Guard (RetroGuard, yGuard, ProGuard..), если я правильно понимаю. Не хватает еще модуля переименования, который стоит первым в очереди на подсоединение.

Добавлю кстати, что если файл или отдельный метод не декомпилируются, то это еще не обязательно означает ошибку Fernflower. Например Eclipse 3.1 содержит такие замечательные баги, что декомпиляция finally после него зачастую невозможна в принципе, так как генерируемый код просто неверен. Кто не верит, выполните в 3.1 следующий пример:
int a = 0;
try {
  if(true) {return;}
} catch (Throwable ex) {
  System.out.println("1");
} finally {
  System.out.println(2 / a++);
  System.out.println("3");
}
и порадуйтесь результату. То же самое относится в целом к Яве версии 1.0 - верификатор находился тогда в зачаточном состоянии и пропускал без возражений грубейшие ошибки. Поэтому если позволяют знания и квалификация, желательно поискать сначала возможную причину в байткоде.

4) Доступ онлайн

Fernflower доступен всем желающим в онлайне по адресу

http://www.reversed-java.com

Хостинг достаточно недорогой и слабый, и границ его выносливости я не знаю. Emmanuel (автор JD GUI) прогнал неделю назад на нем свои тесты и несколько раз вызвал OutOfMemory, причины которых я сейчас изучаю. Пока установил с потолка ограничение на два треда, 5 MB и 7 минут рабочего времени. Если не будет хватать, перейдем на вариант помощнее, но при условии действительной востребованности. Страница тоже довольно сырая еще (первый мой опыт с Wicket), в частности у меня пока руки не дошли сочинить тексты описания и прочее словоблудие (тем более в трех экземплярах). Если какие-то опции непонятны, просто спрашивайте.

5) Версия для скачивания

Локальной версии нет и в ближайшем будущем скорее всего не появится. Ну все, теперь, чувствую, полетят сапоги :)) Попробую объясниться. Дело тут вовсе не в моей жадности или нежелании делиться какими-то тайнами. В алгоритмах ничего сверхсекретного нет - большинство я уже обсуждал у себя в журнале или на васме без особого отклика. Сперва я планировал выложить код целиком под GPL, но месяц назад сел, поразмыслил и решил пока воздержаться. Причины следующие (в порядке убывания значимости):

a) В дальнейшем Fernflower будет развиваться в сторону деобфускатора (что в общем-то и было моей изначальной целью, да вот пришлось отвлечься по дороге). Часть функций встроена уже сейчас в ядро, остальные будут подключаться по мере написания. Но обфускация - это уже рынок, где существует несколько фирм, неплохо зарабатывающих на продаже своей продукции. То есть в любом случае грозит что-то вроде гонки вооружений. А поскольку я: 1) единственный автор проекта 2) занимаюсь им в свободное от всего остального время, то просто не в состоянии тягаться в открытую с десятком программистов на полный рабочий день.

b) Как любой консольный инструмент Fernflower не слишком интуитивен для привыкших к окошкам. Я собираюсь поддерживать его, исправлять ошибки и отвечать на вопросы, но вовсе не желаю разгребать запросы в духе "а где взять Java?", "а как ее установить?", "а почему ничего не запускается?", "а почему он классы не находит?" и так далее. На вебстранице значительно меньше возможностей приложить кривые руки: закачал файл, скачал код.

c) Наверняка будут всплывать еще ошибки и баги в значительном количестве, особенно поначалу. Хочу иметь возможность часто обновлять текущую версию, не заставляя при этом людей скачивать каждые два дня новый файл. Кроме того значительно удобнее тестировать одну эталонную версию онлайн, чем разводить зоопарк локальных версий.

Помимо этих, есть еще трудности формального свойства:

- для открытия кода мне нужно официальное согласие моего работодателя. Вряд ли кто-то будет сильно против, но все равно это отдельный бюрократический процесс, которым надо заниматься
- перед открытием код надо чистить, причесывать, приводить в должный вид комментарии.. нет у меня ни времени, ни сил сейчас. Вывели мы недавно уже один продукт в open source, так рутинной работы оказалось на порядок-полтора больше, чем прикидывали. Пока не горю желанием повторять опыт.

6) Информация и данные пользователей

Ни загруженные файлы *.class, ни результаты декомпиляции я не сохраняю. Никаких логов также не веду, за исключение стандартного лога Tomcat, информация из которого используется только в целях общей анонимной статистики для личного пользования. Файлы автоматически удаляются примерно через полчаса, чтобы дать время скачать их. Поэтому если где-то происходит ошибка, самостоятельно я ее скорее всего не смогу воспроизвести - нужно выслать мне тестовые классы явным образом.

Хотя если народ выскажется за, то могу и сохранять файлы. Тогда ошибки будут исправляться значительно быстрее. Или можно сделать опцию..

7) Дальнейшее развитие

Как уже упоминалось, кроме непосредственных доработок и исправлений Fernflower будет развиваться в сторону деобфускатора. Конечная цель - успешная декомпиляция со снятием всех коммерческих обфускаторов. Кроме того постараюсь продвигать теорию по мере возможности, но это уже другая, совсем особая тема.


8) Выводы и манифест

Со своей стороны могу гарантировать - с поправкой на force majeure - следующее:

a) Декомпилятор всегда будет в бесплатном доступе
b) Буду поддерживать, исправлять баги и развивать Fernflower по мере сил
c) Если в какой-то момент я пойму, что больше не могу уделять проекту необходимое количество времени, то сразу открою его под GPL-подобной лицензией независимо ни от каких внешних обстоятельств

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

9) Связь

Со мной можно связаться:

- через www.reversed-java.com
- через журнал
- через fernflower (dot) decompiler (at) gmail (dot) com

Как кому удобнее.

Update: нет, так мы каши не сварим. Временно включил сохранение классов. Иначе вопросы идут, а слать тестовый материал никто не собирается и гадай как знаешь.
Tags: decompiler
Subscribe

  • Декомпилятор JAVA

    Доброго времени суток всем, Столкнулся с задачей, когда нужно разобрать исходный код уже готового откомпилинного swing приложения. Порыскал в…

  • decompilation

    Добрый день! На работе необходимо освоить библиотеки rhino, и наткнулся я в мануале на такой текст. Опция к компилятору javascript файлов (*.js…

  • Переименование обфусцированных элементов

    Как известно, обфускаторы переименовывают классы, поля и методы. Причем выбирают имена таким образом, чтобы они были 1) как можно короче (или…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 58 comments

  • Декомпилятор JAVA

    Доброго времени суток всем, Столкнулся с задачей, когда нужно разобрать исходный код уже готового откомпилинного swing приложения. Порыскал в…

  • decompilation

    Добрый день! На работе необходимо освоить библиотеки rhino, и наткнулся я в мануале на такой текст. Опция к компилятору javascript файлов (*.js…

  • Переименование обфусцированных элементов

    Как известно, обфускаторы переименовывают классы, поля и методы. Причем выбирают имена таким образом, чтобы они были 1) как можно короче (или…