Техника отладки приложений без исходных кодов (Статья о SoftICE) [Крис Касперски] (fb2) читать постранично, страница - 2


 [Настройки текста]  [Cбросить фильтры]

всегда) осуществляется 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 и условная точка останова будет выглядеть так: «bpx CreateFileA if (*(esp ->4) == 'keyf')». Имя файла, заключенное в кавычки, автоматически преобразуется отладчиком в 32-разрядную константу и потому его длина не должна превышать 4-х байт, причем отладчик чувствителен к регистру ('keyf' и 'Keyf' для него не одно и тоже), а вот файловая система — нет. В большинстве случаев частичного сравнения имени оказывается вполне достаточно. Если же нет, можно прибегнуть к оператору AND и сравнивать несколько 4-битных подстрок за раз. Синтаксис условных точек останова подробно описан в документации на soft-ice, так что не будем на этом останавливаться.

Многие защиты противостоят точкам останова, например, начиная выполнение API-функции не с первого байта, и в таких случаях приходится прибегать к установке бряков на native-API — своеобразному фундаменту операционной системы, ниже которого находятся только порты ввода/вывода и драйвера. Описание native-API функций можно найти в Interrupt List'е Ralf'а Brown'а или «The Undocumented Functions Microsoft Windows NT/2000» от Tomas'а Nowak'а. В частности, NtCreatrFile используется для создания/открытия файлов.

Отладчик OllyDbg поддерживает намного более мощный механизм условных точек, позволяющий отслеживать практически любые ситуации. Например, EAX == «mypswd» — всплывать, когда регистр EAX указывает на строку с паролем/серийным номером, который мы ввели при регистрации. Это универсальный способ взлома, подходящий практически ко всем защитам. Каким бы образом программа не извлекала содержимое окна редактирования, в какой-то момент она неизбежно засунет указатель в регистр. Вот тут-то мы и всплывем! Процедура проверки соответствия пароля будет где-то неподалеку. Конечно, этим регистром не обязательно должен быть EAX. Вполне вероятно, что компилятор задействует EBX, ESI или что-то еще. Документация на OllyDbg заявляет о поддержке выражения R32 == «mypswd», где R32 — любой регистр общего назначения, однако в текущих версиях отладчика эта конструкция не работает и все регистры приходится перебирать вручную (благо, можно написать свой плагин, автоматизирующий этот процесс).

Помимо точек останова на API, можно брякать библиотечные функции. В приложениях, написанных на DELPHI/BUILDER/MFC/Visual BASIC прямые вызовы API используются редко. И хотя никакое дело без API-функций, конечно же, не обходится, их анализ мало что дает, особенно если используется динамический обмен данных с окном (DDX) и другие навороченные технологии, обмазывающие API-функциями несколькими мегабайтами кривого кода. Это же сдохнуть можно! Но мы не будем! Библиотечные функции легко опознаются ИДОЙ и брякаются как обычные API-функции только с той разницей, что точка останова носит локальный характер, воздействующий только на отлаживаемое приложение. А это значит, что после нажатия <Ctrl-D> мы должны переключить контекст управления, чтобы попасть в адресное пространство отлаживаемого приложения. Это осуществляется либо командой «ADDR имя_процесса», либо установкой точки останова на любую API-функцию, вызываемую отлаживаемым приложением. Например, SendMessageA. Жмем, <Ctrl-D>, пишем «bpx MeggsageBoxA», выходим из sof-ice, дожидаемся, пока он всплывет (если не всплывает, можно дернуть мышью или щелкнуть по отлаживаемому окну), если в правом нижнем углу отладчика находится имя нашего процесса — все ок, в противном случае выходим из отладчика и ждем его всплытия опять.

Точки останова на сообщения

Допустим, у нас есть окно с несколькими элементами управления (меню, флажок или кнопка) нажатия на которые мы хотим отследить