C2 jnz loc_4011c0

Найти в листинге дизассемблера его можно двояко — среди перекрестных ссылок на RegCreateKeyExA:

0040200С RegCreateKeyExA dd ?

или по ссылке на строку aSoftwareCrackO;

00403088 aSoftwareCrackO db 'SOFTWARECRACK05',0;DATAXREF:sub_401040+70To

Обратим внимание на строку Ох04010С2. Вопреки ожиданиям, изменять этот условный переход ни в коем случае не надо. Заглянув в SDK, можно узнать, что RegCreateKeyExA возвращает ненулевое значение в случае фатальной ошибки. А результат завершения операции передается через локальную переменную [esp+0x4]. Если раздел был успешно создан, то возвращается единица, в против­ном случае раздел уже существует.

Тогда становится понятен смысл следующего фрагмента:

004010C8 cmp dword ptr [esp+4],1

004010CD jnz short loc_401116

Чтобы защита каждый запуск считала первым, достаточно удалить условный переход jnz. Его можно заменить, например, на две однобайтовые операции пор. Попробуем сделать это сейчас. Переключим дизассемблер в режим hex-дампа и запишем, например, последовательность '83 7С 24 04 01 75 47'. Найдем ее в любом шестнадцатиричном редакторе и заменим на '83 7С 24 04 01 75 47'.

Удостоверимся, что защита больше не функционирует. Разумеется, это не единственно возможный подход. Защитный механизм можно нейтрализовать десятками вариантов. Не будем их здесь рассматривать и предоставим читателю найти их самостоятельно.

Рассмотрим другой пример реализации подобной защиты crack06. Использо­вание монитора реестра нам ничего не дает. Быть может, программа сохранила дату в каком-нибудь файле? Обратимся к файловому монитору. Рассмотрим полученный протокол:

3495 Crack06 Open "С :WINDOWSSYSTEMCRACKOe .DAT" CREATENEH

3498 Crack06 Write "C:WINDOWSSYSTEMCRACK06.DAT" 0ffset:0 Length:4

3499 Crack06 Close "C:MIHDOWSSY£TEMCRACK06.DAT"

Из него видно, что приложение создало новый файл в каталоге WIN-DOWSSYSTEM. В нем легко затеряться среди сотен файлов, часто неясным образом созданных и неизвестно кому принадлежащих. В данном примере исполь­зовалось "говорящее" за себя имя, однако авторы защит склонны к бессмыслен­ным комбинациям типа syswdg.dll. Это признак низкой культуры программирова­ния, не могущей служить образцом для подражания.

Теперь не стоит труда найти код, оперирующий с этим файлом. Нейтрализа­ция защиты выглядит аналогично вышеизложенной и не должна вызвать затруд­нений у читателя.

Мы рассмотрели две простых и очевидных реализации защиты, основанной на ограничении времени с момента первого запуска. Большинство подобных защит построено именно так и не вызывает сложностей со взломом. Печально. Можно ли как-нибудь усовершенствовать реализацию? И да и нет. Да, потому что человеческая хитрость разума неисчерпаема и всегда можно придумать новый головоломный прием. Нет, потому что для любой головоломки можно найти решение. Это только вопрос времени и квалификации взломщика.

Рассмотрим несколько реализаций защитных механизмов, которые не так очевидны) как вышеописанные. Например, xformat 2.4 Криса Касперски сохранял месяц первого запуска в поле сотых долей секунды времени создания com­mand.corn. Антивирусы на это (как ни странно) не реагировали. Такое решение, очевидно, не слишком повышало стойкость защиты и не могло служить примером культурного программирования, но от неквалифицированных пользователей, воо­руженных дисковыми сканерами, защищало надежно.

Некоторые защиты активно используют для этой цели незадействованные поля CMOS. Это очень примитивный способ, имеющий ряд серьезных ограниче­ний. Защита слишком заметна и легко перехватывается. Действительно, доста­точно перехватить запись в порт 0х70. чтобы обнаружить защиту. Однако операционная система (наподобие Windows NT) не позволит напрямую обращать­ся к портам непривилегированным пользователям. Кроме того, CMOS не видна по сети. Наконец, зарезервированные поля могут быть использованы в новых версиях, что приведет к конфликтам и, возможно, к серьезным последствиям.

В более выгодном положении находятся защиты, работающие до какого-то определенного времени. Это более простой в реализации, но менее честный по отношению к пользователям подход. Однако именно так была защищена бета-вер­сия Windows 98, которая работала до определенного момента, а затем удаляла себя из загрузочного сектора.

На самом деле несложно было найти по процедуре системного времени защитный механизм. Однако к системным часам существует множество способов доступа. Чтобы выяснить, какой именно использует приложение, необходимо ознакомиться с таблицей импорта. Так, например, crack07.exe импортирует только одну функцию, непосредственно связанную с опросом времени — GetTick-Count.

.text:00401109 call j_?GetTickCount@CTime(?@SG?AViexz ;

Сейчас в eax адрес двойного слова, содержащего упакованную дату и время.

.text :0040ilOE mov edx, [eax]

Загружаем упакованную дату/время в edx.

.text: 00401110 mov edi, ds:printf

.text: 00401116 sar edx, OFh

Избавляемся от часов, минут, секунд.

.text:00401119 mov esi, 7000h

Упакованная дата окончания использования.

.text :0040111E sub esi, edx

Вычисляем, сколько осталось времени для использования приложения.

. text 100401128 test esi,esi

.text:0040112D pop esi

.text:0040112Ejle short loc_0_401140

Срок истек (нуль или отрицательное число).

.text; 00401130 push offset aworking____

Ветка нормального исполнения программы.

.text: 00401135 call edi

.text: 004 01137 add esp, 4

. text: 0040113A mov eax, ebx

. text: 00401130 pop edi

. text: 0040113D pop ebx

.text: 00 40113E pop ecx

.text: 0040113F retn

Я не буду подробно останавливаться на механизме нейтрализации защиты, так как данный пример в этом отношении ничем не отличается от рассмотренных выше.

Старые приложения, выполняемые в среде MS-DOS не могут быть взломаны подобным образом, так как они не импортируют никаких функций и найти защитный механизм в дизассемблере может быть непростой задачей. Рассмотрим, например, crack07.exe, скомпилированный Turbo-Pascal под. MS-DOS. IDA 3.8 уверенно распознает стандартные функции, среди которых нетрудно найти Get-Date, но что делать, если она недоступна?

На самом деле приложения под MS-DOS могут получить системную дату двумя способами — функцией операционной системы f.Ox2A (int 0х21) или BIOS f.04 (int OxIA). Практически не встречается считывание счетчика дней, прошед­ших с момента 10/1/86 (f.OAh int OxIA) или непосредственным чтением регист­ров CMOS. Перехватить функции указанных прерываний позволит практически любой отладчик, например Soft-Ice.

Поскольку сегодня приложения под MS-DOS медленно, но верно вымирают, мы не будем останавливаться на этом подробно.

В заключение замечу, что иногда встречаются достаточно оригинальные защиты, не опрашивающие системное время, а сканирующие диск в поисках последнего созданного файла, дату которого и принимают за текущую.

Это надежно защищает от "перевода стрелок назад", однако крайне ненадеж­но как метод. Очень часто попадаются файлы с неверным временем создания (например, двухтысячнйм годом). Они могут привести к ложному срабатыванию защиты, что никак не вызовет восторга у пользователя. С другой стороны, перехватить чтение даты создания (последней модификации) файла ничуть не сложнее, чем перехватить опрос системного времени. Механизмы обеих атак совершенно идентичны.