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

Сношения с Идой

Крис Касперски

Хакер, номер #094, стр. 094-120-1

Секреты ассемблирования дизассемблерных листингов

Дизассемблер IDA Pro (как и любой другой) умеет генерировать ассемблерные листинги, однако их непосредственная трансляция невозможна, и прежде чем ассемблер проглотит наживку, приходится совершить немало телодвижений, о самых значимых из которых я и расскажу в этой статье.

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

Значительно реже дизассемблированную программу требуется оттранслировать заново. Например, хочется исправить множественные ошибки разработчиков, нарастить функционал или внести другие изменения… Конечно, все это можно сделать непосредственно в двоичном коде, наложив на программу «заплатку», присобаченную с помощью jump'ов. В большинстве случаев это самый короткий и самый надежный пусть. Нет никаких гарантий, что программа дизассемблирована правильно. Существует, по меньшей мере, три фундаментальные проблемы дизассемблирования: а) синтаксическая неразличимость смещений от констант; б) неоднозначность соответствия ассемблерных мнемоник машинным командам; в) код, ошибочно принятый за данные, и данные, ошибочно принятые за код.

Как следствие, откомпилированный дизассемблерный листинг в лучшем случае вообще не работает, зависая при запуске, в худшем же — периодически падает в разных местах. Но до этих проблем нам — как до Луны, а может, еще и дальше. Для начала необходимо протащить дизассемблерный листинг сквозь ассемблер, устранив явные ошибки трансляции, а со всем остальным мы разберемся как-нибудь потом (быть может, даже в следующей статье).

Первое боевое крещение

Давай создадим простейшую консольную программку типа «hello, world!», откомпилируем ее, а затем дизассемблируем с помощью IDA Pro и попытаемся ассемблировать полученный листинг.

Исходный текст в нашем случае выглядит так:

#include <stdio.h>

main()

{

printf("hello,world!n");

}

Компилируем его компилятором Microsoft Visual C++ 6.0 с настойками по умолчанию («cl.exe demo_console.c») и загружаем полученный exe-файл в IDA Pro 4.7. Естественно, можно использовать и другие версии продуктов, но тогда результат будет несколько отличаться, что, впрочем, на ход повествования практически никак не повлияет.

Дождавшись завершения дизассемблирования файла (когда экран IDA Pro будет выглядеть приблизительно, как показано на рис. 1), попросим ее сгенерировать ассемблированный листинг. Порядочные дизассемблеры поддерживают несколько популярных синтаксисов: TASM, MASM и, учитывая, что IDA Pro недавно была перенесена на Linux, неплохо бы добавить к этому списку еще и AT&T, но… увы! В меню «Options" --> "Target assembler» значится только какой-то загадочный «Generic for Intel 80x86», не совместимый ни с MASM'ом, ни с TASM'ом (во всяком случае, не с их последними версиями). В IDA Pro 5.0 в этом отношении сделан огромный шаг вперед, и теперь нам предлагают выбор между «Generic for Intel 80x86» и «Borland TASM in Ideal mode7 (см. рис. 2).

Содержание  Вперед на стр. 094-120-2
ttfb: 3.3011436462402 ms