Декомпилятор - Decompiler

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

Введение

Период, термин декомпилятор чаще всего применяется к программе, которая переводит исполняемый файл программ (вывод из компилятор ) в исходный код в (относительно) язык высокого уровня который при компиляции создаст исполняемый файл, поведение которого будет таким же, как у исходной исполняемой программы. Для сравнения: дизассемблер переводит исполняемую программу в язык ассемблера (и ассемблер может быть использован, чтобы собрать его обратно в исполняемую программу).

Декомпиляция - это действие с использованием декомпилятора, хотя этот термин также может относиться к выходным данным декомпилятора. Его можно использовать для восстановления утерянного исходного кода, а также в некоторых случаях полезно для компьютерная безопасность, совместимость и исправление ошибки.[1] Успех декомпиляции зависит от количества информации, содержащейся в декомпилируемом коде, и сложности анализа, выполняемого над ним. Форматы байт-кода, используемые многими виртуальными машинами (например, Виртуальная машина Java или .NET Framework общеязыковая среда выполнения ) часто включают обширные метаданные и высокоуровневые функции, которые делают декомпиляцию вполне возможной. Наличие данные отладки может сделать возможным воспроизведение исходных имен переменных и структур и даже номеров строк. Машинный язык без таких метаданных или отладочных данных декомпилировать гораздо труднее.[2]

Некоторые компиляторы и инструменты посткомпиляции производят запутанный код (то есть они пытаются произвести вывод, который очень трудно декомпилировать или который декомпилируется до запутанного вывода). Это сделано для того, чтобы было сложнее обратный инженер исполняемый файл.

Хотя декомпиляторы обычно используются для (воссоздания) исходного кода из двоичных исполняемых файлов, существуют также декомпиляторы для преобразования определенных файлов двоичных данных в читаемые и редактируемые источники.[3][4]

дизайн

Декомпиляторы можно рассматривать как состоящие из серии фаз, каждая из которых вносит свой вклад в определенные аспекты общего процесса декомпиляции.

Загрузчик

Первая фаза декомпиляции загружает и анализирует входной машинный код или промежуточный язык двоичный формат файла программы. Он должен уметь обнаруживать основные факты о программе ввода, такие как архитектура (Pentium, PowerPC и т. Д.) И точка входа. Во многих случаях он должен быть в состоянии найти эквивалент основной функция C программа, которая является началом написано пользователем код. Это исключает код инициализации среды выполнения, который по возможности не следует декомпилировать. Если доступны, также загружаются таблицы символов и данные отладки. Внешний интерфейс может идентифицировать используемые библиотеки, даже если они связаны с кодом, это обеспечит библиотечные интерфейсы. Если он может определить используемый компилятор или компиляторы, он может предоставить полезную информацию для определения идиом кода.[5]

Разборка

Следующим логическим этапом является разборка инструкций машинного кода в машинно-независимое промежуточное представление (IR). Например, машинная инструкция Pentium

mov    eax, [ebx+0x04]

может быть переведен на IR

eax  := м[ebx+4];

Идиомы

Последовательности идиоматического машинного кода - это последовательности кода, комбинированная семантика которых не сразу очевидна из индивидуальной семантики инструкций. Либо как часть фазы разборки, либо как часть более позднего анализа, эти идиоматические последовательности необходимо транслировать в известный эквивалентный IR. Например, ассемблерный код x86:

    cdq    eax             ; edx установлен на расширение знака ≠ edi, edi + (tex) push    xor    eax, edx    суб    eax, edx

можно перевести на

eax: = abs (eax);

Некоторые идиоматические последовательности не зависят от машины; некоторые включают только одну инструкцию. Например, xor eax, eax очищает eax register (обнуляет). Это может быть реализовано с помощью машинно-независимого правила упрощения, такого как а = 0.

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

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

Анализ программы

К IR можно применять различные программные анализы. В частности, распространение выражений объединяет семантику нескольких инструкций в более сложные выражения. Например,

    mov   eax,[ebx+0x04]    Добавить   eax,[ebx+0x08]    суб   [ebx+0x0C],eax

может привести к следующему IR после распространения выражения:

m [ebx + 12]: = m [ebx + 12] - (m [ebx + 4] + m [ebx + 8]);

Результирующее выражение больше похоже на язык высокого уровня, а также исключило использование машинного регистра. eax. Более поздние анализы могут устранить ebx регистр.

Анализ потока данных

Места, в которых определяется и используется содержимое регистров, должны отслеживаться с помощью анализ потока данных. Такой же анализ можно применить к местоположениям, которые используются для временных и локальных данных. Затем для каждого такого связанного набора определений значений и использования может быть сформировано другое имя. Возможно, что одно и то же местоположение локальной переменной использовалось для нескольких переменных в разных частях исходной программы. Еще хуже то, что анализ потока данных может определить путь, по которому значение может перемещаться между двумя такими использованиями, даже если на самом деле это никогда не произойдет или не будет иметь значения в действительности. В плохих случаях это может привести к необходимости определять местоположение как объединение типов. Декомпилятор может позволить пользователю явно нарушить такие неестественные зависимости, что приведет к более ясному коду. Это, конечно, означает, что переменная потенциально может использоваться без инициализации, что указывает на проблему в исходной программе.

Типовой анализ

Хороший декомпилятор машинного кода выполнит анализ типов. Здесь способ использования регистров или ячеек памяти приводит к ограничениям на возможный тип местоположения. Например, и инструкция подразумевает, что операнд является целым числом; программы не используют такую ​​операцию на плавающая точка значения (кроме кода специальной библиотеки) или на указатели. An Добавить инструкция приводит к трем ограничениям, поскольку операнды могут быть как целыми, так и одним целым числом и одним указателем (с целочисленными результатами и указателями соответственно; третье ограничение возникает из-за упорядочения двух операндов, когда типы различаются).[6]

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

Пример из предыдущего раздела может привести к следующему высокоуровневому коду:

структура Т1 *ebx;    структура Т1 {        int v0004;        int v0008;        int v000C;    };ebx->v000C -= ebx->v0004 + ebx->v0008;

Структурирование

Предпоследняя фаза декомпиляции включает в себя структурирование IR в конструкции более высокого уровня, такие как в то время как петли и если / то / еще условные утверждения. Например, машинный код

    xor eax, eaxl0002:    или  ebx, ebx    jge l0003    Добавить eax,[ebx]    mov ebx,[ebx+0x4]    jmp l0002l0003:    mov [0x10040000],eax

можно перевести на:

eax = 0;в то время как (ebx < 0) {    eax += ebx->v0000;    ebx = ebx->v0004;}v10040000 = eax;

Неструктурированный код сложнее перевести в структурированный код, чем уже структурированный код. Решения включают репликацию некоторого кода или добавление логических переменных.[7]

Генерация кода

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

Непосредственно перед генерацией кода может быть желательно разрешить интерактивное редактирование IR, возможно, используя некоторую форму графический интерфейс пользователя. Это позволит пользователю вводить комментарии и неуниверсальные имена переменных и функций. Однако их почти так же легко ввести при редактировании после декомпиляции. Пользователь может захотеть изменить структурные аспекты, например преобразовать в то время как петля к для петля. Их труднее изменить с помощью простого текстового редактора, хотя исходный код рефакторинг кода инструменты могут помочь в этом процессе. Пользователю может потребоваться ввести информацию, которую не удалось идентифицировать на этапе анализа типа, например преобразование выражения памяти в выражение массива или структуры. Наконец, может потребоваться исправить неправильный IR или внести изменения, чтобы выходной код был более читабельным.

Законность

Большинство компьютерных программ покрываются Авторские права законы. Хотя точный объем того, что покрывается авторским правом, отличается от региона к региону, закон об авторском праве обычно предоставляет автору (программисту (программистам) или работодателю) совокупность исключительных прав на программу.[8] Эти права включают право делать копии, в том числе копии, сделанные на компьютере ОЗУ (если создание такой копии не является необходимым для использования программы).[9]Поскольку процесс декомпиляции включает в себя создание нескольких таких копий, это обычно запрещено без разрешения правообладателя. Однако, поскольку декомпиляция часто является необходимым шагом в достижении программного обеспечения совместимость законы об авторских правах в США и Европе разрешают декомпиляцию в ограниченной степени.

В США авторское право добросовестное использование защита была успешно применена в случаях декомпиляции. Например, в Sega против Accolade, суд постановил, что Accolade может на законных основаниях участвовать в декомпиляции, чтобы обойти механизм блокировки программного обеспечения, используемый игровыми консолями Sega.[10] Кроме того, Закон об авторском праве в цифровую эпоху (ПУБЛИЧНЫЙ ЗАКОН 105–304[11]) имеет соответствующие исключения как для тестирования безопасности, так и для оценки в §1205 (i) и для обратного проектирования в §1205 (f).

В Европе Директива по программному обеспечению 1991 г. прямо предусматривает право на декомпиляцию для достижения интероперабельности. В результате жарких споров между, с одной стороны, сторонниками протекционизма, а с другой - учеными, а также независимыми разработчиками программного обеспечения, статья 6 разрешает декомпиляцию только при соблюдении ряда условий:

  • Во-первых, физическое или юридическое лицо должно иметь лицензия использовать декомпилируемую программу.
  • Во-вторых, декомпиляция должна быть необходима для достижения совместимость с целевой программой или другими программами. Поэтому информация о совместимости не должна быть легко доступна, например, в руководствах или API документация. Это важное ограничение. Необходимость должна быть доказана декомпилятором. Целью этого важного ограничения является прежде всего стимулирование разработчиков к документированию и раскрытию информации о совместимости своих продуктов.[12]
  • В-третьих, процесс декомпиляции должен, по возможности, ограничиваться частями целевой программы, имеющими отношение к взаимодействию. Поскольку одной из целей декомпиляции является понимание структуры программы, это третье ограничение может оказаться трудным для выполнения. Опять же, бремя доказательства лежит на декомпиляторе.

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

В целом право на декомпиляцию, предусмотренное статьей 6 кодифицирует то, что считается обычной практикой в ​​индустрии программного обеспечения. Известно, что некоторые европейские иски возникли из-за права на декомпиляцию. Это может быть истолковано как означающее одну из трех вещей: 1) право на декомпиляцию не часто используется, и поэтому право на декомпиляцию могло быть ненужным, 2) право на декомпиляцию функционирует хорошо и обеспечивает достаточную юридическую уверенность, чтобы не вызывать юридических споров или 3) незаконная декомпиляция в значительной степени остается незамеченной. В недавнем отчете о реализации Директивы по программному обеспечению европейскими государствами-членами Европейская комиссия похоже, поддерживает вторую интерпретацию.[13]

инструменты

Декомпиляторы обычно нацелены на определенный двоичный формат. Некоторые из них представляют собой собственные наборы инструкций (например, Intel x86, ARM, MIPS), другие представляют собой байт-код для виртуальных машин (Dalvik, файлы классов Java, WebAssembly, Ethereum).

Из-за потери информации во время компиляции декомпиляция почти никогда не бывает идеальной, и не все декомпиляторы работают одинаково хорошо для данного двоичного формата. Есть исследования, сравнивающие производительность разных декомпиляторов.[14]

Смотрите также

использованная литература

  1. ^ Ван Эммерик, Майк (2005-04-29). "Почему декомпиляция". Program-transformation.org. Получено 2010-09-15.
  2. ^ Мечниковский, Иероним; Хендрен, Лори (2002). «Декомпиляция байт-кода Java: проблемы, ловушки и подводные камни». В Хорспул, Р. Найджел (ред.). Конструирование компилятора: 11-я Международная конференция, сборник материалов / CC 2002. Springer-Verlag. С. 111–127. ISBN  3-540-43369-4.
  3. ^ Пол, Матиас Р. (2001-06-10) [1995]. "Описание формата файлов DOS, OS / 2 и Windows NT .CPI, и Linux .CP" (Файл CPI.LST) (1.30 ред.). В архиве из оригинала от 20.04.2016. Получено 2016-08-20.
  4. ^ Пол, Матиас Р. (13 мая 2002 г.). "[fd-dev] mkeyb". freedos-dev. В архиве из оригинала на 2018-09-10. Получено 2018-09-10. […] Анализатор, валидатор и декомпилятор файлов кодовых страниц .CPI и .CP […] Обзор параметров / Style: […] Исходные файлы ASM […] Автономные исходные файлы ASM […] Модульные исходные файлы ASM […]
  5. ^ Сифуэнтес, Кристина; Гоф, К. Джон (июль 1995 г.). «Декомпиляция двоичных программ». Практика и опыт работы с программным обеспечением. 25 (7): 811–829. CiteSeerX  10.1.1.14.8073. Дои:10.1002 / spe.4380250706.
  6. ^ Майкрофт, Алан (1999). «Типовая декомпиляция». В Swierstra, S. Doaitse (ред.). Языки и системы программирования: 8-й Европейский симпозиум по языкам и системам программирования. Springer-Verlag. С. 208–223. ISBN  3-540-65699-5.
  7. ^ Сифуэнтес, Кристина (1994). "Глава 6". Методы обратной компиляции (PDF) (Кандидатская диссертация). Квинслендский технологический университет. В архиве (PDF) из оригинала от 22.11.2016. Получено 2019-12-21.)
  8. ^ Роуленд, Дайан (2005). Закон об информационных технологиях (3-е изд.). Кавендиш. ISBN  1-85941-756-6.
  9. ^ «Бюро авторских прав США - Закон об авторском праве: Глава 1».
  10. ^ «Законность декомпиляции». Program-transformation.org. 2004-12-03. Получено 2010-09-15.
  11. ^ "Закон о защите авторских прав в цифровую эпоху" (PDF). Конгресс США. 1998-10-28. Получено 2013-11-15.
  12. ^ Чарнота, Бриджит; Харт, Роберт Дж. (1991). Правовая защита компьютерных программ в Европе: руководство к директиве ЕС. Лондон: Баттервортс Толли. ISBN  0-40600542-7.
  13. ^ «EUR-Lex - 52000DC0199 - EN».
  14. ^ Харранд, Николас; Сото-Валеро, Сезар; Монперрус, Мартин; Бодри, Бенуа (2019). «Сильные стороны и особенности поведения декомпиляторов байт-кода Java». 19-я Международная рабочая конференция по анализу исходного кода и манипулированию им (SCAM). IEEE: 92–102. arXiv:1908.06895. Bibcode:2019arXiv190806895H. Дои:10.1109 / SCAM.2019.00019. ISBN  978-1-7281-4937-0.

внешние ссылки