C++ Перевести байты в коды операций?

Я не уверен, как сформулировать этот вопрос, но мне любопытно узнать, как ассемблеры и другие инструменты показывают коды операций определенных байтов?

std::string BytesToOpcode( __in ::BYTE Bytes );

int main( void )
{
    std::cout << BytesToOpcode( ( ::PBYTE )"\x33\xC0" );
    std::cin.get( );
    return( EXIT_SUCCESS );
};

// I don't know what type soo I'll just set as std::string for an example.
std::string BytesToOpcode( __in ::BYTE Bytes )
{
    // Convert Bytes to opcode??
    return( "" );
};


Output should be:
XOR EAX,EAX

3 ответа

Решение

Как правило, дизассемблер будет иметь комбинацию таблиц и "типа декодирования" (который обычно является указателем функции или чем-то, что входит в оператор switch) - тип декодирования сообщает, к какому классу относится инструкция - например, xor, or, and, add, sub будет иметь такое же декодирование, но call, jmp было бы другое декодирование. jnz, jz, jnc, jc, ja, jb, jbe, etc будет иметь еще один тип декодирования.

Таким образом, таблица первого уровня будет 256 входной таблицей. Затем у вас есть определенные записи, которые являются "префиксом", такие как 0xffгде следующий байт говорит, что инструкция "на самом деле". Опять вы получаете таблицу из 256 prefix0xff входная таблица.

Некоторые записи могут быть недействительными, так как не все комбинации взяты до сих пор [хотя почти все].

Хитрый - это записи "префикс модификатора". Например, 0x66 переключит команду с размера операнда от 32 до 16 бит (или наоборот, если процессор находится в 16-битном режиме).

Большая часть фактического декодирования внутри каждой категории будет включать в себя переворачивание битов и перевод "битов 5-3" в регистр числа или "битов 1-2" в режим адресации (верно? eax, [eax] или же [eax+esi], например).

Это довольно много работы. Я написал дизассемблер для 80186, и это заняло у меня около двух дней работы почти весь день. Тем не менее, я уже знал, что я делал. Преобразование в 386 заняло еще 2-3 дня, и я не хотел бы думать о том, чтобы сделать это для современного процессора x86 со всеми SSE, MMX, 3DNow! и т.д. инструкции.

[И я слишком долго объяснял, как это сделать, чтобы получить "правильный ответ" - даже если это правильный ответ того, как вы это делаете - конечно, использование уже существующей библиотеки, безусловно, является более простым способом сделать это. Это].

Это очень сложная задача. Набор команд x86 очень сложен. Лучше всего будет использовать одну из существующих библиотек разборки x86, чтобы делать то, что вы хотите.

Эти ссылки должны помочь вам начать.

Вы можете использовать побитовые операции, например, если ваша инструкция XOR и ваш код операции =4 бита, а код равен 3, вам нужно выполнить MASK и Shift, чтобы получить эти 3, для этого вы:

your example in bin:   0011 0011 1100 0000
make a AND with:       1111 0000 0000 0000
Result:                0011 0000 0000 0000
Shift 12 places:       0000 0000 0000 0011 <-- This is 3, so you got the instruction 3

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

Другие вопросы по тегам