Blog. Just Blog

Исследование защиты скринсейвера Forest Lake

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

С полноценным отдыхом пока напряженка, так что остается наслаждаться виртуальными путешествиями. Скринсейвер Forest Lake переносит нас на берег лесного озера, где под приятную музыку плещется вода, летают птички и бабочки, плавают рыбки. Идиллию нарушает только необходимость выкладывать за это все деньги.

Забираем с офсайта дистрибутив, устанавливаем, смотрим. Исполняемый файл скринсейвера, который находится в системной папке, накрыт протектором ASProtect. Можно воспользоваться одним из автоматических распаковщиков, но лучше попрактикуемся в ручной распаковке, а то давно что-то этого не делали.

Для распаковки понадобится отладчик OllyDbg 1.10 с установленными плагинами ODbgScript, OllyDump и скрипт-распаковщик Aspr2.XX_unpacker от VolX. Загружаем защищенный файл в отладчик, через меню Plugins - ODbgScript - Run Script... выбираем скрипт-распаковщик. Когда он закончит работу, дампим память процесса. Меню Plugins - OllyDump - Dump debugged process. Галочку "Rebuild import" надо обязательно снять.

Делаем дамп файла
Делаем дамп файла

Возвращаемся к логу работы скрипта Plugins - ODbgScript - Log Window..., там будут значения, необходимые для восстановления импорта файла.

Лог работы скрипта
Лог работы скрипта

Запускаем вашу любимую программу для восстановления импорта, заполняем параметры для поиска импорта значениями из лога отладчика.

Загружаем импорт
Загружаем импорт

Когда все функции будут успешно распознаны, надо прикрутить новую секцию импорта к сделанному ранее дампу.

Восстанавливаем дамп
Восстанавливаем дамп

Убеждаемся в работоспособности распакованного файла, после этого отправляем его на разбор в дизассемблер. Чтобы не возиться с параметрами командной строки, SCR-файл можно переименовать в EXE. При открытии настроек, а также до и после запуска скринсейвера открываются разные триальные окна. А окно настроек выглядит следующим образом.

Сообщение незарегистрированной версии
Сообщение незарегистрированной версии

Первое, что бросается в глаза, это надпись "UNREGISTERED TRIAL VERSION". Поиском по листингу обнаруживаем вот такой код. Это не совсем то, но тут тоже используется строка о незарегистрированности.
  1. seg000:0041A869                 push    eax
  2. seg000:0041A86A                 mov     ecx, offset dword_4BEC60
  3. ; Вызвать функцию проверки
  4. seg000:0041A86F                 call    sub_4031A0
  5. seg000:0041A874                 test    eax, eax
  6. ; Значение EAX не 0, никаких надписей не выводить
  7. seg000:0041A876                 jnz     short loc_41A88D
  8. seg000:0041A878                 push    30h             ; uType
  9. seg000:0041A87A                 push    offset aWelcome ; "Welcome"
  10. seg000:0041A87F                 push    offset aUnregisteredVe
  11. ; "UNREGISTERED VERSION. PLEASE REGISTER!"
  12. seg000:0041A884                 push    esi             ; hWnd
  13. seg000:0041A885                 call    ds:MessageBoxA
  14. seg000:0041A88B                 jmp     short loc_41A8EF
  15. seg000:0041A88D ; --------------------------------
  16. seg000:0041A88D loc_41A88D:
  17. seg000:0041A88D                 mov     [esp+4Ch+var_14], 0Fh
  18. seg000:0041A895                 mov     [esp+4Ch+var_18], ebx
  19. seg000:0041A899                 mov     byte ptr [esp+4Ch+lpString], bl
  20. seg000:0041A89D                 push    0Fh             ; Dst
  21. seg000:0041A89F                 push    offset aRegisteredTo
  22. ; "Registered to: "
  23. seg000:0041A8A4                 lea     ecx, [esp+54h+var_2C]
  24. seg000:0041A8A8                 mov     [esp+54h+var_4], ebx
  25. seg000:0041A8AC                 call    sub_4039E0
  26. seg000:0041A8B1                 push    0FFFFFFFFh      ; MaxCount
  27. seg000:0041A8B3                 push    ebx             ; int
  28. seg000:0041A8B4                 push    offset dword_4A9E80 ; int
  29. seg000:0041A8B9                 lea     ecx, [esp+58h+var_2C]
  30. seg000:0041A8BD                 call    sub_403800
Перед условным переходом запускается следующая функция проверки, по ее результатам выполняется та или иная ветка алгоритма. Для того, чтобы нехорошая надпись не появлялась, функция проверки должна вернуть ненулевое значение в регистре EAX.
  1. seg000:004031A0 sub_4031A0      proc near
  2. seg000:004031A0                 sub     esp, 24h
  3. seg000:004031A3                 mov     eax, ds:dword_4ADAE8
  4. seg000:004031A8                 xor     eax, esp
  5. seg000:004031AA                 mov     [esp+24h+var_4], eax
  6. seg000:004031AE                 mov     edx, [esp+24h+arg_0]
  7. seg000:004031B2                 push    ebx
  8. seg000:004031B3                 push    ebp
  9. seg000:004031B4                 push    esi
  10. seg000:004031B5                 push    edi
  11. seg000:004031B6                 lea     eax, [esp+34h+var_24]
  12. seg000:004031BA                 push    eax
  13. seg000:004031BB                 push    edx
  14. seg000:004031BC                 call    sub_403020
  15. seg000:004031C1                 xor     ebx, ebx
  16. seg000:004031C3                 cmp     ds:dword_49A004, ebx
  17. seg000:004031C9                 jle     loc_40326D
  18. seg000:004031CF                 mov     edi, offset nullsub_2
  19. seg000:004031D4 loc_4031D4:
  20. seg000:004031D4                 mov     eax, 8
  21. seg000:004031D9                 lea     ecx, [esp+34h+var_24]
  22. seg000:004031DD                 mov     edx, edi
  23. seg000:004031DF                 nop
  24. seg000:004031E0 loc_4031E0:
  25. seg000:004031E0                 mov     esi, [edx]
  26. seg000:004031E2                 cmp     esi, [ecx]
  27. seg000:004031E4                 jnz     short loc_4031F8
  28. seg000:004031E6                 sub     eax, 4
  29. seg000:004031E9                 add     ecx, 4
  30. seg000:004031EC                 add     edx, 4
  31. seg000:004031EF                 cmp     eax, 4
  32. seg000:004031F2                 jnb     short loc_4031E0
  33. seg000:004031F4                 test    eax, eax
  34. seg000:004031F6                 jz      short loc_403255
  35. seg000:004031F8 loc_4031F8:
  36. seg000:004031F8                 movzx   esi, byte ptr [edx]
  37. seg000:004031FB                 movzx   ebp, byte ptr [ecx]
  38. seg000:004031FE                 sub     esi, ebp
  39. seg000:00403200                 jnz     short loc_403247
  40. seg000:00403202                 sub     eax, 1
  41. seg000:00403205                 add     ecx, 1
  42. seg000:00403208                 add     edx, 1
  43. seg000:0040320B                 test    eax, eax
  44. seg000:0040320D                 jz      short loc_403255
  45. seg000:0040320F                 movzx   esi, byte ptr [edx]
  46. seg000:00403212                 movzx   ebp, byte ptr [ecx]
  47. seg000:00403215                 sub     esi, ebp
  48. seg000:00403217                 jnz     short loc_403247
  49. seg000:00403219                 sub     eax, 1
  50. seg000:0040321C                 add     ecx, 1
  51. seg000:0040321F                 add     edx, 1
  52. seg000:00403222                 test    eax, eax
  53. seg000:00403224                 jz      short loc_403255
  54. seg000:00403226                 movzx   esi, byte ptr [edx]
  55. seg000:00403229                 movzx   ebp, byte ptr [ecx]
  56. seg000:0040322C                 sub     esi, ebp
  57. seg000:0040322E                 jnz     short loc_403247
  58. seg000:00403230                 sub     eax, 1
  59. seg000:00403233                 add     ecx, 1
  60. seg000:00403236                 add     edx, 1
  61. seg000:00403239                 test    eax, eax
  62. seg000:0040323B                 jz      short loc_403255
  63. seg000:0040323D                 movzx   esi, byte ptr [edx]
  64. seg000:00403240                 movzx   eax, byte ptr [ecx]
  65. seg000:00403243                 sub     esi, eax
  66. seg000:00403245                 jz      short loc_403255
  67. seg000:00403247 loc_403247:
  68. seg000:00403247                 test    esi, esi
  69. seg000:00403249                 mov     eax, 1
  70. seg000:0040324E                 jg      short loc_403257
  71. seg000:00403250                 or      eax, 0FFFFFFFFh
  72. seg000:00403253                 jmp     short loc_403257
  73. seg000:00403255 ; --------------------------------
  74. seg000:00403255 loc_403255:
  75. seg000:00403255                 xor     eax, eax
  76. seg000:00403257 loc_403257:
  77. seg000:00403257                 test    eax, eax
  78. seg000:00403259                 jz      short loc_403284
  79. seg000:0040325B                 add     ebx, 1
  80. seg000:0040325E                 add     edi, 20h
  81. seg000:00403261                 cmp     ebx, ds:dword_49A004
  82. seg000:00403267                 jl      loc_4031D4
  83. seg000:0040326D loc_40326D:
  84. seg000:0040326D                 pop     edi
  85. seg000:0040326E                 pop     esi
  86. seg000:0040326F                 pop     ebp
  87. seg000:00403270                 xor     eax, eax
  88. seg000:00403272                 pop     ebx
  89. seg000:00403273                 mov     ecx, [esp+24h+var_4]
  90. seg000:00403277                 xor     ecx, esp
  91. seg000:00403279                 call    sub_44DD84
  92. seg000:0040327E                 add     esp, 24h
  93. seg000:00403281                 retn    4
  94. seg000:00403284 ; --------------------------------
  95. seg000:00403284 loc_403284:
  96. seg000:00403284                 mov     ecx, [esp+34h+var_4]
  97. seg000:00403288                 pop     edi
  98. seg000:00403289                 pop     esi
  99. seg000:0040328A                 pop     ebp
  100. seg000:0040328B                 pop     ebx
  101. seg000:0040328C                 xor     ecx, esp
  102. seg000:0040328E                 mov     eax, 1
  103. seg000:00403293                 call    sub_44DD84
  104. seg000:00403298                 add     esp, 24h
  105. seg000:0040329B                 retn    4
  106. seg000:0040329B sub_4031A0      endp
Записываем в начало функции проверки пару команд MOV EAX,1 и RET 4, чтобы корректно восстановить стек после возврата. Сохраняем изменения, запускаем. Триальные окна исчезли, скринсейвер принимает любое имя и любой серийник.

Скринсейвер успешно "зарегистрирован"
Скринсейвер успешно "зарегистрирован"

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

Водяной знак незарегистрированной версии
Водяной знак незарегистрированной версии

Это значит, что в файле должна быть как минимум еще одна проверка корректности регистрационных данных. Логично предположить, что в ней будут использоваться те же команды и функции, что и в найденной ранее функции проверки регистрации. По паттернам "dword_49A004" и "nullsub_2" обнаружится вторая функция проверки регистрации. Она находится сразу же под первой функцией проверки, так что далеко ходить не пришлось. Патчим ее начало аналогичной парой команд MOV EAX,1 и RET 4, сохраняем изменения, запускаем скринсейвер. Никаких посторонних надписей больше не появляется, цель достигнута.

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

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

Комментарии

Отзывы посетителей сайта о статье
Moskakasy (18.09.2022 в 18:57):
Помню,как долго мучился со скрипт-распаковщиком Aspr2.XX_unpacker от VolX.
Пришлось там поправить,чтоб работал.

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

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

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