Однажды после работы я провел дома телефонное интервью и задал собеседнику вопрос: «Знаете ли вы какой-нибудь способ декомпилировать код Java?». Но интервьюируемый не ответил хорошо, поэтому я написал в оценке интервью: «У меня нет полного понимания знаний, связанных с принципом компиляции». В это время подруга увидела это предложение.
Компьютерный язык относится к языку, используемому для общения между людьми и компьютерами. Компьютерный язык является средством передачи информации между людьми и компьютерами.
Самой большой характеристикой компьютерной системы является то, что инструкции передаются машине через язык. Для того чтобы заставить ЭВМ выполнять различные задачи, необходимо иметь набор чисел, символов и грамматических планов для написания компьютерных программ, которые образуют различные инструкции (или различные утверждения) ЭВМ. Это языки, которые могут принимать компьютеры.
Компьютерные языки включают машинный язык, язык ассемблера и язык высокого уровня.
машинный язык
Машинный язык — это набор машинных инструкций, которые могут быть непосредственно распознаны и выполнены компьютером, представленным двоичным кодом. Машинный язык гибок, прост в исполнении и быстр. Однако разные типы компьютеров имеют разные машинные языки, и программы, составленные в соответствии с машинными инструкциями одного компьютера, не могут выполняться на другом компьютере.
Поскольку машинный язык представлен в двоичном виде, все скомпилированные программы представляют собой коды инструкций, состоящие из нулей и единиц.
Преимущество машинного языка состоит в том, что он может быть непосредственно распознан и выполнен компьютером, что более эффективно, но он также имеет много недостатков, таких как:
1. Машина знает только 0 и 1. Программистам трудно запомнить, что такое комбинация 0 и 1 для каждой инструкции.Приходится проверять большое количество таблиц, чтобы определить, что означает каждое число.
2. Поскольку его письменная форма представляет собой сплошной «парольный» код, он имеет плохую читаемость и неудобен для общения и сотрудничества.
3. Поскольку это сильно зависит от конкретного компьютера, у него плохая переносимость и возможность повторного использования.
Поскольку у машинного языка так много недостатков, существует язык ассемблера.
язык ассемблера
Язык ассемблера использует мнемонику (мнемонику) для замены и представления некоторых низкоуровневых операций машинного языка.
Мнемоника — это легко запоминающийся символ, который может описывать функцию инструкции и операнд инструкции Мнемоника — это английское слово или его аббревиатура, обозначающая функцию инструкции. Например, ADD означает сложение, MOV означает перенос, SUB означает вычитание и т. д.
Однако язык ассемблера лишь облегчает пользователям, то есть программистам, его запоминание и использование.Компьютеры не знают языка ассемблера.Поэтому, если вы хотите, чтобы компьютер выполнял ассемблерный код, вам нужно сначала преобразовать ассемблерную программу в исполняемый файл, код языка. Этот процесс называется процессом сборки.
Поскольку ассемблер ближе к машинному языку и может напрямую работать с оборудованием, сгенерированные программы имеют более высокую скорость работы и меньшее потребление памяти, чем другие языки. большое количество приложений в промышленном управлении.
Машинный язык и язык ассемблера, оба из которых мало или вообще не имеют грамматической абстракции, мы обычно называем этот язык низкоуровневым языком, который ближе к аппаратному обеспечению и не может быть перенесен между другим оборудованием.
Но по мере того, как современные программные системы становятся все более и более сложными, в соответствии с требованиями времени также появляется большое количество инкапсулированных языков высокого уровня, таких как C/C++, Pascal/Object Pascal. Эти новые языки делают процесс разработки более простым и эффективным для программистов, позволяя разработчикам программного обеспечения справляться с требованиями быстрой разработки программного обеспечения.
язык высокого уровня
Языки высокого уровня — это языки программирования с высокой степенью инкапсуляции, в отличие от языков низкого уровня.
Это язык программирования, основанный на повседневном человеческом языке.Он представлен словами, которые легко воспринимаются обычными людьми (такими как китайские иероглифы, неправильный английский или другие иностранные языки), что облегчает программистам написание и имеет более высокий возможность написания Читаемость, чтобы люди с меньшим знанием компьютеров могли примерно понять его содержание.
Такие как популярные java, c, c++, c#, pascal, python, lisp, prolog, FoxPro, easy language, китайская версия языка изучения языка C и т. д., синтаксис и формат команд этих языков отличаются.
Как и язык ассемблера, языки высокого уровня находятся дальше от машинных языков, и компьютеры не могут напрямую распознавать языки высокого уровня. Итак, чтобы компьютер мог выполнять язык высокого уровня, его необходимо преобразовать в машинный язык.
1. Язык высокого уровня близок к языку алгоритмов, прост в изучении и освоении, а общему инженерно-техническому персоналу требуется всего несколько недель обучения, чтобы быть компетентным для работы программистов;
2. Язык высокого уровня предоставляет программистам структурированную среду программирования и инструменты, делая разработанные программы читабельными, удобными в сопровождении и надежными;
3. Язык высокого уровня далек от машинного языка и имеет мало общего с конкретным аппаратным обеспечением компьютера, поэтому написанная программа имеет хорошую переносимость и высокую степень повторного использования;
4. Так как сложные и тривиальные дела передаются компилятору, степень автоматизации высокая, цикл разработки короткий, а программисты разгружаются, и они могут сосредоточить свое время и силы на творческой работе, которая важнее для них. их.Улучшить качество программы.
Есть два языка, упомянутых выше, язык низкого уровня и язык высокого уровня. Упрощенно это можно понять так: язык низкого уровня — это язык, распознаваемый компьютером, а язык высокого уровня — это язык, распознаваемый программистом.
Итак, как преобразовать язык высокого уровня, написанный программистом, в язык низкого уровня, понятный компьютеру, а затем позволить компьютеру выполнить его?
Этот процесс на самом деле компилируется!
Основной целью компиляции является перевод программ с исходным кодом, написанных на языках высокого уровня, которые людям легко писать, читать и поддерживать, в программы на языках низкого уровня, которые компьютеры могут интерпретировать и запускать, то есть , исполняемые файлы.
Как язык высокого уровня, язык Java должен быть преобразован в машинный язык посредством компиляции, если он хочет быть выполнен.
Исходный файл языка Java представляет собой файл Java. Чтобы преобразовать файл Java в двоичный файл, требуется два шага.
Затем, после внутреннего компилятора, файл байт-кода класса компилируется в машинный язык.
Интерфейсные компиляторы Java — это в основном javac, инкрементальный компилятор ECJ в Eclipse JDT и т. д.
Внутренние компиляторы Java в основном реализуются основными виртуальными машинами, такими как JIT-компилятор в HotSpot.
Как упоминалось ранее, мы можем скомпилировать исходный код языка высокого уровня в язык низкого уровня с помощью компилятора, и наоборот, мы также можем выполнить обратное проектирование исходного кода с помощью языка низкого уровня. Этот процесс называется декомпиляцией.
Хотя нам трудно декомпилировать машинный язык в исходный код, мы все же можем декомпилировать промежуточный код. Точно так же, хотя мы не можем декомпилировать машинный язык, скомпилированный виртуальной машиной, мы все же можем декомпилировать класс, скомпилированный javac.
Поэтому мы говорим, что декомпиляция Java обычно преобразует файлы классов в файлы java.
Во-первых, декомпиляция — отличный способ изучить Java.
Потому что Java, как язык программирования, предоставляет много синтаксического сахара, такого как дженерики, автоматическая упаковка и распаковка и т. д., и эти синтаксические сахара не распознаются виртуальной машиной Java, поэтому при компиляции javac он будет несладким. . , а полученный файл класса представляет собой дешугаризированный код. В это время мы декомпилируем дешугаризированный файл класса, чтобы получить java-файл. Из этого java-файла мы можем узнать, как именно реализованы эти синтаксические сахара.
Во-вторых, с помощью инструментов декомпиляции мы можем декомпилировать чужой код, а затем узнать, как реализован чужой код. Или вы можете найти ошибки через исходный код, сделать плагины и т. д.
В Java есть много инструментов для декомпиляции, вот некоторые из них.
javap
javap — это инструмент, поставляемый с jdk, который может декомпилировать код и просматривать байт-код, сгенерированный компилятором java. Файлы, созданные javap, являются не файлами java, а файлами байт-кода класса, понятными программистам.
jad
Jad — относительно хороший инструмент для декомпиляции: пока вы загружаете инструмент для выполнения, вы можете декомпилировать файл класса.
Джад может декомпилировать файлы классов в java-файлы.
Однако jad давно не обновлялся, при декомпиляции байт-кода, сгенерированного Java7, периодически возникают неподдерживаемые проблемы, а при декомпиляции лямбда-выражений в Java 8 — полный сбой.
Адрес: http://www.javadecompilers.com/jad
CFR
jad очень прост в использовании, но он давно не обновлялся, поэтому могу заменить его только на новый инструмент CFR хороший выбор по сравнению с jad его синтаксис может быть немного сложнее, но к счастью он может работать.
Адрес: http://www.benf.org/other/cfr/index.html.
JD-GUI
JD-GUI — это отдельная графическая утилита, которая отображает исходный код Java для файлов «.class». Вы можете просматривать реконструированный исходный код с помощью JD-GUI для немедленного доступа к методам и полям.
Поскольку у нас есть инструменты для декомпиляции файлов Class, защита Java-программ становится очень важной задачей для разработчиков.
Однако рост дьявола составляет один фут, а рост Дао - один чжан. Конечно, для декомпиляции существуют соответствующие технологии.
Однако здесь следует указать, что, как и в случае с защитой сетевой безопасности, сколько бы усилий ни прилагалось, это только увеличит затраты злоумышленников. нельзя полностью предотвратить.
Типичные стратегии выживания следующие:
Изолируйте программы Java, чтобы пользователи не могли прикасаться к вашим файлам Class
Зашифровать файл класса, упомянув о сложности взлома
Обфускация кода, преобразование кода в форму, функционально эквивалентную, но трудную для чтения и понимания.
Например, пакет jar промежуточного программного обеспечения распределенных транзакций с открытым исходным кодом Alibaba зашифрован с помощью технологии обфускации.Декомпилированное содержимое выглядит следующим образом: