сборка x86 - недопустимый код операции 0xff / 7 под Windows - PullRequest
4 голосов
/ 12 февраля 2009

В настоящее время я разрабатываю дизассемблер x86 и начал разбирать PE-файл win32. Большая часть дизассемблированного кода выглядит хорошо, однако есть некоторые случаи неправильного кода операции 0xff / 7 (/ 7 означает reg = 111, 0xff - группа кода операции inc / dec / call / callf / jmp / jmpf / push / недопустимо с операндом р / м 16/32). Первое предположение состояло в том, что / 7 - это команда pop, но она закодирована в 0x8f / 0. Я проверил это по официальному руководству Intel для разработчиков программного обеспечения, том 2: Справочник по наборам инструкций - так что я не просто ошибаюсь.

Пример разборки: (S0000O0040683a - метка, к которой переходит другая инструкция)

S0000O0040683a: inc    edi                      ; 0000:0040683a  ff c7
                test   dword ptr [eax+0xff],edi ; 0000:0040683c  85 78 ff
                0xff/7 edi                      ; 0000:0040683f  ff ff

Кстати: GDB разбирает это одинаково (за исключением ошибки 0xff, не приводящей к -1 в моей разборке):

(gdb) disassemble 0x0040683a 0x00406840
Dump of assembler code from 0x40683a to 0x406840:
0x0040683a:     inc    %edi
0x0040683c:     test   %edi,0xffffffff(%eax)
0x0040683f:     (bad)  
End of assembler dump.

Таким образом, вопрос заключается в следующем: есть ли какой-либо обработчик по умолчанию в обработчике исключений недопустимого кода операции Windows, который реализует какую-либо функциональность в этом недопустимом коде операции, и если да, то что происходит там?

С уважением, Бодо

Ответы [ 4 ]

4 голосов
/ 13 февраля 2009

После многих дополнительных часов работы моего дизассемблера для получения вывода в том же синтаксисе, что и в gdb, я смог разобраться в двух версиях. Это выявило довольно неловкую ошибку в моем дизассемблере: я забыл учесть, что инструкция перехода 0x0f 0x8x имеет двухбайтовый код операции (плюс операнд rel16 / 32). Таким образом, каждая цель перехода 0x0f 0x8x была отключена тем, что приводило к коду, который в реальности недоступен. После исправления этой ошибки никакие коды операции 0xff / 7 больше не разбираются.

Спасибо всем, кто отвечает на мой вопрос (и комментирует эти ответы) и, таким образом, хотя бы пытается помочь мне.

2 голосов
/ 12 февраля 2009

Visual Studio разбирает это на следующее:

00417000 FF C7            inc         edi  
00417002 85 78 FF         test        dword ptr [eax-1],edi 
00417005 ??               db          ffh  
00417006 FF 00            inc         dword ptr [eax] 

Очевидно, что общая ошибка защиты происходит в 00417002, потому что eax не указывает на что-либо значимое, но даже если я ее исключаю (90 90 90), он вызывает исключение недопустимого кода операции в 00417005 (оно не обрабатывается ядром ). Я почти уверен, что это какие-то данные, а не исполняемый код.

1 голос
/ 12 февраля 2009

Чтобы ответить на ваш вопрос, Windows закроет приложение с кодом исключения 0xC000001D STATUS_ILLEGAL_INSTRUCTION. Диалог будет соответствовать диалогу, используемому для любых других сбоев приложения, независимо от того, предлагает ли он отладчик или для отправки отчета об ошибке.

Что касается предоставленного кода, он, по-видимому, либо неправильно собран (кодирует смещение более 8 бит), либо фактически является данными (как уже предлагалось другими). ​​

0 голосов
/ 12 февраля 2009

Похоже, что 0xFFFFFFFF был вставлен вместо 0xFF для инструкции по тестированию, возможно, с ошибкой?

85 = test r / m32, а 78 - это байт для параметров [eax + disp8], edi, с последующим disp8, который должен быть просто 0xFF (-1), но как 32-разрядное целое число со знаком это 0xFFFFFFFF .

Итак, я предполагаю, что у вас есть 85 78 FF FF FF FF, где должно быть 85 B8 FF FF FF FF для 32-битного смещения или 85 78 FF для 8-битного смещения? Если это так, то следующий байт в коде должен быть 0xFF ...

Конечно, как уже предлагалось, это могут быть просто данные, и не забывайте, что данные могут храниться в PE-файлах, и нет строгой гарантии какой-либо конкретной структуры. Вы можете вставить код или определенные пользователем данные в некоторые поля заголовков MZ или PE, если агрессивно оптимизируете, чтобы уменьшить размер .exe.

РЕДАКТИРОВАТЬ: согласно комментариям ниже, я бы также рекомендовал использовать исполняемый файл, в котором вы уже точно знаете, каким должен быть ожидаемый дизассемблированный код.

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