Ограничение числа запусков

Ограничение числа запусков имеет много общего с защитой по времени с момента первого запуска. Однако теперь вместо начального времени необходимо где-то сохранить счетчик, инкрементирующийся (декрементирующийся) при каж­дом запуске приложения.

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

Постоянное изменение счетчика позволяет, сравнив протоколы разных запу­сков, найти различия, которых обычно бывает немного. Один из них и будет искомым счетчиком.

Заметим, что защита может использовать очень сложный н неочевидный формат. Продемонстрируем это на примере crack09. Найти пару созданных им счетчиков будет нетрудно. Но вот формат представления данных для нас будет загадкой. Кажется, что оба счетчика меняются произвольным образом, то увели­чиваясь, то уменьшаясь при каждой итерации. Нас даже берет сомнение: а счетчики ли это вообще? Может быть, какие-то другие служебные данные?

Выяснить истину нам поможет отладчик или дизассемблер. В сегменте данных найдем строку:

.data:00403050 aCountI db 'Countl',0 : DATAXREF: Jiain+CB

.data:00403050 ; _liaiin.l22o ...

Перекрестные ссылки помогут нам выяснить, какой код читает или устанав­ливает значение этого раздела реестра. Я не буду приводить здесь его целиком, отмечу только ключевой фрагмент:

.text:0040120F mov еах, [esp+5Ch+var_54] ; Count2

.text:00401213 mov edx, [esp+SCh+var 4C] , Count1

.text:00401217 xor eax,edx

Расшифровываем значение счетчика. Count 1 на самом деле ключ, а Count2 — зашифрованный счетчик. Такой прием позволит надежно скрыть защитный механизм от неквалифицированного пользователя, вооруженного редактором реестра.

.text '.00401219 dec eax

Уменьшаем значенне счетчика на единицу.

.text:00401220 test еах, eax

.text:0040122F jz short loc_0_401296

Очередной промах компилятора. На самом деле инструкция test еах,еах не нужна, так как флаг нуля устанавливается инструкцией dec еах. Как нетрудно догадаться, это и есть тот самый условный переход, который по истечении отведенных запусков приложения прекращает его работу. В качестве тренировки читателю рекомендуется самостоятельно модифицировать его так, чтобы програм­ма работала вечно. Разумеется, можно поступить иначе и удалить инструкцию dec. — кому как нравится.

.text:00401231 push О

.text: 00401233 call ds:time

.text :00401239 push еах

,text:0040123A call ds:sran

.text: 00401240 add esp, В

.text: 00401243 call ds:rand

Генерируем случайное число — меняем ключ шифрования после каждого запуска.

.text :00401249 mov edi, [esp+5Ch+var_54] ; Key

.text:0040124D mov ecx, [esp+5Ch+var_50} ; Real Count

.text:0040125B xor edi, еах

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

Res=4;

RegQueryValueEx (hKey, "Counti", 0, &TYPE, (LPBYTE) sCountI, Sres) ;

RegQueryValueEx (hKey, "Count2", 0, 6TYPE, tLPBYTE) &Count2, &res) ;

Count 2 = Count 2 ^ Count. 1;

Count2--;

printf ("Count %x n", Count 2) ;

if (!Count2) return 0;

srand(unsigned)time (NULL ) );

Counti = (unsigned) rand I ) ;

Count 2 = Count2 ^ Count1;

RegsetValueEx(hKey,"Counti",0,REG_DWORD,(CONST BYTE *) &Countl,4); RegSetVaLueEx(hKeу,"Count2"fO,REG_DWORD,(CONST BYTE *) SCount2,4);

Однако программисты в своем большинстве достаточно ленивы и заняты, чтобы активно использовать подобные приемы. Чаще всего счетчики записаны в реестре "AS IS" и легко могут быть изменены редактором реестра на любое другое значение, ограниченное совестью взломщика.

На этом я заканчиваю обзор защит с ограниченным временем (числом запусков) использования. Они достаточно просты и не должны вызывать трудно­стей при взломе.

Использовать их могут только беспечные или низкоквалифицированные раз­работчики. Стойкость таких защит очень низка и никак не оправдывает возложен­ных на них надежд.