Blog. Just Blog

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

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

Скринсейвер Ripple Pool рисует на экране эффект водной поверхности. Реализация вроде нормальная, все работает, непонятно почему этот скринсейвер убрали с сайта разработчика. В загашнике у меня остался дистрибутив, вот его и поковыряем.

Забираем с файлообменника дистрибутив, устанавливаем, смотрим. Файл скринсейвера ничем не упакован, отправляем его на дизассемблирование. На стандартные параметры командной строки он не реагирует, поэтому открываем настройки экрана, а затем настройки самого скринсейвера.

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

В окне ввода серийного номера нет никаких кнопок. Похоже, что какая-то реакция будет только в случае ввода правильного серийника. Интересный ход со стороны разработчика, хоть идея и не нова. Значит будем цепляться за что-нибудь другое, например, за текст в заголовке окна настроек. И да, он действительно с синтаксической ошибкой.

Строка в файле
Строка в файле

Переходим в дизассемблер, находим место, где используются эти строки.
  1. CODE:004764D2                 mov     ecx, ds:off_4ABCAC
  2. CODE:004764D8                 mov     ecx, [ecx]
  3. CODE:004764DA                 mov     edx, ds:off_4ABC68
  4. CODE:004764E0                 mov     edx, [edx]
  5. CODE:004764E2                 mov     eax, ds:off_4ABBE4
  6. CODE:004764E7                 mov     eax, [eax]
  7. ; Вызвать функцию проверки
  8. CODE:004764E9                 call    sub_467738
  9. CODE:004764EE                 test    al, al
  10. ; Условный переход по результатам проверки
  11. CODE:004764F0                 jz      short loc_476500
  12. ; Зарегистрировано
  13. CODE:004764F2                 mov     edx, offset _str_Settings__Ver4_.Text
  14. CODE:004764F7                 mov     eax, ebx
  15. CODE:004764F9                 call    @Controls@TControl@SetText
  16. CODE:004764FE                 pop     ebx
  17. CODE:004764FF                 retn
  18. CODE:00476500 ; ------------------------------------
  19. CODE:00476500 loc_476500:
  20. ; Незарегистрировано
  21. CODE:00476500                 mov     edx, offset _str_Settings__Ver4__0.Text
  22. CODE:00476505                 mov     eax, ebx
  23. CODE:00476507                 call    @Controls@TControl@SetText
  24. CODE:0047650C                 pop     ebx
Обычное ветвление алгоритма, выполняется проверка, по ее результатам в заголовок окна записывается та или иная строчка. За правильную регистрацию отвечает AL!=0. Открываем функцию проверки. Если посмотреть в заголовке, откуда она вызывается, то там как раз обнаружится событие изменения поля ввода, значит моя догадка о реакции на правильный серийник подтверждается. Патчим функцию проверки парой команд MOV EAX,1 и RET 4, чтобы не разрушить стек. Сохраняем изменения, запускаем настройки скринсейвера.

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

В заголовке окна сразу правильная строка, при попытке регистрации любыми левыми данными после первого же введенного символа серийного номера появляется кнопка "Register", а при ее нажатии скринсейвер благодарит нас за регистрацию. Первая половина задачи успешно решена.

Теперь попробуем сделать валидный серийник. Вернемся к функции проверки, если внимательно посмотреть, то там помимо всяких манипуляций с регистрами обнаруживаются несколько функций сравнения строк. Давайте посмотрим на них под отладчиком. Откатываем из резервной копии оригинальный файл или переустанавливаем скринсейвер, открываем настройки и цепляемся к процессу отладчиком. Ставим точку останова на начало функции проверки по адресу 00467738 и отпускаем на выполнение. При попытке регистрации на каждый введенный символ будет срабатывать точка останова, так что лучше сразу где-нибудь в блокнотике сделать длинную строку и копипастнуть ее в поле ввода. Начинаем трассировку. На функциях сравнения происходит нечто странное. Первая строка явно сгенерированная, а вторая почему-то пустая. На примере первого сравнения:
  1. ; Сгенерированная строка
  2. CODE:004678A7                 mov     edx, [ebp+var_4C]
  3. ; Пустая строка
  4. CODE:004678AA                 mov     eax, [ebp+var_C]
  5. CODE:004678AD                 call    @System@@LStrCmp$qqrv
Посмотрим, откуда берется [ebp+var_C]. В самом начале функции проверки обнаруживается вот такой блок:
  1. CODE:00467749                 mov     [ebp+var_C], ecx
  2. CODE:0046774C                 mov     [ebp+var_8], edx
  3. CODE:0046774F                 mov     [ebp+var_4], eax
То есть эти адреса инициализируются параметрами, переданными функции проверки в регистрах. Вернемся к вызову функции проверки, например, там где проверяется поле ввода.
  1. CODE:00467EA0                 call    @Controls@TControl@GetText$qqrv
  2. CODE:00467EA5                 mov     eax, ds:off_4ABC9C
  3. CODE:00467EAA                 mov     edx, [ebp+var_8]
  4. CODE:00467EAD                 call    @System@@LStrAsg$qqrpvpxv
  5. CODE:00467EB2                 lea     ecx, [ebp+var_10]
  6. CODE:00467EB5                 mov     eax, ds:off_4ABC9C
  7. CODE:00467EBA                 mov     eax, [eax]
  8. CODE:00467EBC                 mov     edx, 2
  9. CODE:00467EC1                 call    sub_467AD8
  10. CODE:00467EC6                 mov     edx, [ebp+var_10]
  11. CODE:00467EC9                 mov     eax, ds:off_4ABCAC
  12. CODE:00467ECE                 call    @System@@LStrAsg$qqrpvpxv
  13. CODE:00467ED3                 lea     ecx, [ebp+var_14]
  14. CODE:00467ED6                 mov     eax, ds:off_4ABC9C
  15. CODE:00467EDB                 mov     eax, [eax]
  16. CODE:00467EDD                 mov     edx, 3
  17. CODE:00467EE2                 call    sub_467AD8
  18. CODE:00467EE7                 mov     edx, [ebp+var_14]
  19. CODE:00467EEA                 mov     eax, ds:off_4ABA9C
  20. CODE:00467EEF                 call    @System@@LStrAsg$qqrpvpxv
  21. CODE:00467EF4                 mov     eax, ds:off_4ABA9C
  22. CODE:00467EF9                 mov     eax, [eax]
  23. CODE:00467EFB                 push    eax
  24. ; Инициализация регистров-параметров
  25. CODE:00467EFC                 mov     ecx, ds:off_4ABCAC
  26. CODE:00467F02                 mov     ecx, [ecx]
  27. CODE:00467F04                 mov     eax, ds:off_4ABBE4
  28. CODE:00467F09                 mov     eax, [eax]
  29. CODE:00467F0B                 mov     edx, [ebp+var_4]
  30. ; Вызов функции проверки
  31. CODE:00467F0E                 call    sub_467738
  32. CODE:00467F13                 test    al, al
  33. CODE:00467F15                 jz      short loc_467F26
Кроме библиотечных функций, нас интересует функция sub_467AD8. Посмотрим, что там делается:
  1. CODE:00467AD8                 push    ebp
  2. CODE:00467AD9                 mov     ebp, esp
  3. CODE:00467ADB                 add     esp, 0FFFFFFF8h
  4. CODE:00467ADE                 push    ebx
  5. CODE:00467ADF                 push    esi
  6. CODE:00467AE0                 mov     [ebp+var_8], ecx
  7. CODE:00467AE3                 mov     esi, edx
  8. CODE:00467AE5                 mov     [ebp+var_4], eax
  9. CODE:00467AE8                 mov     eax, [ebp+var_4]
  10. CODE:00467AEB                 call    @System@@LStrAddRef$qqrpv
  11. CODE:00467AF0                 xor     eax, eax
  12. CODE:00467AF2                 push    ebp
  13. CODE:00467AF3                 push    offset loc_467B5E
  14. CODE:00467AF8                 push    dword ptr fs:[eax]
  15. CODE:00467AFB                 mov     fs:[eax], esp
  16. CODE:00467AFE                 mov     dl, 1
  17. CODE:00467B00                 mov     eax, off_412BA8
  18. CODE:00467B05                 call    unknown_libname_39
  19. CODE:00467B0A                 mov     ebx, eax
  20. ; Символ '-'
  21. CODE:00467B0C                 mov     dl, 2Dh
  22. CODE:00467B0E                 mov     eax, ebx
  23. CODE:00467B10                 call    @Classes@TStrings@SetDelimiter$qqrxc
  24. CODE:00467B15                 mov     edx, [ebp+var_4]
  25. CODE:00467B18                 mov     eax, ebx
  26. CODE:00467B1A                 call    @Classes@TStrings@SetDelimitedText
  27. CODE:00467B1F                 mov     eax, ebx
  28. CODE:00467B21                 mov     edx, [eax]
  29. CODE:00467B23                 call    dword ptr [edx+14h]
  30. CODE:00467B26                 cmp     esi, eax
  31. CODE:00467B28                 jg      short loc_467B39
Берется строка, разделяется на подстроки по символу-разделителю, потом возвращается подстрока, соответствующая переданному параметру, в нашем случае это 2 и 3. То есть в серийном номере должны быть символы-разделители "-" таким образом, чтобы в результате ее разделения получалось как минимум три фрагмента. Не проблема, подкорректируем тестовый серийник, добавив в него пару разделителей. Повторяем регистрацию.

Первое сравнение строк
Первое сравнение строк

Для регистрационного имени "ManHunter / PCL" в первом сравнении сравнивается второй блок серийника и строка "5E662A".

Второе сравнение строк
Второе сравнение строк

Во втором сравнении сравнивается третий блок серийника и строка "EZ0ZY6". Первый блок серийника в сравнениях не используется. Раз остальные блоки по 6 символов, то можно предположить, что и первый блок должен быть такой же длины. Итак, сгенерированный серийник имеет вид "123456-5E662A-EZ0ZY6". Закрываем отладчик, открываем настройки скринсейвера, повторяем регистрацию.

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

Нас снова благодарят за регистрацию, на этот раз вполне себе легальную, нехорошая надпись в заголовке пропадает. Цель достигнута окончательно.

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

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

Комментарии

Отзывы посетителей сайта о статье
ManHunter (13.04.2020 в 22:11):
Не пользуюсь, не знаю. Никаких глубинных смыслов ни в чем не ищу.
прохожий (13.04.2020 в 22:07):
Понял, спасибо. Тоже обратил внимание именно на эту сборку.
А что думаете по поводу Olly2? Есть в нём какой-то смысл?
ManHunter (13.04.2020 в 21:58):
OllyDbg 1.10, сборка от diablo2oo2. За остальные ничего не скажу, не пользуюсь.
прохожий (13.04.2020 в 21:55):
Товарищ хирург, подскажите, какой версией Olly Вы пользуетесь? Если это сборка, то которая именно? И что Вы думаете про Immunity Debugger и x64dbg? Там есть и 32-битная версия. А то, к сожалению, не нашёл у Вас обзора отладчиков.
ManHunter (13.04.2020 в 12:34):
При чем тут актуальность? Может быть не заметил, смысл статьи не в донесении софтовых новинок до населения. И "понадобиться" в этом контексте пишется без мягкого знака, "что сделаЕТ?" - "понадобиТСЯ".
Softvok (13.04.2020 в 12:32):
Давно не актуально. Сломали еще в 2009 году. Ему еже 11 лет, уже ретро.
Может кому понадобиться: [del]
A1eksandr1 (13.04.2020 в 00:15):
"Цель достигнута окончательно" - я бы сказал, задача решена максимально корректно в плане невмешательства в код, а значит случайно не навредим функционалу, оставим живую ЦП (если она там вообще есть), и не нарвёмся на скрытые проверки. Хотя с последним не факт, находится не мало извращуг, встраивающих дополнительные скрытые проверки по таймеру или какому то событию.

Самое удобное именно лечение, ИМХО, это отследить, что меняется после регистрации, как проверяется, что программа уже зарегистрировано, и фиксить уже этот момент, чтобы в принципе никуда не нужно было лезть и что то вводить.

Это если что не в упрёк, просто мысли, которые возможно натолкнут кого то на свои..

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

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

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