количество выполненных байтов при отладке PE - PullRequest
0 голосов
/ 08 ноября 2018

В настоящее время я пишу небольшой отладчик в сборке на платформе Windows.

Я открываю процесс отладки следующим образом:

invoke    CreateProcess, addr buffer, NULL, NULL, NULL, FALSE, DEBUG_PROCESS+DEBUG_ONLY_THIS_PROCESS, NULL, NULL, addr startinfo, addr pi

Это работает хорошо, я могу получить EIP, посмотрев на контекст отладчика, и таким образом я могу получить 1-й байт инструкции, которая будет выполнена.

Однако мне нужно получить количество байтов, которые были выполнены в предыдущей инструкции.

Инструкции не зависят от размера. Иногда инструкция занимает всего 1 байт, а иногда - 6 или более байтов.

Я попытался вычесть предыдущий EIP текущим EIP, чтобы получить количество выполненных байтов. Но это не работает, если есть JMP или вызов, потому что адресное пространство больше не то же самое.

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

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

С наилучшими пожеланиями

1 Ответ

0 голосов
/ 08 ноября 2018

TL; DR

Сохраняйте это простым: один шаг и декодируйте только инструкции ветвления и используйте EIP - last EIP, если только последняя инструкция не была ветвью (в этом случае используйте декодирование, чтобы найти длину).
Если неизвестная инструкция найдена, отступите и не указывайте ее размер.


Невозможно декодировать поток инструкций x86 в обратном направлении, потому что кодировка x86 не является симметричной (рост адреса w.r.t.), чтобы увидеть это mov eax, 90909090h или подобное.

Таким образом, вам нужно разбирать каждую инструкцию по мере того, как вы проходите через программу (это все равно нужно отладчику) и записывать ее размер.
Команды передачи управления значительно меньше, чем общее количество команд, поэтому вы можете декодировать только это и использовать трюк EIP - EIP' (где EIP' - EIP последней инструкции) в противном случае.

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

Я не могу вспомнить ни одного события для счетчиков производительности (при условии, что вы можете их использовать), которое привело бы к количеству байтов инструкции.
На самом деле в бэкэнде понятие «инструкция» было сведено к последовательности операций (возможно, с небольшим, чтобы сказать, что код операции является последним в инструкции), а интерфейс в основном отделен от архитектурного значения eip (работает почти всегда с умозрительным значением eip), поэтому перед бэкэндом может быть несколько инструкций.
Я полагаю, что каждый uOP, вероятно, имеет поле для записи, как обновлять eip при выходе на пенсию, но не размер инструкции в байтах.
Точно так же во внешнем интерфейсе только на этапе предварительного декодирования записывается длина инструкции в байтах, после чего я думаю, что она отбрасывается (я не могу думать о каком-либо ее использовании).

Инструкции в кеше команд L1 еще не декодированы, поэтому даже если бы был способ проверить их содержимое и метаданные , там ничего бы не было.

Обычный способ сделать это - выполнить трассировку: пошагово выполнить программу, разобрать инструкцию в eip (см. Ниже), записать ее размер, возобновить программу, повторить до состояния остановки.
Это дает вам список адресов и размеров инструкций.
Если вы находите инструкцию, которую вы не можете декодировать, вы либо не записываете ее размер, либо пытаетесь оценить ее с помощью некоторой эвристики (ее длина должна быть меньше 16 В, и вы теоретически можете интегрировать данные с количеством из PMC, например 1034 *).

Возможно определить размер инструкции во время выполнения, но это совершенно неосуществимо в этом контексте .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...