Дизассемблер — это компьютерная программа , которая переводит машинный язык на язык ассемблера — операция, обратная операции ассемблера . Дизассемблер , вывод дизассемблера, часто форматируется для удобства чтения человеком, а не для пригодности для ввода в ассемблер, что делает его в основном инструментом обратного проектирования . Обычные применения дизассемблеров включают анализ вывода компиляторов языков программирования высокого уровня и их оптимизаций, восстановление исходного кода программы, исходный код которой был утерян, анализ вредоносных программ , изменение программного обеспечения (например, взлом ПЗУ ) и взлом программного обеспечения .
Дизассемблер отличается от декомпилятора тем, что он ориентирован на язык высокого уровня, а не на язык ассемблера.
Исходный код на языке ассемблера обычно допускает использование констант и комментариев программиста . Обычно они удаляются из собранного машинного кода ассемблером. В таком случае дизассемблер, работающий с машинным кодом, произведет дизассемблирование, в котором отсутствуют эти константы и комментарии; дизассемблированный вывод становится более сложным для интерпретации человеком, чем исходный аннотированный исходный код. Некоторые дизассемблеры предоставляют встроенную функцию комментирования кода, при которой сгенерированный вывод обогащается комментариями относительно вызываемых функций API или параметров вызываемых функций. Некоторые дизассемблеры используют символьную отладочную информацию, присутствующую в объектных файлах, таких как ELF . Например, IDA позволяет пользователю-человеку составлять мнемонические символы для значений или областей кода в интерактивном сеансе: человеческое понимание, применяемое к процессу дизассемблирования, часто соответствует человеческому творчеству в процессе написания кода.
Написание дизассемблера, который производит код, который при сборке производит точно такой же двоичный файл, возможно; однако часто есть различия. Это предъявляет требования к выразительности ассемблера. Например, ассемблер x86 делает произвольный выбор между двумя двоичными кодами для чего-то столь простого, как . Если исходный код использует другой выбор, исходный код просто не может быть воспроизведен в любой заданный момент времени. Однако даже когда производится полностью правильный дизассемблированный файл, проблемы остаются, если программа требует модификации. Например, одна и та же инструкция перехода на машинном языке может быть сгенерирована кодом ассемблера для перехода в указанное место (например, для выполнения определенного кода) или для перехода на указанное количество байтов (например, для пропуска нежелательной ветви). Дизассемблер не может знать, что именно предполагается, и может использовать любой синтаксис для генерации дизассемблированного файла, который воспроизводит исходный двоичный файл. Однако если программист хочет добавить инструкции между инструкцией перехода и ее местом назначения, необходимо понимать работу программы, чтобы определить, должен ли переход быть абсолютным или относительным, т. е. должно ли его место назначения оставаться в фиксированном месте или быть перемещено таким образом, чтобы пропустить как исходные, так и добавленные инструкции.MOV AX,BX
Другая проблема заключается в том, что не всегда возможно определить, какие части двоичного файла соответствуют исполняемому коду, а какие — данным. В то время как распространенные исполняемые форматы, такие как ELF и PE, делят двоичный файл на исполняемые и данные, другие форматы, такие как плоские двоичные файлы, этого не делают, поэтому любое заданное место в двоичном файле может содержать исполняемые инструкции или неисполняемые данные, что затрудняет принятие решения о том, следует ли его дизассемблировать как инструкции или оставить как данные. Поскольку процессоры обычно допускают динамические переходы, вычисляемые во время выполнения, не всегда возможно определить все возможные места в двоичном файле, в которые можно перейти и которые, следовательно, содержат инструкции.
В архитектурах компьютеров с инструкциями переменной ширины , например, во многих архитектурах компьютеров со сложным набором инструкций (CISC) , допустимым может быть более одного дизассемблирования.
Дизассемблеры не обрабатывают код, который изменяется во время выполнения.
Шифрование может использоваться в некоторых компьютерных программах, особенно в рамках управления цифровыми правами, чтобы помешать обратному проектированию и взлому . Это создает дополнительную проблему для дизассемблирования, поскольку код должен быть расшифрован перед дизассемблированием.
Дизассемблер может быть автономным или интерактивным. Автономный дизассемблер при запуске генерирует файл на языке ассемблера, который можно изучить; интерактивный дизассемблер немедленно показывает эффект любого изменения, вносимого пользователем. Например, дизассемблер может изначально не знать, что раздел программы на самом деле является кодом, и рассматривать его как данные; если пользователь указывает, что это код, полученный дизассемблированный код отображается немедленно, что позволяет пользователю изучить его и предпринять дальнейшие действия во время того же запуска.
Любой интерактивный отладчик будет включать в себя некоторый способ просмотра дизассемблирования отлаживаемой программы. Часто тот же инструмент дизассемблирования будет упакован как автономный дизассемблер, распространяемый вместе с отладчиком. Например, objdump , часть GNU Binutils , связан с интерактивным отладчиком gdb . [1]
Динамический дизассемблер может быть включен в вывод эмулятора или гипервизора для «отслеживания», строка за строкой, реального времени выполнения любых выполняемых машинных инструкций. В этом случае, а также строки, содержащие дизассемблированный машинный код, регистр(ы) и/или изменение(я) данных (или любые другие изменения « состояния », такие как коды условий), которые вызывает каждая отдельная инструкция, могут быть показаны рядом или под дизассемблированной инструкцией. Это обеспечивает чрезвычайно мощную отладочную информацию для окончательного решения проблемы, хотя размер результирующего вывода иногда может быть довольно большим, особенно если он активен для выполнения всей программы. OLIVER предоставлял эти функции с начала 1970-х годов как часть своего предложения отладочного продукта CICS и теперь его можно найти включенным в продукт XPEDITER от Compuware .
Дизассемблер длины , также известный как механизм дизассемблера длины ( LDE ), — это инструмент, который, учитывая последовательность байтов (инструкций), выводит количество байтов, занятых проанализированной инструкцией. Известные проекты с открытым исходным кодом для архитектуры x86 включают ldisasm, [8] Tiny x86 Length Disassembler [9] и Extended Length Disassembler Engine для x86-64. [10]