ЛитВек - электронная библиотека >> Крис Касперски >> Отладка, тестирование и оптимизация ПО и др. >> Техника отладки приложений без исходных кодов (Статья о SoftICE)

Крис Касперски ака мыщъх ТЕХНИКА ОТЛАДКИ ПРИЛОЖЕНИЙ БЕЗ ИСХОДНЫХ КОДОВ

Введение в отладку

Отладчик — невероятно мощный инструмент в руках взломщика, однако к нему нужен свой подход. Большинство начинающих хакеров начинает отлаживать программу с точки входа и… умирает в цикле выборки сообщений. Пошаговое исполнение программы (также называемое трассировкой) — слишком трудоемкий и крайне неэффективный процесс. Событийно-ориентированные приложения (а к ним относятся практически все Windows-приложения) так не отлаживаются. Допустим, мы трассируем MFC-приложение, доходим до вызова AfxWinMain и… оказываемся глубоко внутри MFC42.DLL, откуда уже и вызывается весь пользовательский код, но прежде чем трассировка доберется до него, мы успеем состариться!

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

Мы будем курочить программу Drive LED от компании O&O Software, 30-дневую демонстрационную версию которой можно скачать с сайта: http://www.oo-software.com/en/download/index.shtml;

Дизассемблер и отладчик в одной упряжке

Дизассемблер содержится в каждом отладчике (мы же ведь не собираемся отлаживать программу непосредственно в машинном коде, верно?), но тот дизассемблер, что находится внутри soft-ice или OllyDbg, слишком примитивен и ненагляден. IDA PRO намного мощнее. Она автоматически распознает имена библиотечных функций, определяет типы локальных переменных и делает множество других полезных вещей — в частности, позволяет комментировать листинг и назначать символьные метки для инструкций и данных. Исследовать защищенные программы с ее помощью — настоящее удовольствие. Однако вызовы типа call [ebx+64h] приводят хакеров в бешенство, особенно если функция вызывается из различных мест с различным ebx. На выяснение значения ebx в дизассемблере можно ухлопать целый день, а в отладчике просто «подсмотрел» его и все!

Или вот вызывается что-то по адресу 77E92B8D, лежащим где-то внутри операционной системы (при дизассемблировании дампов памяти такие адреса встречаются сплошь и рядом). В отладчике достаточно просто дать команду «u 77E92B8D» и мы тут же увидим, что это CreateFileA.

Бессмысленно спорить, кто круче — отладчик или дизассемблер. Эти инструменты взаимно дополняют друг друга. Реконструкцию алгоритмов лучше поручить дизассемблеру, а все непонятные места уточнять в отладчике.

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


Техника отладки приложений без исходных кодов (Статья о SoftICE). Иллюстрация № 1
Рисунок 1. Загрузка символьной информации в loader32.

Сначала исследуемый файл пропускается через ИДУ. Затем, в меню «File» выбирается пункт «Produce output file —> Produce MAP file» (причем имя MAP-файла должно совпадать с именем самого дизассемблируемого файла). В появившемся диалоговом окне взводим все три галочки: Segmentation information (информация о сегментах), Autogenerated names (автогенерируемые имена) и Demangle names (размагленные имена). Полученный MAP-файл скармливается утилите idasym (которую можно скачать с сайта www.idapro.com) и конвертируется в sym-формат. Под воздействием утилиты nmsym, входящей в комплект поставки soft-ice, sym-файл преобразуется в nms. Уф! Половина работы сделана — теперь, пока запускается NuMega Symbol Loader можно и передохнуть. В меню File выбираем пункт Open, открываем nms-файл и говорим Module —> Load (загрузить). Появившаяся надпись «Symbols for C: \TEMP\SIMPLE.NMS successfully loaded» говорит о том, что все прошло успешно. Теперь можно открыть и сам исполняемый файл (File —> Open и Module —> Load).

Сравните, как выглядит экран отладчика с символами и без:


Техника отладки приложений без исходных кодов (Статья о SoftICE). Иллюстрация № 2
Рисунок 2. Отладка файла без символьной информации.

Техника отладки приложений без исходных кодов (Статья о SoftICE). Иллюстрация № 3
Рисунок 3. Отладка файла с символьной информацией, автоматически сгенерированной IDA PRO.

Без символьной информации назначение функций 401234h и 401124h совсем не очевидно и на их отладку можно угробить несколько часов лучших лет своей жизни, а с символами все ясно и так. К тому же, символьные имена можно использовать в точках останова, например: «bpx _fgets» (установить точку останова на функцию чтения пароля) или «bmp aMygoodpassword» (установить точку останова на код, обращающийся к эталонному паролю).

Точки останова на API-функции

Точки останова (они же break point'ы или просто бряки) — основное оружие хакера в борьбе с защитными механизмами. Наибольшей популярностью пользуются точки останова на API-функции. Чтение содержимого окна часто (но не всегда) осуществляется API-функцией GetWindowTextA, открытие файла — CreateFileA, загрузка динамической библиотеки — LoadLibraryA и т. д. Установка точки останова на эти функции заставит отладчик «всплывать» всякий раз, когда защита пытается сделать что-то нехорошее. Этим она демаскирует свое расположение в исследуемом коде, выводя на след.

Проблема в том, что API-функций очень много и угадать, каким именно способом защита манипулирует с окном, не так-то просто. Обычно используется либо «тупой» перебор всех возможных API-функций одна за другой, либо API-шпионы, показывающие, что происходит под капотом отлаживаемой программы (см. статью «Взлом архиватора WinRAR»).

Для установки точки останова на API-функцию достаточно нажать <Ctrl-D>, и дождавшись появления отладчика на экране, написать «bpx имя_функции». В soft-ice точки останова носят глобальный характер. Если мы устанавливаем бряк на функцию CreateFileA, отладчик всплывает при каждом открытии/создании какого бы то ни было файла. Вот радость! Чтобы ограничить пыл отладчика, необходимо использовать условные точки останова. Допустим, мы хотим всплывать на «keyfile.key». Открываем MSDN и смотрим прототип функции CreateFile. Видим, что lpFileName передается в крайнем левом аргументе, а поскольку аргументы API функций заносятся в стек справа налево, указатель на имя открываемого файла окажется на вершине стека и выше него будет только адрес возврата.

Таким образом, в момент вызова CrateFile, lpFileName будет лежать по смещению 4, относительно ESP и условная точка останова будет выглядеть так: