Disassembler

Jan 12, 2010 23:14

По просьбам трудящихся выкладываю версию в новой записи.

Что появилось/изменилось:

+++ Добавился флаг OPERAND_FLAG_REL. Он означает, что значение операнда высчитывается относительно значения ip/eip/rip (начало следующей инструкции). Это относится к таким инструкциям как jmp/Jcc/call/etc.

+++ Чтобы немного автоматизировать процесс получения абсолютного адреса в инструкциях с флагом OPERAND_FLAG_REL, добавилась опция DISASM_OPTION_APPLY_REL. Беда в том, что она должна знать текущий адрес инструкции, поэтому появилось поле DISASM_INOUT_PARAMS::base. Как теперь выглядит процесс:

DISASM_INOUT_PARAMS params;
...
params.base = 0x00401000; //задаем начальный адрес кода.
params.options = DISASM_OPTION_APPLY_REL; //включаем опцию.
...
res = disassemble(ptr, &instr, ¶ms);
...
params.base += res; //прибавляем к базе размер полученной инструкции.

Теперь инструкция 'jmp 0x0' (0xEB 0x00) будет выглядеть как 'jmp 0x401002'.

+++ Возможность уничтожать смещения с нулевым значением теперь опциональна. Название опции == DISASM_OPTION_OPTIMIZE_DISP. Т.е. если мы хотим видеть инструкцию 'mov eax, [eax + 0x0]' как 'mov eax, [eax]', то включаем опцию. Иначе не включаем :).

=== Немного поменялась работа с операндами инструкций. Теперь для определения типа операнда не нужно делать сдвиг вправо, достаточно просто наложить маску: OPERAND_TYPE_MASK. Например:

switch (op ->flags & OPERAND_TYPE_MASK)
{
case OPERAND_TYPE_REG:
dump_reg(stream, op ->value.reg.type, op ->value.reg.code, op ->size);
break;
case OPERAND_TYPE_MEM:
dump_addr(stream, instr, op);
break;
case OPERAND_TYPE_IMM:
dump_imm(stream, op);
break;
case OPERAND_TYPE_DIR:
dump_dir(stream, op);
break;
default:
di_strncpy(stream, "internal error");
break;
}

=== Немного поменялись названия структур, чтобы выглядеть более красноречиво :).

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

http://www.8fn.net/200175
Previous post Next post
Up