Как написать дизассемблер? [закрытый]
Я заинтересован в написании x86 dissembler в качестве образовательного проекта.
единственный реальный ресурс, который я нашел, - это спиральное пространство",Как написать дизассемблер". Хотя это дает хорошее описание высокого уровня различных компонентов дизассемблера, меня интересуют некоторые более подробные ресурсы. Я также быстро взглянул на в NASM-х исходный код, но это несколько супертяжелом учиться.
Я понимаю, одна одной из основных проблем этого проекта является довольно большой набор инструкций x86, который мне придется обрабатывать. Меня также интересует базовая структура, основные ссылки дизассемблера и т. д.
может ли кто-нибудь указать мне на какие-либо подробные ресурсы по написанию дизассемблера x86?
5 ответов:
посмотри 17.2 на программист 80386 это. Дизассемблер действительно просто прославленный автомат. Шаги в разборке являются:
- проверьте, является ли текущий байт байтом префикса инструкции (
F3,F2илиF0); если это так, то у вас естьREP/REPE/REPNE/LOCKпрефикс. Переход к следующему байту.- проверьте, если текущая byte-это байт размера адреса (
67). Если это так, декодируйте адреса в остальной части инструкции в 16-битном режиме, если в настоящее время в 32-битном режиме, или декодируйте адреса в 32-битном режиме, если в настоящее время в 16-битном режиме- проверьте, является ли текущий байт байтом размера операнда (
66). Если да, то декодируйте непосредственные операнды в 16-битном режиме, если в настоящее время в 32-битном режиме, или декодируйте непосредственные операнды в 32-битном режиме, если в настоящее время в 16-битном режиме- проверяем, чтобы увидеть, если текущий байт является байт переопределения сегмента (
2E,36,3E,26,64или65). Если это так, используйте соответствующий сегментный регистр для декодирования адресов вместо стандартного сегментного регистра.- следующий байт-это код операции. Если код операции
0F, то это расширенный код операции, и читать следующий байт как расширенный код операции.- в зависимости от конкретного кода операции считайте и декодируйте байт Mod R/M, байт базы индекса масштаба (SIB), смещение (0, 1, 2 или 4 байта), и/или непосредственное значение (0, 1, 2 или 4 байта). Размеры этих полей зависят от кода операции , переопределения размера адреса и переопределений размера операнда, ранее декодированных.
код говорит вам, что операция выполняется. Аргументы кода операции могут быть декодированы из значений Mod R / M, SIB, смещения и непосредственного значения. Есть много возможностей и много особых случаев, из-за сложной природы x86. См. ссылки выше для более подробного объяснения.
Я бы рекомендовал проверить некоторые дизассемблеры с открытым исходным кодом, предпочтительно distorm и особенно " disOps (инструкции устанавливает базу данных)" (ctrl+найти его на странице).
сама документация полна сочной информации об опкодах и инструкциях.
цитатаhttps://code.google.com/p/distorm/wiki/x86_x64_Machine_Code
80x86 инструкция:
инструкция 80x86 делится на количество элементов:
- префиксы инструкций, влияет на поведение инструкции операция.
- обязательный префикс, используемый в качестве байта кода операции для инструкций SSE.
- байт кода операции, может быть один или несколько байт (до 3 целых байт).
- байт ModR/M является необязательным и иногда может содержать часть сам код операции.
- байт Сиб опционный и представляет комплекс косвенного обращения к памяти формы.
- смещение является обязательным, и это значение переменной размер байты (байт, слово, длиной) и использованный как сдвиг.
- Immediate является необязательным и используется в качестве общего числового значения, построенного от различного размера байтов(байт, словом, долго).
формат выглядит следующим образом:
/-------------------------------------------------------------------------------------------------------------------------------------------\ |*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
цитата:
Декодирования Фазы
- [приставки]
- [Fetch Opcode]
- [Filter Opcode]
- [извлечь операнд(Ы)]
- [Форматирование]
- [Дамп]
- [Декодируются Инструкция]
каждый шаг объяснил также.
исходные ссылки сохраняются по историческим причинам:
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 источники-это отличный инструмент, он содержит много таблиц кодов операций, и его источники могут обеспечить хорошую базу для создания собственного дизассемблера.
Comments