Как декомпилировать файл jar
Обновлено: 21.11.2024
Основная команда для извлечения содержимого файла JAR:
Давайте посмотрим на параметры и аргументы этой команды:
- Параметр x указывает, что вы хотите извлекать файлы из архива JAR.
- Параметры f указывают, что файл JAR, из которого должны быть извлечены файлы, указывается в командной строке, а не через стандартный ввод.
- Аргумент jar-file — это имя файла (или путь и имя файла) файла JAR, из которого нужно извлечь файлы.
- файл(ы) в архиве – необязательный аргумент, состоящий из разделенного пробелами списка файлов, которые нужно извлечь из архива. Если этот аргумент отсутствует, инструмент Jar извлечет все файлы из архива.
Как обычно, порядок, в котором параметры x и f появляются в команде, не имеет значения, но между ними не должно быть пробела. р>
При извлечении файлов инструмент Jar создает копии нужных файлов и записывает их в текущий каталог, воспроизводя структуру каталогов, которую файлы имеют в архиве. Исходный файл JAR остается без изменений.
Внимание! При извлечении файлов инструмент Jar перезапишет любые существующие файлы с тем же путем, что и у извлеченных файлов.
Пример
Предположим, вы хотите извлечь файл класса TicTacToe и файл изображения cross.jpg. Для этого вы можете использовать эту команду:
Эта команда делает две вещи:
- Он помещает копию TicTacToe.class в текущий каталог.
- Он создает каталог images, если он еще не существует, и помещает в него копию cross.jpg.
Исходный JAR-файл TicTacToe остается без изменений.
Таким же образом из JAR-файла можно извлечь сколько угодно файлов. Если в команде не указано, какие файлы нужно извлечь, инструмент Jar извлечет все файлы в архиве. Например, вы можете извлечь все файлы из архива TicTacToe с помощью этой команды:
В последние несколько дней я повеселился, пытаясь понять внутреннюю работу APK-файла. Раньше я использовал только легендарный JD-GUI в качестве декомпилятора для некоторых задач CTF. Но при работе с более сложным кодом я обнаружил, что может помочь просмотр вывода различных декомпиляторов. Поэтому я провел небольшое исследование, чтобы найти больше декомпиляторов, использующих разные подходы. Этот пост служит небольшим справочным материалом о том, как создавать и использовать эти инструменты.
Введение
Начнем с того, что общего между файлами JAR и APK. Когда создается приложение для Android, исходные коды сначала компилируются в байт-код JVM. После этого байт-код JVM компилируется в байт-код Dalvik. В то время как байт-код JVM находится в файлах .class внутри JAR, байт-код Dalvik находится в файлах .dex внутри APK.
Это означает, что для восстановления исходного кода APK-файла есть два подхода:
- либо мы находим декомпилятор, который напрямую реконструирует исходный код из байт-кода Dalvik, либо
- мы переводим байт-код Dalvik в байт-код JVM и оттуда используем обычный декомпилятор Java.
Для первого подхода подойдет jadx. Если вашей целью является файл APK, вам обязательно стоит попробовать этот инструмент. Я видел, что на него полагаются многие анализаторы APK, что, вероятно, означает, что он хорошо справляется со своей задачей.
Второй подход требует некоторого механизма для преобразования файлов .dex в файлы .class. dex2jar, несомненно, является наиболее известным инструментом для этого. Однако я наткнулся на Enjarify. Он рекламирует, чтобы работать лучше для нескольких крайних случаев:
Он [dex2jar] работает достаточно хорошо большую часть времени, но множество непонятных функций или пограничных случаев приводят к его сбою или даже молчаливому выдаче неверных результатов. В отличие от этого, Enjarify предназначен для работы в максимально возможном количестве случаев, даже для кода, в котором Dex2jar не сработает.
Enjarify выводит, как следует из названия, файл JAR. Отсюда можно использовать несколько популярных инструментов для восстановления исходного кода Java.
Подводя итог, на следующем рисунке показаны оба варианта, которые у нас есть.
Мы можем либо использовать jadx для прямой декомпиляции APK, либо использовать Enjarify, который позволяет использовать более классические декомпиляторы Java.
Декомпиляторы
Далее позвольте мне показать вам, какие декомпиляторы меня особенно интересовали, и как их установить.
Когда я впервые увидел домашнюю страницу CFR, проект быстро завоевал мою симпатию. Никакого причудливого интерфейса на основе JavaScript, только обычный HTML-сайт. Первое предложение на странице сразу бросилось в глаза:
CFR декомпилирует современные функции Java, включая большую часть Java 9, 12 и 14, но полностью написан на Java 6, поэтому будет работать везде!
Выпуски можно найти на GitHub и в других местах, хотя я не уверен, что исходный код полностью открыт. Будучи проектом Java, он удобно компилируется в один файл JAR.
Этот файл JAR можно использовать следующим образом:
Для больших JAR-файлов не хватило памяти. Вы можете просто изменить размер пула выделения памяти JVM, если это произойдет и с вами.
В этом примере можно выделить максимум 4 ГБ.
В выходном каталоге вы найдете декомпилированные файлы .java вместе со сводкой декомпиляции.
Папоротник
Следующим идет Fernflower, который является частью IntelliJ IDEA. Все упоминают, что это аналитический декомпилятор (как указано в описании их проекта), но никто не указывает, что это на самом деле означает. Я нашел только этот вопрос Stackoverflow, который, к сожалению, на сегодняшний день остается без ответа.
В любом случае, поскольку автономных релизов не существует, вам нужно собрать его самостоятельно. Как проект на основе Gradle, вы можете клонировать его, а затем выполнить следующую команду, если на вашем компьютере установлен Gradle.
Здесь мы сначала переключаем наш рабочий каталог на корневой каталог Fernflower. Затем мы указываем Gradle собрать файл ./build/libs/fernflower.jar .
Вызов Fernflower аналогичен вызову CFR.
Среди описанных здесь декомпиляторов это единственный, который выводит сгенерированные файлы .java в файл JAR. Вы можете легко извлечь исходные файлы, используя unzip .
Кракатау
Помните Enjarify сверху? Тот же автор также является разработчиком декомпилятора Krakatau.
В отличие от других проектов, этот написан на Python. И я думаю, что именно поэтому он немного отличается от других.
Затем убедитесь, что у вас есть jar-файлы, содержащие определения (sic!) для любых внешних классов (например, библиотек), на которые может ссылаться jar-файл, который вы пытаетесь декомпилировать. Сюда входят классы стандартной библиотеки (например, JRT).
И судя по описанию, эти стандартные библиотечные классы поставляются с Java версии до 8 в виде файла rt.jar . Для более поздних версий автор предоставляет jrt-extractor, который может сгенерировать для нас этот файл.
Поэтому мы скачиваем этот инструмент и запускаем следующие команды.
Это должно было записать файл rt.jar внутри каталога.
Учитывая этот файл, мы можем запустить Krakatau следующим образом.
Позвольте мне обратиться к GitHub проекта для объяснения параметров. Просто обратите внимание, что для любых библиотек, используемых вашим файлом JAR, Krakatau потребует, чтобы вы добавили его как файл JAR к флагу -path.
Процион
Последний и четвертый декомпилятор, на который я смотрел, это Procyon.
Несмотря на то, что вики проекта ссылается на файлы для загрузки на Bitbucket, на момент написания статьи доступных для загрузки нет. Вот почему я попытался скомпилировать его самостоятельно.
В проекте также используется Gradle для сборки. Итак, давайте попробуем gradle jar .
О нет! Это не компилируется гладко.
В крайнем случае я проверил, есть ли что-нибудь в репозиториях, и, к счастью, — по крайней мере, в Debian — оно упаковано и готово к использованию.
После установки пользоваться несложно.
Но подождите, если Debian упаковывает Procyon, должен быть способ его собрать.
Итак, давайте посмотрим, как они исправили исходный код, чтобы исправить это. Обсуждение в отчете об ошибке ссылается на этот коммит diff. Там мы видим, что был добавлен патч для совместимости с OpenJDK 11.
Мне пришлось подправить патч, так как основной исходный код уже расходился, но, наконец, мне удалось его собрать. Если вы хотите собрать его самостоятельно, вот файл исправления, с которым мне удалось справиться.
Сначала примените исправление, а затем вызовите Gradle для сборки проекта.
Это должно создать файл ./build/Procyon.Decompiler/libs/procyon-decompiler-1.0-SNAPSHOT.jar , который является вашим только что скомпилированным декомпилятором Procyon.
Декомпиляторы в работе
Вы можете задаться вопросом: а нет ли более простого способа? И я полагаю, что это зависит.
Инструменты с графическим интерфейсом, такие как Bytecode Viewer, также используют несколько декомпиляторов под капотом и позволяют вам просматривать их выходные данные рядом друг с другом. Но я предпочитаю использовать ручной способ, чтобы посмотреть, какие параметры я могу настроить. У вас больше контроля над запуском декомпилятора, и вы, вероятно, узнаете что-то новое.
Чтобы сделать все это более доступным, я создал образ Docker, в котором все четыре декомпилятора доступны из коробки. Посетите страницу проекта GitHub, чтобы узнать, как его использовать.
Обратите внимание, что он также включает возможность декомпиляции APK-файлов. Как обсуждалось ранее, Enjarify используется для преобразования ваших APK в JAR. Он также декомпилирует ваши файлы APK через jadx.
Заключение
Я намеренно сделал этот пост коротким и практичным. Цель состояла в том, чтобы записать мои шаги для дальнейшего использования, и я подумал, что это может быть полезно для других.
Если декомпиляция ни к чему не привела, могут пригодиться другие инструменты. Вместо того, чтобы пытаться реконструировать источник, может быть, достаточно немного скорректировать поведение вашей цели. В этом случае вам следует изучить инструментарий, предоставленный Frida and Soot.
Закрыто. Этот вопрос не соответствует правилам переполнения стека. В настоящее время ответы не принимаются.
Хотите улучшить этот вопрос? Обновите вопрос, чтобы он соответствовал теме Stack Overflow.
Закрыт 6 лет назад.
Кто-нибудь знает бесплатный декомпилятор, который может декомпилировать весь файл Jar вместо одного класса? У меня проблема с подклассами, такими как name$1.class name$2.class name.class
Помните еще две вещи: 1) Простое упоминание о декомпиляторе вызовет появление "святее, чем ты" и вынесет оценочное суждение о ваших мотивах, несмотря на то, что он понятия не имеет, что вы планируете использовать, поэтому будьте осторожны, с кем вы говорите к. 2) Причудливый JavaDecompiler даст вам отличное представление кода, хорошо выложенного и легко читаемого - отсутствуют только комментарии. Это поразительно хорошо, восстанавливая файл JAR, который давно потерял исходный код вместе с именами переменных. Конечно, мы не запутываем наши внутренние JAR-файлы.
Я столько раз останавливался на этой теме, когда мне нужно было изучить, как кто-то что-то сделал для плагина Bukkit. Этот комментарий всегда вызывает у меня улыбку. Хотел бы я голосовать за него каждый раз, когда захожу.
Это не следует закрывать, так как игровая площадка декомпилятора динамически меняется. В настоящее время лучшим, вероятно, является FernFlower. Если вы ищете простое решение, загрузите Windup и запустите его версию командной строки на вашем .jar. Он будет декомпилировать с помощью FernFlower с поддержкой до Java 8 (jad поддерживает только до Java 1.3, JavaDecompiler до Java 1.5 IIRC) с откатом к Procyon в случае сбоя FernFlower.
8 ответов 8
2009: JavaDecompiler хорошо справляется с jar: начиная с версии 0.2.5 отображаются все файлы в файлах JAR.
Похоже, что JD-Eclipse не изменился с конца 2009 года (см. Изменения).
Поэтому его интеграция с последней версией Eclipse (3.8, 4.2+) может быть проблематичной.
JD-Core активно поддерживается.
Оба являются результатом фантастической работы (пользователя SO) Эммануэля Дюпюи.
2018: Более современный вариант, упомянутый в комментариях Дэвидом Кеннеди Араужо:
Fernflower — это первый реально работающий аналитический декомпилятор для Java и, возможно, для языка программирования высокого уровня в целом.
См. также Как декомпилировать в java-файлы intellij idea для команды, работающей с последней версией IntelliJ IDEA.
С помощью декомпилятора Java вы можете открыть файл JAR и перейти в меню «Файл», «Сохранить все источники». Он сохраняет все файлы классов в java-файлы =D
Пожалуйста, помните, что он тоже делает ошибки. У меня есть класс с переменной Member, и он переместил ее в параметр функции, уничтожив эффект кода. Берегись, это тебя достанет.
Прежде всего, стоит помнить, что все архивные файлы Java ( .jar / .war / и т. д.) в основном представляют собой просто причудливые файлы .zip с несколькими добавленными манифестами и метаданными.
Во-вторых, для решения этой проблемы лично я использую несколько инструментов, которые решают эту проблему на всех уровнях:
-
+ Jadclipse во время работы в IDE для декомпиляции файлов .class, мой любимый инструмент сжатия изначально поддерживает архивы Java (опять же, см. первый абзац). , мой любимый инструмент сравнения, при правильной настройке может выполнять сравнения на лету между любым архивным файлом, включая файлы jar. Стоит попробовать.
Преимущество всего вышеперечисленного заключается в том, что мне не нужно держать какой-либо другой внешний инструмент, который загромождает мою рабочую среду. Все, что мне когда-либо понадобится из одного из этих файлов, может быть обработано внутри моей IDE или изменено с другими файлами изначально.
В этом руководстве мы обсудим декомпиляцию классов Java. Если исходный код недоступен, декомпиляция классов Java помогает отладить и понять поведение исходного кода.
Давайте рассмотрим различные доступные варианты.
2. Декомпиляция в IDE
Поскольку большая часть разработки выполняется в интегрированной среде разработки (IDE), декомпиляция также должна выполняться в IDE.
Для получения дополнительной информации об интегрированных средах разработки, с которыми мы будем работать, ознакомьтесь с нашими статьями об отладке в Eclipse и настройке IntelliJ IDEA.
2.1. затмение
Во-первых, в Eclipse нам нужен подключаемый модуль, такой как Enhanced Class Decompiler (ECD). Этот плагин использует пять различных декомпиляторов. Мы можем установить его из Eclipse Marketplace, а затем нам нужно перезапустить Eclipse.
Далее, ECD требует небольшой настройки, чтобы связать файлы классов со средством просмотра декомпилятора классов:
Кроме того, нам нужно связать файлы «.class без исходного кода»:
Наконец, мы можем использовать декомпилятор, нажав Ctrl+щелчок левой кнопкой мыши на имени класса. Мы видим используемый декомпилятор на вкладке файла в скобках.
В этом примере мы используем FernFlower:
2.2. ИДЕЯ IntelliJ
В отличие от Eclipse, IntelliJ IDEA по умолчанию предоставляет декомпилятор FernFlower.
Чтобы использовать его, просто нажмите Ctrl+щелчок левой кнопкой мыши на имени класса и просмотрите код:
Кроме того, мы можем скачать исходный код. Скачав исходный код, вы получите актуальный код и комментарии.
Например, класс аннотаций Component на снимке экрана выше включает Javadoc по использованию Component. Мы можем заметить разницу:
Несмотря на то, что декомпиляция очень полезна, она не всегда дает полную картину. Полный исходный код дает нам полную картину.
3. Декомпиляция командной строки
До появления подключаемых модулей IDE для декомпиляции классов использовалась командная строка. Декомпиляторы командной строки также могут быть полезны для отладки байт-кода Java на удаленном сервере, который недоступен через IDE или графический интерфейс.
Например, мы можем декомпилировать JDCommandLine с помощью простой команды jar:
Не упускайте параметр ./classes. Он определяет выходной каталог.
После успешной декомпиляции мы можем получить доступ к исходным файлам, содержащимся в выходном каталоге. Теперь их можно просмотреть в текстовом редакторе, таком как Vim.
4. Заключение
Мы рассмотрели декомпиляцию в средах разработки Eclipse и IntelliJ IDEA, а также параметры командной строки, когда они недоступны.
Мы также рассмотрели разницу между связыванием исходного кода и декомпиляцией.
Возможность декомпилировать файл класса Java очень полезна для любого разработчика Java, который хочет изучить исходный код любой библиотеки с открытым исходным кодом или частной библиотеки, используемой в проекте. Хотя я всегда предпочитаю прикреплять исходники в Eclipse для большинства распространенных библиотек, таких как JDK, это не всегда возможно с увеличением числа зависимостей. Декомпилятор Java (программа, которая может декомпилировать файлы классов Java для создания исходных файлов) очень полезен в такой ситуации. Используя декомпилятор Java, вы можете легко проверить исходный код любого файла .class. Благодаря Eclipse IDE и растущему количеству бесплатных подключаемых модулей, доступных для разработчиков Java, вы можете иметь в своем арсенале мощную декомпиляцию Java.
Раньше я использовал JadEclipse, плагин Eclipse, который хорошо работает с декомпилятором JAD, но зная, что декомпилятор JAD не поддерживает исходный код Java 1.5, я искал другой подходящий и полезный плагин Eclipse, который может декомпилировать . файл класса.
Мой поиск заканчивается на JD-Eclipse , это еще один бесплатный плагин Eclipse для некоммерческого и личного использования, который помогает вам получить исходный код из файлов классов. JD-Eclipse легко установить, и на его сайте есть подробное пошаговое руководство по установке подключаемого модуля JD-Eclipse. Если вы уже знакомы с установкой плагина Eclipse, то это несложно.
Как декомпилировать файл класса в Eclipse IDE
После установки и запуска JD-Eclipse вам, вероятно, потребуется перезапустить Eclipse после установки подключаемого модуля. Вы готовы декомпилировать файл класса Java из Eclipse. Чтобы декомпилировать файл класса, просто откройте любой из ваших проектов Java и перейдите к зависимостям библиотек Maven, чтобы увидеть файлы jar, включенные в ваш проект.
Просто разверните любой jar-файл, для которого у вас нет исходного кода в Eclipse, и щелкните файл .class. Теперь вы можете увидеть исходный код этого файла в редакторе Java, просто и элегантно, не правда ли.
Хотя я настоятельно рекомендую прикрепить исходный код для JAR в Eclipse, по крайней мере, для часто используемых библиотек, таких как JDK или Spring, поскольку качество декомпилированного кода и исходного кода различается. Исходный код обеспечивает лучшую видимость, а также показывает комментарии, в то время как декомпилированный код представляет собой лишь минимальную версию.
Как декомпилировать файл класса в Java – пример команды javap
Даже с мощной IDE Eclipse и подключаемым модулем нам иногда может понадобиться работать с командной строкой, особенно при работе на серверах разработки Linux, и неудобно переключаться туда и обратно для быстрого просмотра файла .class или получения некоторой информации из скомпилированного форма источника.
Благодаря команде javap вы можете декомпилировать файл класса на лету в командной строке. javap — это стандартный двоичный файл, который поставляется с установкой JDK и находится в каталоге JAVA_HOME/bin. javap похож на javac (компилятор java) и работает напрямую с файлом .class.
Чтобы использовать команду javap, вы должны иметь JAVA_HOME в системном пути. вы можете проверить это, набрав « javap » в командной строке, и если он не жалуется и вместо этого показывает какой-то вывод, как показано ниже, тогда все готово. Если он не распознает команду, значит, вам нужно установить путь, проверьте, как установить путь в Java, более подробные шаги.
Теперь посмотрим, что нам предлагает команда javap. У нас есть простой класс Java с одним полем и одним методом.
abc@localhost:~/java cat Hello.java
public class Hello <
private String version= "1.2" ;
public static void main ( String args []) <
System. вне . println("Бегу привет");
>
>
abc@localhost:~/java javap Hello
Собран из "Hello.java"
открытый класс Hello расширяет java. lang .Object <
public Hello () ;
public static void main ( java. lang .String []);
>
Похоже, что javap предоставляет только информацию, связанную с методом в файле .class. В нем также указывается конструктор, даже конструктор по умолчанию, добавленный компилятором Java. javap может предоставить больше информации в зависимости от его параметра командной строки, например, - private покажет все частные члены. вот пример запуска команды javap с параметром -private:
abc@localhost:~/java javap — private Hello
Собран из "Hello.java"
общедоступный класс Hello расширяет java. lang .Object <
private java. язык .String версия ;
публичный привет () ;
public static void main ( java. lang .String []);
>
Как посмотреть байт-код из файла .class
Команда javap также может отображать байт-коды из скомпилированных файлов классов. Просто запустите javap с параметром -c, и он напечатает байт-коды файла класса, как показано в примере ниже:
Это все о том, как декомпилировать файлы классов в Java и Eclipse IDE. JD-Eclipse — это простой в использовании подключаемый модуль eclipse, в котором подробно описаны шаги установки. если вы используете JDK ниже, чем Java 5, вы все равно можете использовать известный декомпилятор JAD и подключаемый модуль JADEclipse. Помимо этого есть еще много чего, что я не пробовал. Просто зайдите на рынок Eclipse, и вы увидите много таких.
Читайте также: