Литвек - электронная библиотека >> Крис Касперски >> Статьи и рефераты и др. >> Техника отладки приложений без исходных кодов (Статья о SoftICE) >> страница 2
->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, дожидаемся, пока он всплывет (если не всплывает, можно дернуть мышью или щелкнуть по отлаживаемому окну), если в правом нижнем углу отладчика находится имя нашего процесса — все ок, в противном случае выходим из отладчика и ждем его всплытия опять.

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

Допустим, у нас есть окно с несколькими элементами управления (меню, флажок или кнопка) нажатия на которые мы хотим отследить (см. рис. 1). Как это сделать? Очень просто! Установить точку останова на сообщение! В Windows весь интерфейс построен на сообщениях (об этом хорошо написал Петзолд в «Программировании для Windows 95»). В частности, при нажатии на элемент управления (или изменении окна редактирования) окну посылается сообщение WM_COMMAND. Вот на него-то мы и поставим точку останова, но прежде определим дескриптор (handle) окна.


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

Это можно сделать либо любым Windows-шпионом (например, Spy++, входящим в состав Microsoft Visual Studio), либо средствами самого soft-ice, а конкретно — командой «HWND», выводящей список всех оконных элементов. Если в ответ на «HWND» soft-ice выплюнет «Unable to find a desktop window», необходимо переключить контекст командой «ADDR».

Левая колонка содержит дескрипторы оконных элементов, правая — имена модулей, которым эти элементы принадлежат. Имя модулей не всегда совпадают с именами процессов, если окно принадлежит динамической библиотеке, то soft-ice пишет имя DLL, а не основного процесса. В данном случае диалог обрабатывается библиотекой oodlrwrs, о чем можно узнать с помощью команды MOD, а фрагмент отчета выглядит так:


Handle   Class               WinProc    TID   Module

--------------------------------------------------------

010098   VMDropTargetClass   00403810   138   VMwareUser

010096   VMDropTargetClass   00403810   138   VMwareUser

010094   VMDropTargetClass   00403810   138   VMwareUser

010090   VMDropTargetClass   00403810   138   VMwareUser

01001C   NDDEAgnt            0100BC04    F8   winlogon

120124   #32770 (Dialog)     00F7BC5E   2BC   comctl32

220132   #32770 (Dialog)     00F7BC5E   2BC   oodlrwrs

1F00FE   Button              00F7BC5E   2BC   oodlrwrs

200102   Button              00F7BC5E   2BC   oodlrwrs

1B00F0   Button              00F7BC5E   2BC   oodlrwrs

320130   Static              00F7BC5E   2BC   oodlrwrs

210138   Static              77E19AA4   2BC   oodlrwrs

230116   Static              77E19AA4   2BC   oodlrwrs

24014C   Static              77E19AA4   2BC   oodlrwrs

1700F8   Static              00F7BC5E   2BC   oodlrwrs

20013A   Static              77E19AA4   2BC   oodlrwrs

1F0122   Static              77E19AA4   2BC   oodlrwrs

Листинг 1. Определение дескрипторов окон и элементов управления.


Мы видим, что три наших кнопки принадлежат диалогу #32770 с дескриптором 220132. В принципе, можно поставить точку останова и на 120124 — адрес оконной процедуры (WinProc) у них одинаков. Говорим: «BMSG 220132 WM_COMMAND» и выходим из soft-ice. Нажимаем на кнопку «Далее >» и… отладчик послушно всплывает! Остается только немного протрассировать оконную процедуру в поисках кода, обрабатывающего это нажатие.

Точки останова на данные

Чаще всего бывает так, что ключевой файл/регистрационные данные извлекаются в одном месте, а обрабатываются совсем в другом. Установив точку останова на GetWindowTextA, мы перехватим код, считывающий введенный нами регистрационный номер, но как найти то место, где он сравнивается с оригиналом? Это легко!

Открываем MSDN, смотрим прототип функции GetWindowText, ага: указатель на возвращаемую строку находится во втором аргументе слева, значит на момент вызова GetWindowTextA он будет располагаться по адресу ESP + 8 (четыре байта на hWnd и еще четыре — на