SetTimer

18C Is Iconic

195 KillTimer

B7 EnableWindow

146 GetSystemMetrics

19E LoadIconA

Попробуем найти код, который вызывает SetTimer, для чего установим на последнюю точку останова:

015F:004013CD MOV ЕАХ, [ESI+20]

015F:004013DO PUSH 00

015F:004013D2 PUSH 00002710

015F:004013D7 PUSH 01

015F: 004013D9 PUSH EAX

015F:004013DA CALL [USER32! SetTimer]

015F:004013EO MOV ECX, [ESP+OC]

015F:004013E4 MOV DWORD PTR [ESI+60],00000000

Очевидно, что, удалив CALL tUSER32!SetTimer] вместе с заносимыми в стек параметрами, можно полностью парализовать защиту. Ветка вывода диалога попросту никогда нс получит сообщения WM_TIMER и. следовательно, управле­ния. Анализ защиты можно считать завершенным. Как видим, сушестнует не один путь ее взлома. И любой способ ничем не хуже другого.

Рассмотрим еще один похожий пример file://CD:SOURCEVCCRACKOC RELEASEcrackOC.exe. Первым бросающимся в глаза отличием является NAG-Screen, всплывающий при первом запуске программы. Очевидно, что его появле­ние связано не с таймером, а с процедурой инициализации приложения. Другое (более существенное) отличие можно увидеть, если запустить spyxx или изучить таблицу импорта. Нет сообщения WM_TIMER, и нет в импорте процедуры SetTiiner. Очевидно, приложение ухитряется с высокой периодичностью вызывать nag-screen не используя таймера. Самый очевидный способ это сделать — постоянно опрашивать текущее время и через некоторые промежутки передавать управление защите. Разумеется, организовать подобное можно либо непосредст­венно в цикле выборки сообщений, либо в отдельном потоке. По опыту могу сказать, что разработчики защит чаще всего предпочитают последнее. В чем можно убедиться, запустив 'Process Viewer Application', который входит в поставку MS VC.

Приложение имеет два потока. Вполне возможно, что один из них целиком принадлежит защите и не делает ничего кроме постоянного опроса времени. Для подтверждения этого нам нужно изучить код потока и проанализировать его. Установим точку останова на CreateThread. Разумеется, приложение не вызывает его непосредственно, а действует через MFC. Но сейчас это для нас не важно. Вспомним прототип функции CrealeThread или обратимся к SDK:

HANDLE CREATEThread (

LPSECURITY_ATTRIBUTES lptthreadAttributes, //pointer ti security attributes

DWORD dwstackSize, //initial thread stack size

LPTHREAD_START_ROUTINE lpStartAddress, //pointer to thread function

LPVOID lpparameter, //argument for new thread

DWORD dwcreationflags, //creation flags

LPDWORD lpthreadId //pointer to receive thread ID );

Таким образом, адрес процедуры потока можно узнать с помощью команды D ss:esp+OC и последующего дизассемблирования. Разумеется, это будет _beginth-readex модуля MSVCRT. Однако, немного потрассировав последнюю, можно добраться и до кода приложения. Здесь не помешает небольшой опыт работы с MFC и ее исследования. MicroSoft предоставляет отладочные версии и даже исходные тексты, поэтому архитектуру MFC изучить нетрудно, но очень и очень полезно. То же самое можно отнести и к другим компиляторам и библиотекам.

Так или иначе, но найти рабочий код приложения в потоке будет нетрудно. Изучать его непосредственно в отладчике затруднительно и неудобно. Дизассем­блер в этом отношении окажется более подходящим. Рассмотрим результат его работы.

. text: 00401740 push есх

ЕСХ указывает на экземпляр класса, производного от CWinThread.

.text: 00401741 mov ean, [ecx+6Ch]

.text: 00401744 push esi

.text: 00401745 test eax, eax

Очевидно, что [ecx+6Ch] какой-то флаг. Но какой? На данном этапе это еще не ясно.

.text 100401747 push edi

.text:00401748 jz short loc_0_401750

Если этот флаг равен нулю, происходит выход из потока. Он может быть связан или с какой-то ошибкой, или с регистрацией. Так или иначе, если удалить условный переход JZ, поток никогда не получит управления и NAG-SCREEN не появится. Однако, это не будет полноценным взломом, так как при первом запуске программы по-прежнему будет появляться диалог.

.text:0040174A pop edi

.text:0040174B xor eax, eax

.text:0040174D pop esi

.text:0040174E pop ecx

.text:0040174F retn

Остальное тело потока здесь не приводится для экономии места. Его содер­жимое не представляет ничего интересного. Поток — "стрелочник". Ему прика­зали — он выполнил, т.е. вывел диалог. Да, конечно, создание диалога нетрудно и блокировать, но это не даст ответа на вопрос: кто же за всем этим стоит? Убедимся, что этот поток всецело подчинен защите, т.е. ни для чего другого больше не служит.

Собственно говоря, непосредственно к защитному механизму могла относить­ся только переменная [ecx+6Ch], весь остальной код потока полностью автономен и ничем не управляется.

Необходимо найти код, манипулирующий этой переменной. Очень вероятно, что он и будет ядром защитного механизма, который мы пытаемся снять. Однако это потребует анализа, возможно, непростого и утомительного. Не лучше ли просто блокировать вызов диалога, невзирая на то что защита по-прежнему работает, — ведь досадить пользователю она уже не может? Чем плох этот метод? Так (или почти так) думает большинство кракеров. Может быть думает все-таки по другому, но ломает именно так. И в этом трудно их винить, так как рынок требует самых быстрых и дешевых решений. Красиво это решение или нет. заказчика ни в малейшей степени не интересует. Этим и вызвана деградация технической культуры. В наши дни эти слова уже звучат как метафора. Действи­тельно, есть техника, есть культура — а что такое техническая культура?

Сегодня программирование уже перестало быть искусством, и только отдель­ные энтузиасты-одиночки все еще считают его увлекательным хобби, на которое не жалко тратить все свободное время. F-сли вы принадлежите к их числу, то исследование защиты несомненно стоит продолжать, в противном случае можно удалить вызовы AfxMessageBox, чтобы NAG-SCREEN не появлялся ни при запуске, ни в дальнейшем.

Задумаемся над следующим неочевидным моментом. Если защитный меха­низм манипулирует каким-то флагом, вполне естественно, что при каком-то условии программа считается зарегистрированной и эта переменная принимает единичное значение, блокирующее все остальные ветки защиты. (А их, забегая вперед, целых три). Но какое же условие может проверять защита? Никакой явной регистрации в программе не предусмотрено. Из источников ввода остаются только командная строка, ключевой файл и реестр. Первое — давно забытый пережиток MS-DOS и в Windows массового применения не нашло. А вот реестр очень даже вероятная кандидатура.

Читатель, вероятно, уже запускает монитор. Посмотрим, что нам даст его применение: 43 CrackOc OpenKey HKCUSOFTWARECRACKOCRegIt NOTFOUND

В самом деле, защита пыталась открыть явно относящийся к регистрации раздел. Попробуем его создать b запустим программу еще раз.

О чудо! Программа признала нас зарегистрированным пользователем! Исчезли NAG-SCREEN-ы. изменилась строка с "Ждите..." на "больше не появится...". Вот что значит качественный взлом!

Конечно, реальные защиты не только проверяют существование раздела, но и проверяют его значение. Здесь же для упрощения этого не делалось. Работа с реестром уже была рассмотрена выше и никаких трудностей не представляет. Более того, даже облегчает нам распространение "кряков" к программе. Доста­точно только экспортировать раздел CRACKOC в файл: запустив его. пользователь импортирует раздел в свой реестр и тем самым регистрирует приложение. Надо ли говорить, что распространение подобного файла никак не противоречит российскому законодательству, а поэтому ограничено быть не может.

Вообще же NAG-SCREEN-ы даже трудно отнести к защитам. Они принципи­ально не могут быть сложно защищены. Все, что нужно, — это удалить одну или несколько процедур, даже не вникая в их алгоритм. Можно, конечно, противодей­ствовать отладке и дизассемблированию, но сегодня совершенство и мощь инструментария хакера позволяют противодействовать любому антиотладочному коду. Интерактивный дизассемблер IDA вообще невозможно обмануть именно в силу его интерактивности, так как предполагается его тесное взаимодействие с человеком. Человека же, в отличие от автоматики, одурачить очень трудно.