Декомпиляция Java приложений

    Декомпиляция — процесс воссоздания исходного кода декомпилятором
    Недавно я задался вопросом: Какой декомпилятор лучше?
    Начал мучить Google, экспериментировать. В итоге нашел отличное решение. Как декомпильнуть любую программу и получить рабочие «исходники»? Об этом в сабже.

    Краткий обзор популярных декомпиляторов


    Mocha

    Mocha (автор — Hanpeter van Vliet)— это, вероятно, один из первых выпущенных декомпиляторов Java. Предоставляет консольный пользовательский интерфейс. Его релиз состоялся в 1996-ом году, ещё до того, как появился Java Development Kit версии 1.1

    JAva Decompiler

    JAva Decompiler, JAD (автор — Pavel Kouznetsov) — по всей видимости, самый
    популярный декомпилятор Java. Как и Mocha, этот декомпилятор предоставляет консольный интерфейс, давно не обновляется и не поддерживается, но большое число графических инструментов для работы с ним, в том числе плагин JadClipse для среды разработки Eclipse, делают его и по сей день используемым в качестве подручного средства для декомпиляции небольших классов.
    Помимо декомпиляции, JAva Decompiler обладает возможностью дизассемблирования .class-файлов.

    DJ Java Decompiler

    DJ Java Decompiler (автор — Atanas Neshkov) — долгое время вопреки названию являлся лишь графической оболочкой для предыдущего декомпилятора, позволявшей легко и удобно выбрать аргументы командной строки для вызова JAD. В текущей версии добавлена поддержка аннотаций, но декомпилятор стал условно-бесплатным (необходима покупка после 10 пробных использований).

    JD-Core

    JD-Core (автор — Emmanuel Dupuy) — очень мощная и функциональная библиотека для декомпиляции и анализа байткода Java, разработанная в рамках «Java Decompiler project».
    Имеет следующие особенности:
    • Полностью написана на языке C++, что делает декомпиляцию необычайно быстрой
    • Не требует для работы Java Runtime Environment и поэтому не требует специальной установки
    • Корректно декомпилирует .class-файлы, сгенерированные большинством компиляторов
    Пожалуй, к недостаткам JD-Core можно отнести лишь то, что она распространяется как
    часть самостоятельного графического приложения JD-GUI, также разработанного на C++ и прилинкованного к ней статически, или плагина JD-Eclipse для среды разработки Eclipse, что делает практически невозможным её использование в стороннем некоммерческом проекте, особенно разработанном на языке Java. Использование библиотеки в коммерческих программных продуктах запрещено автором.

    Fernflower

    Fernflower — один из лучших декомпиляторов языка программирования Java на сегодняшний день.
    Обладает следующими возможностями:
    1. Поддерживает разнообразные языковые конструкции:
    • Параметрические типы
    • Аннотации
    • Перечислимые типы
    • Утверждения
    2. Корректно декомпилирует байткод, сгенерированный вследствие некоторых известных багов компиляторов

    Мой выбор


    1. JD-GUI — для просмотра, не более
    2. Fernflower — полное восстановление

    Остановлюсь на втором. Вообще, автор данного декомпилятора вроде как не выкладывал оффлайн версию в общий доступ(или я упустил этот факт читая его блог), до последнего времени была только онлайн. Но для меня было приятным удивлением найти ее на одном форуме!

    Скачать: fernflower.jar

    Цитата из блога автора:
    Fernflower будет развиваться в сторону деобфускатора

    Специальных функций деобфускации Fernflower сейчас не содержит, они будут подключаться в дальнейшем отдельными модулями
    Т.к. онлайн версия по неизвестным причинам не работает, а про оффлайн трудно что-либо сказать(кроме того, что качество декомпиляции отменное), не о каких модулях на данный момент речи быть не может.
    Не хватает еще модуля переименования
    Это да. Поищем что-то такое в интернетах.
    На выручку придет Proguard, но необыкновенный
    ProGuardDeobfuscator — небольшая модификация программы ProGuard, превращающая ее в квази-деобфускатор. В процессе обработки короткие обфусцированные имена пакетов, классов, полей и методов заменяются на более осмысленные и уникальные в пределах Jar файла.
    Скачать исходники и сам деобфускатор: projectd8.org/Programs/Java/PGD

    Инструменты все есть, но лично я, для облегчения воссоздания сорцов использую так же любимую Netbeans IDE — очень сильно помогает своими подсказками, особенно когда классов много.
    Спасибо за внимание!

    Ссылки

    se.math.spbu.ru/SE/YearlyProjects/2011/YearlyProjects/2011/345/345_Mikhailov_report.pdf
    ru-java.livejournal.com

    UPD:
    Извиняюсь, в offline версии Fernflower присутствует модуль переименований и уйма других штук — Readme
    Поделиться публикацией

    Комментарии 35

      +1
      Я ещё использую плагин для TotalCmd, чтобы быстро посмотреть class налету: TC Jad
      Про плагин JD-Eclipse можно добавить, что ему иногда требуется realignment во время отладки. Так как не всегда строки полученных сырцов совпадают с позицией курсора. Если интересно, можно посмотреть тут. Или погуглить по другим веткам.
        0
        К сожалению, пока, на чем то одном врядли можно остановится. Одни куски хорошо декомпилируются в jd-gui, другие в fernflower. Иногда нужно использовать 2, а то и 3 разных декомпилятора, что бы получить вменяемый код.
          0
          Декомпилировать — это не интересно, а вот дебажить без сырцов — да :)
          +1
          Кто то вообще в курсе, что происходит с fernflower? Сайт не работает, ни откуда официально скачать нельзя, только по закромам.
          Или видимо автор ушел в платную версию с проектом AndroChef?
            0
            А все, это разные авторы. AndroChef и DJ Java Decompiler — Atanas Neshkov
            Но вопрос про fernflower тот же, где он? :)
              +2
              На сайт у меня сейчас времени нет, к сожалению :( Он как-то повадился падать, и после очередного падения не поднял. Тем более, что на нем версия 0.6 была, а с тех пор многое добавилось.

              Скачать официально см. ниже, MCP например. Атанас использует Fernflower с моего ведома и разрешения.
                +1
                Извиняюсь за «некрофилию», но, как мне кажется, именно здесь самое подходящее место для следующего вопроса:

                Когда вы только выпускали Fernflower «в свет», вы сказали следующее: «Если в какой-то момент я пойму, что больше не могу уделять проекту необходимое количество времени, то сразу открою его под GPL-подобной лицензией независимо ни от каких внешних обстоятельств». Насколько я понимаю, обновлений самого декомпилятора не было уже очень долгое время, сайт не работает (и даже домен уже увели). Можно уточнить, какие на настоящее время ваши планы относительно раскрытия проекта под свободной лицензией? (Причём я уверен, что абсолютное большинство заинтересованных будут рады раскрытию в _любом_ виде, даже без «причёсывания»).
                  +2
                  Не хочу пока давать подробности, чтобы не сглазить. Но могу сказать, что сейчас идет обновление на Java 7 / 8 и подготовка открытия кода под одной из свободных лицензий. Надеюсь, все получится как запланировано :)
                    +1
                    Задержали дыхание и ждём ;-)
                      0
                      А на какой стадии сейчас находится этот процесс?
              0
              Для галочки можно еще назвать soot, правда выдает в большинстве случаев какую то какашку, но так или иначе, как еще один взгляд на декомпиляцию подойдет.
                +20
                >> Но вопрос про fernflower тот же, где он? :)

                Здесь он. В смысле я — автор Fernflower :)

                Последняя offline версия используется например в MCP (http://mcp.ocean-labs.de/index.php/MCP_Releases), оттуда же ее можно скачать. Модуль переименований в ней должен быть.
                  0
                  а где можно найти список поддерживаемых опций?
                  (что, например, такое -dgs=true? и какие есть другие?)

                  а также хотелось бы возможность вывода результата декомпиляции (одного класса) в STDOUT.

                  Спасибо.
                    0
                    de.fernflower.main.extern.IFernflowerPreferences
                    В этом классе описаны константы опций.
                      0
                      По идее — если из того же MCP качать — то к jar'у прилагается еще и readme файл (а также файл с лицензией, ага).

                      Кому качать лень, он тут отдельно: pastebin.com/bh83nHL5

                      >>а также хотелось бы возможность вывода результата декомпиляции (одного класса) в STDOUT.

                      Такого действительно пока нет, возьму в список хотелок.
                        0
                        Можно еще попросить опцию, чтобы номера строк вставлялись в файл аутпута? удобно при дебаге — валится с ошибкой в строке номер такая-то. Декомпилировал — и сразу ага, вот строка.

                        Спасибо!
                          0
                          Спасибо.
                          Я ведь правильно понимаю, что с конца 2010-го в проекте не было никаких изменений?
                          (дата классов в jar'е — 2010-12-28)
                            0
                            С опцией -ren переименованию подвергаются так же и конструкторы классов.
                            Исправьте, пожалуйста, в следующих версиях
                          0
                          Кстати, оказалось, что в посте как-раз последняя версия fernflower :)
                          Как пользоваться модулем переименований?
                          0
                          JD-GUI уж очень падуч и современные конструкции плохо распознаёт, но несложные алгоритмы им вполне можно раскалывать.
                            +1
                            Я яву декомпилировал для изучения кода под Android. Качество работы утилит настолько неприемлемо, что оказалось проще изучить smali.
                              0
                              Поддерживаю. Smali читать достаточно легко, модифицировать — приемлимо. Вот еще бы ide под него ;)
                              +1
                              Относительно недавно появился android-decompiler (jeb). Кто то вкурсе что там за ява декомпилятор? По картинкам и тому как распознает очень похож на FernFlower, но возможно там что то свое.

                              Стоит почему то очень дорого ($1000 за лицензию), триалки или чего то подобного нету. Видимо расчитано на профессиональных реверсеров. Хотя суть все та же: dex2jar + FernFlower/jd-gui + smali.
                                0
                                В jeb свой декомпилятор. И не java, а сразу dalvik байткода. Нет смысла обратно конвертировать обратно в java байткод, когда после конвертации многие конструкции не будут выглядеть как раньше (можно представить себе promt англ-рус-англ). Уж лучше брать парсить dex (благо libdex есть) и строить java из него, т.е. суть у него другая.
                                  0
                                  А, все оказывается написано на офф сайт :) Но он почему то лежал во время написания комента, сейчас уже подняли.
                                0
                                  0
                                  JD-GUI определенно лучший. Бесплатный, поддерживает аннотации, дженерики, енамы и т.п., багтрекер на официальном сайте.

                                  JAD умер тогда, когда появилась Java5, ибо ни дженериков ни аннотаций не поддерживает.

                                  С Fernflower непонятная ситуация — официальный сайт лежит, вы здесь какой-то JAR выложили, но где гарантия что это не вирус? Надо декомпильнуть и разгрести с помощью JD-GUI чтоб убедится? (-:
                                  Плюс по слухам он не может декомпилировать например такой код — pastebin.com/f0aE6Jh0 — тогда как JD-GUI это делает легко.
                                  0
                                  > JAva Decompiler обладает возможностью дизассемблирования .class-файлов.
                                  Это как? чем оно отличается от декомпиляции?
                                    0
                                    Отличается тем, что при декомпиляции мы получаем привычный нам код, а при дизассемблировании — в виде набора команд JVM
                                    0
                                    JD-Eclipse вещь капризная, по моему опыту требует VCRT, которая входит в состав какой-то версии .NET, и не работает в 64-разрядном Eclipse.
                                      +1
                                      Есть ещё Jasper — не декомпилятор, а дизассемблер, который разбирает .class в формат джавовского ассемблера Jasmin. Код, конечно, получается чуть менее удобочитаемым, но зато работает эта штука, вроде, в 100% случаев и для небольших изменений софта очень даже годится.
                                        +1
                                        Ну это уже отдельный разговор :)
                                        К дизассемблерам совместимым с Jasmin могу отнести также D-Java и ClassFileAnalyzer
                                        0
                                        Для тех, кто в будущем найдет этот пост: для меня fernflower в своем исходном виде оказался неюзабелен совершенно (слишком много классов не разбирает вообще, выпадая с NPE), зато вот с этим патчем отработал просто на «ура».
                                        Автору плюс в карму (не только на хабре, но и вообще) и пожелания вернуть своему детищу хотя бы просто страничку, где его можно скачать.

                                        Сюда же добавлю багрепорт, вдруг автор прочитает :) У меня самая частая ошибка в получаемых исходниках: fernflower ставит модификатор final у переменных, используемых в безымянных классах даже тогда, когда вне этих классов переменная меняется. JAD в этих случаях перед сразу определением безымянного класса создает отдельную final-переменную, равную исходной в данный момент.

                                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                        Самое читаемое