Можно ли декодировать инструкции x86-64 в обратном порядке? - PullRequest
0 голосов
/ 20 сентября 2018

Мне было интересно, можно ли декодировать инструкции x86-64 в обратном порядке?

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

Я хочу сделать это путем обратного декодирования.

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Поток команд x86 не является самосинхронизирующимся и может быть только однозначно декодирован вперед.Вам нужно знать правильную начальную точку для декодирования.Последним байтом немедленного значения может быть 0x90, который декодируется как nop, или, как правило, 4-байтовое немедленное или смещение может иметь байтовые последовательности, которые являются действительными инструкциями, или любые другие возможности перекрытия с байтами ModRM / SIB.выглядит как коды операций.

Если вы декодируете вперед в коде, который не является преднамеренно запутанным, вы часто возвращаетесь к синхронизации с «правильными» границами команд, поэтому вы можете попытаться запомнить границы команд как заведомо исправныеукажите и убедитесь, что декодирование с начального адреса кандидата с обратным шагом имеет границу инструкций в вашей заведомо хорошей точке.

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

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


Другой альтернативой является требование функциональных символов (externфункции или любая другая функция с отладочной информацией).

GDB не позволяет прокручивать вверх (в режиме layout reg), если вы не находитесь внутри функции, которой известен начальный адрес.Затем, я думаю, он декодируется с начального адреса функции, поэтому он знает границы инструкций, когда попадает в ту часть, которая помещается в окне.

Если вы хотите вернуться назад, вам нужно disas 0x12345, +16, чтобы начать декодирование стам.Затем вы можете прокрутить вниз, но если вы ошибетесь в границах insn, вы получите мусор.

0 голосов
/ 20 сентября 2018

Базовый формат инструкций x86 выглядит следующим образом:

x86 instruction format

Современные процессоры могут поддерживать префиксы VEX и EVEX.В x86-64 также может присутствовать префикс REX в начале

Если посмотреть на формат, можно легко увидеть, что инструкции не являются палиндромами и вы не можете читать с конца.


Что касается определения, к какой инструкции принадлежит произвольный адрес, к сожалению, это также невозможно сделать, потому что инструкции x86 не являются самосинхронизируемыми и (как правило) не выровнены.Вы должны точно знать начало инструкции, иначе инструкция будет декодирована по-разному.

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

Тем не менее, можно угадать вво многих случаях, поскольку функции и циклы часто выровнены по 16 или 32 байтам, а значения NOP дополняются

...