Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #78, ИЮНЬ 2005 г.

Дизассемблер своими руками

GPcH (www.dotfix.net)

Хакер, номер #078, стр. 078-114-2


Именно расшифровкой этих команд и занимается дизассемблер. Чтобы его написать самому с нуля, потребуется море сил и времени. Опкодов у x86 процессоров наделано жуть как много (загляни в интеловский мануал и убедись). Каждый имеет свои параметры, и каждый надо описать. Кодеры, чтобы осуществить дизассемблирование, обычно просто составляют огромную таблицу опкодов и используют ее при анализе кода. Ты прикинь, какого размера должна быть таблица — там одних mov’ов разных будет штук 10. А если вспомнить о всяческих расширениях вроде SSE и 3DNow! — так вообще дурно станет. Неужели, чтобы написать дизассемблер, самому придется днями и ночами сидеть над мануалами по процессорам, выписывая особенности той или иной инструкции? Как бы не так. Я предлагаю не париться чтением тысячестраничных мануалов и использовать уже готовые решения.

[выбираем компонент]

Если ты очень сильно постараешься, то найдешь целых два бесплатных дизассемблера, которые можно внедрить в свою прогу на Delphi. Первый выдирается из исходника DeDe, свободно распространяемого декомпилятора Delphi. При желании этот исходник ты можешь взять на диске или на сайте www.wasm.ru и самостоятельно его изучить. Мы же рассмотрим второй дизассемблер, поставляющийся в виде компонента для Delphi и бесплатный для некоммерческого использования. Называется он madDisAsm и входит в состав большой библиотеки компонентов madCollection (http://madshi.bei.t-online.de). В «бешеной коллекции» помимо дизассемблера есть еще куча всего интересного. Есть, к примеру, «бешеный Бэйсик» (madBasic), но это уже совсем другая история. Даже немного жаль, что нам потребуется только madDisAsm.

[madDisAsm]

Данный компонент практически не документирован. Описаны только прототипы функций и структур. Примеров же использования нет ни одного, из чего следует, что разбираться со всем придется нам самим. Что ж, давай рассмотрим функции данного рульного компонента. Основных всего две. Первая позволяет дизассемблировать одну машинную инструкцию. Ее прототип выглядит следующим образом:

function ParseCode (code: pointer; var disAsm: string) : TCodeInfo; overload;

code — это pointer (указатель) на код инструкции, которую мы хотели бы дизассемблировать.

disAsm — переменная, в которую будет занесена первая дизассемблированная строчка.

TCodeInfo — информация, полученная в результате анализа кода. Одним из элементов этой структуры является ссылка на следующую инструкцию. С ее помощью мы можем дизассемблировать в цикле сразу несколько инструкций, следующих друг за другом.

[структура TCodeInfo]

TCodeInfo = record

// действительно ли это опкод

IsValid : boolean;

// опкод, один ($00xx) или два ($0fxx) байта

Opcode : word;

// ModRm-байт, если присутствует, иначе 0

ModRm : byte;

Назад на стр. 078-114-1  Содержание  Вперед на стр. 078-114-3