По просьбам трудящихся выкладываю версию в новой записи.
Что появилось/изменилось:
+++ Добавился флаг 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