Исследование защиты программы Cool ASCII


Скриншот программы Cool ASCII

Программа Cool ASCII - простенький редактор для рисования изображений ASCII-символами, а также для преобразования графических файлов из формата BMP в цветные "картины" в виде HTML-страниц. На выходе получаются, например, такие или такие интересные результаты. Но настоящий художник должен быть голодным, так что будем избавлять эту программу от необходимости выкладывать за нее бабло.

Загружаем дистрибутив, устанавливаем, запускаем. Программа радостно сообщает, что она не зарегистрирована и поэтому будет запускаться только 10 раз, после чего понадобится сходить в кассу. После запуска посмотрим, как программа реагирует на неправильный серийный номер.


Окно регистрации программы

Отлично, теперь мы знаем нехорошую строку: "Sorry, the registration code is not correct. Please try again." Переходим к анализу исполняемого файла. Он упакован пакером ASPack, который легко снимается вручную или при помощи автоматических распаковщиков, здесь никаких проблем быть не должно. Строка о неправильной регистрации тоже лежит в открытом виде:


Нехорошая строка найдена

Загоняем распакованный файл в дизассемблер, чтобы более подробно выяснить при каких условиях она появляется.
...
CODE:004CCD81                 mov     fs:[eax], esp
CODE:004CCD84                 lea     edx, [ebp-4]
CODE:004CCD87                 mov     eax, [ebx+314h]
CODE:004CCD8D                 call    sub_47812C
CODE:004CCD92                 mov     edx, [ebp-4]
; Проверить позицию подстроки "YI-9V" в строке серийного номера
CODE:004CCD95                 mov     eax, offset aYi9v_0 ; "YI-9V"
CODE:004CCD9A                 call    sub_404F5C
CODE:004CCD9F                 test    eax, eax
; Если подстроки нет, то EAX=-1
CODE:004CCDA1                 jle     loc_4CCE2E
CODE:004CCDA7                 mov     edx, [ebp-4]
; Проверить позицию подстроки "7" в строке серийного номера
CODE:004CCDAA                 mov     eax, offset a7_0 ; "7"
CODE:004CCDAF                 call    sub_404F5C
CODE:004CCDB4                 test    eax, eax
; Если подстроки нет, то EAX=-1
CODE:004CCDB6                 jle     short loc_4CCE2E
CODE:004CCDB8                 mov     edx, ds:off_4D0008
CODE:004CCDBE                 mov     edx, [edx]
CODE:004CCDC0                 lea     eax, [ebp-8]
; Записать введенный регистрационный номер в файл
CODE:004CCDC3                 mov     ecx, offset aDataCa_id_0 ; "\\Data\\ca.id"
CODE:004CCDC8                 call    sub_404C64
CODE:004CCDCD                 mov     eax, [ebp-8]
CODE:004CCDD0                 mov     edx, [ebp-4]
CODE:004CCDD3                 call    sub_4C7C78
CODE:004CCDD8                 mov     eax, ds:off_4D02F4
CODE:004CCDDD                 mov     eax, [eax]
CODE:004CCDDF                 add     eax, 31Ch
CODE:004CCDE4                 mov     edx, offset aThanksForYou_0
; "Thanks for your register. If you have a"...
CODE:004CCDE9                 call    sub_4049AC
CODE:004CCDEE                 mov     eax, ds:off_4D02F4
CODE:004CCDF3                 mov     eax, [eax]
CODE:004CCDF5                 mov     eax, [eax+2FCh]
CODE:004CCDFB                 xor     edx, edx
CODE:004CCDFD                 call    sub_4461CC
CODE:004CCE02                 mov     eax, ds:off_4D02F4
CODE:004CCE07                 mov     eax, [eax]
CODE:004CCE09                 mov     eax, [eax+2F8h]
CODE:004CCE0F                 mov     dl, 1
CODE:004CCE11                 call    sub_4461CC
CODE:004CCE16                 mov     eax, ds:off_4D02F4
CODE:004CCE1B                 mov     eax, [eax]
CODE:004CCE1D                 mov     edx, [eax]
CODE:004CCE1F                 call    dword ptr [edx+0ECh]
CODE:004CCE25                 mov     eax, ebx
CODE:004CCE27                 call    sub_46288C
CODE:004CCE2C                 jmp     short loc_4CCE7B
CODE:004CCE2E ; -----------------------------------------------------
CODE:004CCE2E loc_4CCE2E:
CODE:004CCE2E                 mov     eax, ds:off_4D02F4
CODE:004CCE33                 mov     eax, [eax]
CODE:004CCE35                 add     eax, 31Ch
; Сообщение о неправильном серийном номере
CODE:004CCE3A                 mov     edx, offset aSorryTheRegi_0
; "Sorry, the registration code is not cor"...
CODE:004CCE3F                 call    sub_4049AC
CODE:004CCE44                 mov     eax, ds:off_4D02F4
CODE:004CCE49                 mov     eax, [eax]
CODE:004CCE4B                 mov     eax, [eax+2FCh]
...

Под отладчиком видно, что проверяется наличие в строке серийного номера двух строк: "YI-9V" и "7", причем без точного месторасположения. Попробуем ввести серийный номер, в котором они содержатся, например, что-то вроде PCLYI-9V7. Программа благодарит за регистрацию:


Сообщение об успешной регистрации

Закрываем программу, запускаем ее снова. Опа! Триальное окно на месте, счетчик запусков продолжает тикать. Значит где-то должны быть еще какие-то проверки. Вернемся к коду регистрации, посмотрим на него повнимательнее. Мы видим, что регистрационные данные записываются в файл "\Data\ca.id", для верности можно сходить в эту папку и убедиться, что мы не ошиблись. Логично предположить, что раз туда сохраняется серийный номер, то он должен где-то читаться и проверяться. Поищем это место в дизассемблере по строке "ca.id". Немного ниже по коду находится аналогичная проверка с записью серийника в файл, видимо тупо продублирована процедура регистрации с заходом из другого места. Ее мы пропускаем. А еще ниже находятся интересные манипуляции с файлом ca.id:
...
CODE:004CD238                 call    sub_403B28
CODE:004CD23D                 mov     edx, ds:off_4D0008
CODE:004CD243                 mov     edx, [edx]
CODE:004CD245                 lea     eax, [ebp-8]
CODE:004CD248                 mov     ecx, offset aDataCa_id_1 ; "\\Data\\ca.id"
CODE:004CD24D                 call    sub_404C64
CODE:004CD252                 mov     eax, [ebp-8]
CODE:004CD255                 lea     edx, [ebp-4]
CODE:004CD258                 call    sub_4C7D14
CODE:004CD25D                 mov     edx, [ebp-4]
; Проверить позицию подстроки "A" в строке серийного номера
CODE:004CD260                 mov     eax, offset aA  ; "A"
CODE:004CD265                 call    sub_404F5C
CODE:004CD26A                 test    eax, eax
; Если подстроки нет, то EAX=-1
CODE:004CD26C                 jle     short loc_4CD290
CODE:004CD26E                 mov     edx, [ebp-4]
; Проверить позицию подстроки "9" в строке серийного номера
CODE:004CD271                 mov     eax, offset a9  ; "9"
CODE:004CD276                 call    sub_404F5C
CODE:004CD27B                 test    eax, eax
; Если подстроки нет, то EAX=-1
CODE:004CD27D                 jle     short loc_4CD290
CODE:004CD27F                 mov     edx, [ebp-4]
; Проверить позицию подстроки "CY" в строке серийного номера
CODE:004CD282                 mov     eax, offset aCy ; "CY"
CODE:004CD287                 call    sub_404F5C
CODE:004CD28C                 test    eax, eax
; Если подстроки нет, то EAX=-1
CODE:004CD28E                 jg      short loc_4CD29F
CODE:004CD290 loc_4CD290:
CODE:004CD290                 mov     eax, ds:off_4D037C
CODE:004CD295                 mov     eax, [eax]
CODE:004CD297                 mov     edx, [eax]
CODE:004CD299                 call    dword ptr [edx+0ECh]
CODE:004CD29F loc_4CD29F:
CODE:004CD29F                 xor     eax, eax
CODE:004CD2A1                 pop     edx
CODE:004CD2A2                 pop     ecx
CODE:004CD2A3                 pop     ecx
CODE:004CD2A4                 mov     fs:[eax], edx
CODE:004CD2A7                 push    offset loc_4CD2C1
CODE:004CD2AC loc_4CD2AC:
CODE:004CD2AC                 lea     eax, [ebp-8]
CODE:004CD2AF                 mov     edx, 2
CODE:004CD2B4                 call    sub_40497C
CODE:004CD2B9
...

Под отладчиком картина тоже проясняется. Из файла "\Data\ca.id" читается серийный номер, но уже выполняются другие проверки: наличие в нем строк "A", "9" и "CY", причем опять же без какого-то конкретного расположения их в строке. Дополним ими серийный номер до строки PCLYI-9V7ACY (подстрока "9" уже есть) и попробуем снова зарегистрировать программу:


Программа успешно зарегистрирована

На этот раз триальное окно не появляется, значит регистрация считается полностью валидной. Осталось посмотреть, где программа хранит свой триальный счетчик. Для этого найдем место, где формируется строка с указанием количества оставшихся запусков:
...
CODE:004CCAB4                 mov     eax, off_438EEC
CODE:004CCAB9                 call    sub_438FEC
CODE:004CCABE                 mov     esi, eax
CODE:004CCAC0                 mov     edx, 80000002h
CODE:004CCAC5                 mov     eax, esi
CODE:004CCAC7                 call    sub_43908C
CODE:004CCACC                 mov     cl, 1
; Открыть ветку реестра HKLM\SOFTWARE\Microsoft\Direcs3D\
; "Direcs3D" - это не опечатка, именно в этой ветке прячется триальный счетчик
CODE:004CCACE                 mov     edx, offset aSoftwareMicros
; "\\SOFTWARE\\Microsoft\\Direcs3D\\"
CODE:004CCAD3                 mov     eax, esi
CODE:004CCAD5                 call    sub_4390F0
CODE:004CCADA                 test    al, al
CODE:004CCADC                 jz      loc_4CCC79
CODE:004CCAE2                 mov     edx, offset aDirectdraw ; "DirectDraw"
CODE:004CCAE7                 mov     eax, esi
CODE:004CCAE9                 call    sub_43940C
CODE:004CCAEE                 test    al, al
CODE:004CCAF0                 jnz     short loc_4CCB2B
CODE:004CCAF2                 call    sub_40B358
CODE:004CCAF7                 add     esp, 0FFFFFFF8h
CODE:004CCAFA                 fstp    qword ptr [esp]
CODE:004CCAFD                 wait
CODE:004CCAFE                 lea     eax, [ebp-1Ch]
CODE:004CCB01                 call    sub_40BF6C
CODE:004CCB06                 mov     eax, [ebp-1Ch]
CODE:004CCB09                 lea     edx, [ebp-18h]
CODE:004CCB0C                 call    sub_4CC6B8
CODE:004CCB11                 lea     eax, [ebp-18h]
CODE:004CCB14                 lea     edx, [ebp-8]
CODE:004CCB17                 call    sub_4CC72C
CODE:004CCB1C                 mov     ecx, [ebp-8]
CODE:004CCB1F                 mov     edx, offset aDirectdraw ; "DirectDraw"
CODE:004CCB24                 mov     eax, esi
CODE:004CCB26                 call    sub_43928C
CODE:004CCB2B loc_4CCB2B:
CODE:004CCB2B                 mov     edx, offset aDirectinput ; "DirectInput"
CODE:004CCB30                 mov     eax, esi
CODE:004CCB32                 call    sub_43940C
CODE:004CCB37                 test    al, al
CODE:004CCB39                 jnz     short loc_4CCB67
CODE:004CCB3B                 lea     edx, [ebp-18h]
CODE:004CCB3E                 mov     eax, offset dword_4CCD08
CODE:004CCB43                 call    sub_4CC6B8
CODE:004CCB48                 lea     eax, [ebp-18h]
CODE:004CCB4B                 lea     edx, [ebp-20h]
CODE:004CCB4E                 call    sub_4CC72C
CODE:004CCB53                 mov     ecx, [ebp-20h]
CODE:004CCB56                 mov     edx, offset aDirectinput ; "DirectInput"
CODE:004CCB5B                 mov     eax, esi
CODE:004CCB5D                 call    sub_43928C
CODE:004CCB62                 jmp     loc_4CCC79
CODE:004CCB67 ; --------------------------------------------------
CODE:004CCB67 loc_4CCB67:
CODE:004CCB67                 lea     ecx, [ebp-4]
CODE:004CCB6A                 mov     edx, offset aDirectinput ; "DirectInput"
CODE:004CCB6F                 mov     eax, esi
CODE:004CCB71                 call    sub_4392B8
CODE:004CCB76                 mov     ebx, 1
CODE:004CCB7B loc_4CCB7B:
CODE:004CCB7B                 lea     edx, [ebp-28h]
CODE:004CCB7E                 mov     eax, ebx
CODE:004CCB80                 call    sub_40940C
CODE:004CCB85                 lea     eax, [ebp-28h]
CODE:004CCB88                 push    eax
CODE:004CCB89                 lea     edx, [ebp-2Ch]
CODE:004CCB8C                 mov     eax, ebx
CODE:004CCB8E                 call    sub_40940C
CODE:004CCB93                 mov     edx, [ebp-2Ch]
CODE:004CCB96                 pop     eax
CODE:004CCB97                 call    sub_404C20
CODE:004CCB9C                 mov     eax, [ebp-28h]
CODE:004CCB9F                 lea     edx, [ebp-18h]
CODE:004CCBA2                 call    sub_4CC6B8
CODE:004CCBA7                 lea     eax, [ebp-18h]
CODE:004CCBAA                 lea     edx, [ebp-24h]
CODE:004CCBAD                 call    sub_4CC72C
CODE:004CCBB2                 mov     edx, [ebp-24h]
CODE:004CCBB5                 mov     eax, [ebp-4]
CODE:004CCBB8                 call    sub_404D64
CODE:004CCBBD                 jz      short loc_4CCBC5
CODE:004CCBBF                 inc     ebx
CODE:004CCBC0                 cmp     ebx, 0Ah
CODE:004CCBC3                 jnz     short loc_4CCB7B
CODE:004CCBC5 loc_4CCBC5:
CODE:004CCBC5                 cmp     ebx, 0Ah
CODE:004CCBC8                 jnz     short loc_4CCBF6
CODE:004CCBCA                 mov     dword ptr [edi+31Ch], 1
CODE:004CCBD4                 mov     eax, [edi+304h]
CODE:004CCBDA                 xor     edx, edx
CODE:004CCBDC                 mov     ecx, [eax]
CODE:004CCBDE                 call    dword ptr [ecx+64h]
CODE:004CCBE1                 mov     eax, [edi+2FCh]
CODE:004CCBE7                 mov     edx, offset aYouHaveUsed10T
; "You have used 10 times."
CODE:004CCBEC                 call    sub_4462DC
CODE:004CCBF1                 jmp     loc_4CCC79
CODE:004CCBF6 ; -----------------------------------------------------
CODE:004CCBF6 loc_4CCBF6:
CODE:004CCBF6                 xor     eax, eax
CODE:004CCBF8                 mov     [edi+31Ch], eax
CODE:004CCBFE                 push    offset aYouHaveUsed ; "You have used "
CODE:004CCC03                 lea     edx, [ebp-34h]
CODE:004CCC06                 lea     eax, [ebx+1]
CODE:004CCC09                 call    sub_40940C
CODE:004CCC0E                 push    dword ptr [ebp-34h]
CODE:004CCC11                 push    offset aTimes_  ; " times."
CODE:004CCC16                 lea     eax, [ebp-30h]
CODE:004CCC19                 mov     edx, 3
CODE:004CCC1E                 call    sub_404CD8
CODE:004CCC23                 mov     edx, [ebp-30h]
...

Оригинальностью аффтар не страдает, поэтому счетчик количества запусков прячется в ветке HKLM\SOFTWARE\Microsoft\Direcs3D\ в ключах с именами DirectDraw и DirectInput. Если периодически удалять эту ветку из реестра, то программой можно будет пользоваться и без регистрации в течение неограниченного времени. Но мы уже разобрали алгоритм генерации серийного номера, так что можете написать рабочий кейген самостоятельно.
Теги:
защита, взлом
Добавлено: 19 Сентября 2013 12:13:06 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...