Вопрос

Я заинтересован в написании диссеминатора x86 в качестве образовательного проекта.

Единственный реальный ресурс, который я нашел, - это Spiral Space ".Как написать дизассемблер".Хотя это дает хорошее высокоуровневое описание различных компонентов дизассемблера, меня интересуют некоторые более подробные ресурсы.Я также бегло взглянул на NASM's исходный код, но это несколько тяжеловесный материал для изучения.

Я понимаю, что одной из основных проблем этого проекта является довольно большой набор команд x86, с которым мне придется справиться.Меня также интересует базовая структура, базовые ссылки на дизассемблер и т.д.

Кто-нибудь может указать мне на какие-либо подробные ресурсы по написанию дизассемблера x86?

Это было полезно?

Решение

Взгляните на раздел 17.2 из числа Справочное руководство программиста 80386.Дизассемблер - это на самом деле просто прославленный конечный автомат.Этапы разборки следующие:

  1. Проверьте, является ли текущий байт байтом префикса инструкции (F3, F2, или F0);если это так, то у вас есть REP/REPE/REPNE/LOCK префикс.Переходите к следующему байту.
  2. Проверьте, является ли текущий байт байтом размера адреса (67).Если это так, декодируйте адреса в остальной части инструкции в 16-разрядном режиме, если в данный момент они находятся в 32-разрядном режиме, или декодируйте адреса в 32-разрядном режиме, если в данный момент они находятся в 16-разрядном режиме
  3. Проверьте, является ли текущий байт байтом размера операнда (66).Если это так, декодируйте непосредственные операнды в 16-разрядном режиме, если в данный момент они находятся в 32-разрядном режиме, или декодируйте непосредственные операнды в 32-разрядном режиме, если в данный момент они находятся в 16-разрядном режиме
  4. Проверьте, является ли текущий байт байтом переопределения сегмента (2E, 36, 3E, 26, 64, или 65).Если это так, используйте соответствующий сегментный регистр для декодирования адресов вместо сегментного регистра по умолчанию.
  5. Следующий байт - это код операции.Если код операции равен 0F, тогда это расширенный код операции, и считайте следующий байт как расширенный код операции.
  6. В зависимости от конкретного кода операции считайте и декодируйте байт Mod R/M, байт базового индекса масштаба (SIB), смещение (0, 1, 2 или 4 байта) и/или непосредственное значение (0, 1, 2 или 4 байта).Размеры этих полей зависят от кода операции, переопределения размера адреса и переопределения размера операнда при ранее декодировании.

Код операции сообщает вам о выполняемой операции.Аргументы кода операции могут быть декодированы в виде значений Mod R/M, SIB, смещения и немедленного значения.Существует множество возможностей и множество особых случаев из-за сложной природы x86.Смотрите ссылки выше для более подробного объяснения.

Другие советы

Я бы порекомендовал проверить некоторые дизассемблеры с открытым исходным кодом, желательно искажать и особенно "disOps (Инструкции по установке базы данных)" (ctrl + найдите его на странице).

Сама документация полна полезной информации о кодах операций и инструкциях.

Цитата из https://code.google.com/p/distorm/wiki/x86_x64_Machine_Code

инструкция 80x86:

В 80х86 инструкции делится на количество элементов:

  1. Префиксы команд, влияющие на поведение команды операция.
  2. Обязательный префикс, используемый в качестве байта кода операции для инструкций SSE.
  3. Байты кода операции, могут быть одним или несколькими байтами (до 3 целых байт).
  4. Байт ModR/M является необязательным и иногда может содержать часть самого кода операции .
  5. Байт SIB является необязательным и представляет сложные формы косвенного обращения к памяти .
  6. Смещение является необязательным и представляет собой значение переменного размера в байт (byte, word, long) и используется как смещение.
  7. Значение Immediate является необязательным и используется как общее числовое значение, построенное из байтов разного размера (byte, word, long).

Формат выглядит следующим образом:

/-------------------------------------------------------------------------------------------------------------------------------------------\
|*Prefixes | *Mandatory Prefix | *REX Prefix | Opcode Bytes | *ModR/M | *SIB | *Displacement (1,2 or 4 bytes) | *Immediate (1,2 or 4 bytes) |
\-------------------------------------------------------------------------------------------------------------------------------------------/
* means the element is optional.

Структуры данных и этапы декодирования описаны в https://code.google.com/p/distorm/wiki/diStorm_Internals

Цитата:

Фазы декодирования

  1. [Префиксы]
  2. [Извлечь код операции]
  3. [Код операции фильтрации]
  4. [Извлечь операнд (ы)]
  5. [Форматирование текста]
  6. [Шестнадцатеричный Дамп]
  7. [Расшифрованная инструкция]

Также объясняется каждый шаг.


Исходные ссылки сохранены по историческим причинам:

http://code.google.com/p/distorm/wiki/x86_x64_Machine_Code и http://code.google.com/p/distorm/wiki/diStorm_Internals

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

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

Вам нужна таблица кодов операций для загрузки.

Фундаментальная структура данных поиска - это trie, однако таблица будет работать достаточно хорошо, если вы не очень заботитесь о скорости.

Чтобы получить базовый тип кода операции, начните с сопоставления в таблице.

Существует несколько стандартных способов декодирования аргументов регистра;однако существует достаточно особых случаев, чтобы потребовать реализации большинства из них по отдельности.

Поскольку это учебное пособие, взгляните на ndisasm .

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top