Blog. Just Blog

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

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Темная сторона Силы | Автор: ManHunter
Скриншот программы Cool ASCII
Скриншот программы Cool ASCII

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

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

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

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

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

Загоняем распакованный файл в дизассемблер, чтобы более подробно выяснить при каких условиях она появляется.
  1. ...
  2. CODE:004CCD81                 mov     fs:[eax], esp
  3. CODE:004CCD84                 lea     edx, [ebp-4]
  4. CODE:004CCD87                 mov     eax, [ebx+314h]
  5. CODE:004CCD8D                 call    sub_47812C
  6. CODE:004CCD92                 mov     edx, [ebp-4]
  7. ; Проверить позицию подстроки "YI-9V" в строке серийного номера
  8. CODE:004CCD95                 mov     eax, offset aYi9v_0 ; "YI-9V"
  9. CODE:004CCD9A                 call    sub_404F5C
  10. CODE:004CCD9F                 test    eax, eax
  11. ; Если подстроки нет, то EAX=-1
  12. CODE:004CCDA1                 jle     loc_4CCE2E
  13. CODE:004CCDA7                 mov     edx, [ebp-4]
  14. ; Проверить позицию подстроки "7" в строке серийного номера
  15. CODE:004CCDAA                 mov     eax, offset a7_0 ; "7"
  16. CODE:004CCDAF                 call    sub_404F5C
  17. CODE:004CCDB4                 test    eax, eax
  18. ; Если подстроки нет, то EAX=-1
  19. CODE:004CCDB6                 jle     short loc_4CCE2E
  20. CODE:004CCDB8                 mov     edx, ds:off_4D0008
  21. CODE:004CCDBE                 mov     edx, [edx]
  22. CODE:004CCDC0                 lea     eax, [ebp-8]
  23. ; Записать введенный регистрационный номер в файл
  24. CODE:004CCDC3                 mov     ecx, offset aDataCa_id_0 ; "\\Data\\ca.id"
  25. CODE:004CCDC8                 call    sub_404C64
  26. CODE:004CCDCD                 mov     eax, [ebp-8]
  27. CODE:004CCDD0                 mov     edx, [ebp-4]
  28. CODE:004CCDD3                 call    sub_4C7C78
  29. CODE:004CCDD8                 mov     eax, ds:off_4D02F4
  30. CODE:004CCDDD                 mov     eax, [eax]
  31. CODE:004CCDDF                 add     eax, 31Ch
  32. CODE:004CCDE4                 mov     edx, offset aThanksForYou_0
  33. ; "Thanks for your register. If you have a"...
  34. CODE:004CCDE9                 call    sub_4049AC
  35. CODE:004CCDEE                 mov     eax, ds:off_4D02F4
  36. CODE:004CCDF3                 mov     eax, [eax]
  37. CODE:004CCDF5                 mov     eax, [eax+2FCh]
  38. CODE:004CCDFB                 xor     edx, edx
  39. CODE:004CCDFD                 call    sub_4461CC
  40. CODE:004CCE02                 mov     eax, ds:off_4D02F4
  41. CODE:004CCE07                 mov     eax, [eax]
  42. CODE:004CCE09                 mov     eax, [eax+2F8h]
  43. CODE:004CCE0F                 mov     dl, 1
  44. CODE:004CCE11                 call    sub_4461CC
  45. CODE:004CCE16                 mov     eax, ds:off_4D02F4
  46. CODE:004CCE1B                 mov     eax, [eax]
  47. CODE:004CCE1D                 mov     edx, [eax]
  48. CODE:004CCE1F                 call    dword ptr [edx+0ECh]
  49. CODE:004CCE25                 mov     eax, ebx
  50. CODE:004CCE27                 call    sub_46288C
  51. CODE:004CCE2C                 jmp     short loc_4CCE7B
  52. CODE:004CCE2E ; -----------------------------------------------------
  53. CODE:004CCE2E loc_4CCE2E:
  54. CODE:004CCE2E                 mov     eax, ds:off_4D02F4
  55. CODE:004CCE33                 mov     eax, [eax]
  56. CODE:004CCE35                 add     eax, 31Ch
  57. ; Сообщение о неправильном серийном номере
  58. CODE:004CCE3A                 mov     edx, offset aSorryTheRegi_0
  59. ; "Sorry, the registration code is not cor"...
  60. CODE:004CCE3F                 call    sub_4049AC
  61. CODE:004CCE44                 mov     eax, ds:off_4D02F4
  62. CODE:004CCE49                 mov     eax, [eax]
  63. CODE:004CCE4B                 mov     eax, [eax+2FCh]
  64. ...
Под отладчиком видно, что проверяется наличие в строке серийного номера двух строк: "YI-9V" и "7", причем без точного месторасположения. Попробуем ввести серийный номер, в котором они содержатся, например, что-то вроде PCLYI-9V7. Программа благодарит за регистрацию:

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

Закрываем программу, запускаем ее снова. Опа! Триальное окно на месте, счетчик запусков продолжает тикать. Значит где-то должны быть еще какие-то проверки. Вернемся к коду регистрации, посмотрим на него повнимательнее. Мы видим, что регистрационные данные записываются в файл "\Data\ca.id", для верности можно сходить в эту папку и убедиться, что мы не ошиблись. Логично предположить, что раз туда сохраняется серийный номер, то он должен где-то читаться и проверяться. Поищем это место в дизассемблере по строке "ca.id". Немного ниже по коду находится аналогичная проверка с записью серийника в файл, видимо тупо продублирована процедура регистрации с заходом из другого места. Ее мы пропускаем. А еще ниже находятся интересные манипуляции с файлом ca.id:
  1. ...
  2. CODE:004CD238                 call    sub_403B28
  3. CODE:004CD23D                 mov     edx, ds:off_4D0008
  4. CODE:004CD243                 mov     edx, [edx]
  5. CODE:004CD245                 lea     eax, [ebp-8]
  6. CODE:004CD248                 mov     ecx, offset aDataCa_id_1 ; "\\Data\\ca.id"
  7. CODE:004CD24D                 call    sub_404C64
  8. CODE:004CD252                 mov     eax, [ebp-8]
  9. CODE:004CD255                 lea     edx, [ebp-4]
  10. CODE:004CD258                 call    sub_4C7D14
  11. CODE:004CD25D                 mov     edx, [ebp-4]
  12. ; Проверить позицию подстроки "A" в строке серийного номера
  13. CODE:004CD260                 mov     eax, offset aA  ; "A"
  14. CODE:004CD265                 call    sub_404F5C
  15. CODE:004CD26A                 test    eax, eax
  16. ; Если подстроки нет, то EAX=-1
  17. CODE:004CD26C                 jle     short loc_4CD290
  18. CODE:004CD26E                 mov     edx, [ebp-4]
  19. ; Проверить позицию подстроки "9" в строке серийного номера
  20. CODE:004CD271                 mov     eax, offset a9  ; "9"
  21. CODE:004CD276                 call    sub_404F5C
  22. CODE:004CD27B                 test    eax, eax
  23. ; Если подстроки нет, то EAX=-1
  24. CODE:004CD27D                 jle     short loc_4CD290
  25. CODE:004CD27F                 mov     edx, [ebp-4]
  26. ; Проверить позицию подстроки "CY" в строке серийного номера
  27. CODE:004CD282                 mov     eax, offset aCy ; "CY"
  28. CODE:004CD287                 call    sub_404F5C
  29. CODE:004CD28C                 test    eax, eax
  30. ; Если подстроки нет, то EAX=-1
  31. CODE:004CD28E                 jg      short loc_4CD29F
  32. CODE:004CD290 loc_4CD290:
  33. CODE:004CD290                 mov     eax, ds:off_4D037C
  34. CODE:004CD295                 mov     eax, [eax]
  35. CODE:004CD297                 mov     edx, [eax]
  36. CODE:004CD299                 call    dword ptr [edx+0ECh]
  37. CODE:004CD29F loc_4CD29F:
  38. CODE:004CD29F                 xor     eax, eax
  39. CODE:004CD2A1                 pop     edx
  40. CODE:004CD2A2                 pop     ecx
  41. CODE:004CD2A3                 pop     ecx
  42. CODE:004CD2A4                 mov     fs:[eax], edx
  43. CODE:004CD2A7                 push    offset loc_4CD2C1
  44. CODE:004CD2AC loc_4CD2AC:
  45. CODE:004CD2AC                 lea     eax, [ebp-8]
  46. CODE:004CD2AF                 mov     edx, 2
  47. CODE:004CD2B4                 call    sub_40497C
  48. CODE:004CD2B9
  49. ...
Под отладчиком картина тоже проясняется. Из файла "\Data\ca.id" читается серийный номер, но уже выполняются другие проверки: наличие в нем строк "A", "9" и "CY", причем опять же без какого-то конкретного расположения их в строке. Дополним ими серийный номер до строки PCLYI-9V7ACY (подстрока "9" уже есть) и попробуем снова зарегистрировать программу:

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

На этот раз триальное окно не появляется, значит регистрация считается полностью валидной. Осталось посмотреть, где программа хранит свой триальный счетчик. Для этого найдем место, где формируется строка с указанием количества оставшихся запусков:
  1. ...
  2. CODE:004CCAB4                 mov     eax, off_438EEC
  3. CODE:004CCAB9                 call    sub_438FEC
  4. CODE:004CCABE                 mov     esi, eax
  5. CODE:004CCAC0                 mov     edx, 80000002h
  6. CODE:004CCAC5                 mov     eax, esi
  7. CODE:004CCAC7                 call    sub_43908C
  8. CODE:004CCACC                 mov     cl, 1
  9. ; Открыть ветку реестра HKLM\SOFTWARE\Microsoft\Direcs3D\
  10. ; "Direcs3D" - это не опечатка, именно в этой ветке прячется триальный счетчик
  11. CODE:004CCACE                 mov     edx, offset aSoftwareMicros
  12. ; "\\SOFTWARE\\Microsoft\\Direcs3D\\"
  13. CODE:004CCAD3                 mov     eax, esi
  14. CODE:004CCAD5                 call    sub_4390F0
  15. CODE:004CCADA                 test    al, al
  16. CODE:004CCADC                 jz      loc_4CCC79
  17. CODE:004CCAE2                 mov     edx, offset aDirectdraw ; "DirectDraw"
  18. CODE:004CCAE7                 mov     eax, esi
  19. CODE:004CCAE9                 call    sub_43940C
  20. CODE:004CCAEE                 test    al, al
  21. CODE:004CCAF0                 jnz     short loc_4CCB2B
  22. CODE:004CCAF2                 call    sub_40B358
  23. CODE:004CCAF7                 add     esp, 0FFFFFFF8h
  24. CODE:004CCAFA                 fstp    qword ptr [esp]
  25. CODE:004CCAFD                 wait
  26. CODE:004CCAFE                 lea     eax, [ebp-1Ch]
  27. CODE:004CCB01                 call    sub_40BF6C
  28. CODE:004CCB06                 mov     eax, [ebp-1Ch]
  29. CODE:004CCB09                 lea     edx, [ebp-18h]
  30. CODE:004CCB0C                 call    sub_4CC6B8
  31. CODE:004CCB11                 lea     eax, [ebp-18h]
  32. CODE:004CCB14                 lea     edx, [ebp-8]
  33. CODE:004CCB17                 call    sub_4CC72C
  34. CODE:004CCB1C                 mov     ecx, [ebp-8]
  35. CODE:004CCB1F                 mov     edx, offset aDirectdraw ; "DirectDraw"
  36. CODE:004CCB24                 mov     eax, esi
  37. CODE:004CCB26                 call    sub_43928C
  38. CODE:004CCB2B loc_4CCB2B:
  39. CODE:004CCB2B                 mov     edx, offset aDirectinput ; "DirectInput"
  40. CODE:004CCB30                 mov     eax, esi
  41. CODE:004CCB32                 call    sub_43940C
  42. CODE:004CCB37                 test    al, al
  43. CODE:004CCB39                 jnz     short loc_4CCB67
  44. CODE:004CCB3B                 lea     edx, [ebp-18h]
  45. CODE:004CCB3E                 mov     eax, offset dword_4CCD08
  46. CODE:004CCB43                 call    sub_4CC6B8
  47. CODE:004CCB48                 lea     eax, [ebp-18h]
  48. CODE:004CCB4B                 lea     edx, [ebp-20h]
  49. CODE:004CCB4E                 call    sub_4CC72C
  50. CODE:004CCB53                 mov     ecx, [ebp-20h]
  51. CODE:004CCB56                 mov     edx, offset aDirectinput ; "DirectInput"
  52. CODE:004CCB5B                 mov     eax, esi
  53. CODE:004CCB5D                 call    sub_43928C
  54. CODE:004CCB62                 jmp     loc_4CCC79
  55. CODE:004CCB67 ; --------------------------------------------------
  56. CODE:004CCB67 loc_4CCB67:
  57. CODE:004CCB67                 lea     ecx, [ebp-4]
  58. CODE:004CCB6A                 mov     edx, offset aDirectinput ; "DirectInput"
  59. CODE:004CCB6F                 mov     eax, esi
  60. CODE:004CCB71                 call    sub_4392B8
  61. CODE:004CCB76                 mov     ebx, 1
  62. CODE:004CCB7B loc_4CCB7B:
  63. CODE:004CCB7B                 lea     edx, [ebp-28h]
  64. CODE:004CCB7E                 mov     eax, ebx
  65. CODE:004CCB80                 call    sub_40940C
  66. CODE:004CCB85                 lea     eax, [ebp-28h]
  67. CODE:004CCB88                 push    eax
  68. CODE:004CCB89                 lea     edx, [ebp-2Ch]
  69. CODE:004CCB8C                 mov     eax, ebx
  70. CODE:004CCB8E                 call    sub_40940C
  71. CODE:004CCB93                 mov     edx, [ebp-2Ch]
  72. CODE:004CCB96                 pop     eax
  73. CODE:004CCB97                 call    sub_404C20
  74. CODE:004CCB9C                 mov     eax, [ebp-28h]
  75. CODE:004CCB9F                 lea     edx, [ebp-18h]
  76. CODE:004CCBA2                 call    sub_4CC6B8
  77. CODE:004CCBA7                 lea     eax, [ebp-18h]
  78. CODE:004CCBAA                 lea     edx, [ebp-24h]
  79. CODE:004CCBAD                 call    sub_4CC72C
  80. CODE:004CCBB2                 mov     edx, [ebp-24h]
  81. CODE:004CCBB5                 mov     eax, [ebp-4]
  82. CODE:004CCBB8                 call    sub_404D64
  83. CODE:004CCBBD                 jz      short loc_4CCBC5
  84. CODE:004CCBBF                 inc     ebx
  85. CODE:004CCBC0                 cmp     ebx, 0Ah
  86. CODE:004CCBC3                 jnz     short loc_4CCB7B
  87. CODE:004CCBC5 loc_4CCBC5:
  88. CODE:004CCBC5                 cmp     ebx, 0Ah
  89. CODE:004CCBC8                 jnz     short loc_4CCBF6
  90. CODE:004CCBCA                 mov     dword ptr [edi+31Ch], 1
  91. CODE:004CCBD4                 mov     eax, [edi+304h]
  92. CODE:004CCBDA                 xor     edx, edx
  93. CODE:004CCBDC                 mov     ecx, [eax]
  94. CODE:004CCBDE                 call    dword ptr [ecx+64h]
  95. CODE:004CCBE1                 mov     eax, [edi+2FCh]
  96. CODE:004CCBE7                 mov     edx, offset aYouHaveUsed10T
  97. ; "You have used 10 times."
  98. CODE:004CCBEC                 call    sub_4462DC
  99. CODE:004CCBF1                 jmp     loc_4CCC79
  100. CODE:004CCBF6 ; -----------------------------------------------------
  101. CODE:004CCBF6 loc_4CCBF6:
  102. CODE:004CCBF6                 xor     eax, eax
  103. CODE:004CCBF8                 mov     [edi+31Ch], eax
  104. CODE:004CCBFE                 push    offset aYouHaveUsed ; "You have used "
  105. CODE:004CCC03                 lea     edx, [ebp-34h]
  106. CODE:004CCC06                 lea     eax, [ebx+1]
  107. CODE:004CCC09                 call    sub_40940C
  108. CODE:004CCC0E                 push    dword ptr [ebp-34h]
  109. CODE:004CCC11                 push    offset aTimes_  ; " times."
  110. CODE:004CCC16                 lea     eax, [ebp-30h]
  111. CODE:004CCC19                 mov     edx, 3
  112. CODE:004CCC1E                 call    sub_404CD8
  113. CODE:004CCC23                 mov     edx, [ebp-30h]
  114. ...
Оригинальностью аффтар не страдает, поэтому счетчик количества запусков прячется в ветке HKLM\SOFTWARE\Microsoft\Direcs3D\ в ключах с именами DirectDraw и DirectInput. Если периодически удалять эту ветку из реестра, то программой можно будет пользоваться и без регистрации в течение неограниченного времени. Но мы уже разобрали алгоритм генерации серийного номера, так что можете написать рабочий кейген самостоятельно.

Поделиться ссылкой ВКонтакте
Просмотров: 4285 | Комментариев: 10

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
user (29.02.2024 в 13:46):
Цитатав этом случае кейген по человеко-часам сопоставим с патчем.

Поймать в отладчике наг и перепрыгнуть его сопоставимо с разбором?
- Извените
ezfalc0n (03.04.2011 в 04:30):
Согласен, Дима, в этом случае кейген по человеко-часам сопоставим с патчем.
ManHunter (29.03.2011 в 23:42):
Можно. Только тут была задача закейгенить, а не пропатчить.
paralvic(wasm.ru) (29.03.2011 в 23:09):
Всяко можно ещё JCC(условный переход) занопить.
AyTkACT (28.03.2011 в 07:15):
ManHunter, красивый разбор проверки. Приятно почитать.
Jadavin (27.03.2011 в 22:59):
Спасибо. )
Super_DJ (27.03.2011 в 17:37):
Давно не встречал подобных прог, а тут и лечение есть =)
Респект!
sj3.14159 (27.03.2011 в 17:18):
True программа, хорошая статья. Спасибо.
ManHunter (27.03.2011 в 15:01):
Поднимаю свои варезные архивы :) А где встретил уже и не упомню, давно дело было.
Rustamer (27.03.2011 в 14:57):
Спасибо. Весьма интересная программа. Если не секрет, где ты ее встретил?

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2025
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.007 сек.) / Память: 4.5 Mb
Наверх