Blog. Just Blog

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

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

Игрушка Advanced Gomoku - это по сути те же самые "крестики-нолики", в которые, наверное, играл каждый. Игрушка достаточно старая, и из-за особенности ее защиты получается, что она работает только на системах Windows XP. Это значит, что даже если кто-то потратил деньги на ее приобретение, то он не сможет в нее играть после обновления своей операционной системы. Справедливо? Нет. В соответствии с действующем законодательством мы имеем полное право внести изменения в программу, чтобы она могла продолжать работать на новой системе.

Правомерно овладеваем дистрибутивом, но для его установки придется воспользоваться компьютером с Windows XP или виртуальной машиной. После установки и запуска появляется триальное окно:

Наг-скрин при старте программы
Наг-скрин при старте программы

Кроме него, как я понял, в программе других ограничений нет. Первичный осмотр главного исполняемого файла показывает, что он упакован старой версией ASProtect, именно поэтому файл и отказывается работать на современных системах. Статические распаковщики его не берут, воспользуемся автоматическим распаковщиком Stripper 2.07 для снятия навесного протектора.

Распаковываем исполняемый файл
Распаковываем исполняемый файл

Проверим распакованный файл на работоспособность. Он запускается, триальное окно при запуске пропало, но в окне "О программе" все равно показывается, что программа не зарегистрирована и остался минус один день испытательного срока. Если со счетчиком дней все понятно - это побочный эффект снятия ASProtect, и ничего страшного в этом нет, то строка "unregistered" говорит о том, что программа не может найти регистрационное имя (ключ). Казалось бы, можно оставить и так, триального окна же нет. Но на своей практике я уже неоднократно сталкивался с тем, что после распаковки на одном компьютере программа считает себя зарегистрированной, а на другом распакованный файл продолжает работать как триалка. Это связано с тем, что в файле все равно могут оставаться некоторые функции протектора, и запрашиваемые им адреса памяти на разных машинах могут отличаться.

Окно "О программе"
Окно "О программе"

Для однозначного решения этой проблемы надо сделать так, чтобы программа на свой запрос всегда получала какое-нибудь регистрационное имя, лучше всего наше. В конце концов мы же ее адаптируем, так сделаем это по полной программе. Посмотрим в дизассемблере, как и при каких условиях появляется строка о незарегистрированной программе:
  1. ; Проверить первый байт строки, на которую ссылается указатель dword_440BD0
  2. .text:00401269                 mov     edx, ds:dword_440BD0
  3. .text:0040126F                 movsx   eax, byte ptr [edx]
  4. .text:00401272                 test    eax, eax
  5. ; Если строка пустая (регистрационного имени нет), то программа триальная
  6. .text:00401274                 jz      short loc_4012C9
  7. ; Иначе вывести строку "Зарегистрирована на..."
  8. .text:00401276                 push    0               ; nCmdShow
  9. .text:00401278                 push    403h            ; nIDDlgItem
  10. .text:0040127D                 mov     ecx, [ebp+hWnd]
  11. .text:00401280                 push    ecx             ; hDlg
  12. .text:00401281                 call    GetDlgItem
  13. .text:00401287                 push    eax             ; hWnd
  14. .text:00401288                 call    ShowWindow
  15. ; Указатель на строку регистрационного имени
  16. .text:0040128E                 mov     edx, ds:dword_440BD0
  17. .text:00401294                 push    edx
  18. .text:00401295                 push    offset aRegisteredToS
  19. ; "Registered to :\n%s"
  20. .text:0040129A                 lea     eax, [ebp+String]
  21. .text:004012A0                 push    eax
  22. .text:004012A1                 call    wsprintfA
  23. .text:004012A7                 add     esp, 0Ch
  24. .text:004012AA                 lea     ecx, [ebp+String]
  25. .text:004012B0                 push    ecx             ; lpString
  26. .text:004012B1                 push    401h            ; nIDDlgItem
  27. .text:004012B6                 mov     edx, [ebp+hWnd]
  28. .text:004012B9                 push    edx             ; hDlg
  29. .text:004012BA                 call    GetDlgItem
  30. .text:004012C0                 push    eax             ; hWnd
  31. .text:004012C1                 call    SetWindowTextA
  32. .text:004012C7                 jmp     short loc_40133E
  33. .text:004012C9 ; -------------------------------------------------------
  34. .text:004012C9 loc_4012C9:
  35. .text:004012C9                 mov     eax, ds:dword_429004
  36. .text:004012CE                 push    eax
  37. .text:004012CF                 push    offset aUnregisteredVe
  38. ; "Unregistered version!\nYou can use this "...
  39. .text:004012D4                 lea     ecx, [ebp+String]
  40. .text:004012DA                 push    ecx
  41. .text:004012DB                 call    wsprintfA
Все понятно. Проверяется строка регистрационного имени, на которую ссылается указатель по адресу 00440BD0. Как я уже говорил выше, этот указатель в нормальных условиях инициализируется протектором, но протектор мы уже сняли, поэтому надо проинициализировать указатель самостоятельно. Поищем наиболее удобное место, где это можно сделать.

Перекрестные ссылки на указатель
Перекрестные ссылки на указатель

По перекрестным ссылкам находим команду, которая записывает EAX в указатель. Казалось бы - вот оно, но не тут-то было. Это всего лишь "мертвый" код, оставшийся от протектора. Он никогда не получит управления, а значит что-то исправлять там бесполезно. Самый лучший вариант - это заменить какую-нибудь его проверку на инициализацию. По другим перекрестным ссылкам находим код, в котором раньше всего выполняется проверка:
  1. .text:0041BBFE                 push    ebp
  2. .text:0041BBFF                 mov     ebp, esp
  3. ; Если указатель пустой, то запустить игру
  4. .text:0041BC01                 cmp     ds:dword_440BD0, 0
  5. .text:0041BC08                 jz      short loc_41BC26
  6. ; Если указатель есть, но строка пустая, то показать триальное окно
  7. .text:0041BC0A                 mov     eax, ds:dword_440BD0
  8. .text:0041BC0F                 movsx   ecx, byte ptr [eax]
  9. .text:0041BC12                 test    ecx, ecx
  10. .text:0041BC14                 jnz     short loc_41BC26
  11. .text:0041BC16                 call    sub_40CF5E
  12. ; По выбранной кнопке в триальном окне или выход, или играем
  13. .text:0041BC1B                 test    eax, eax
  14. .text:0041BC1D                 jz      short loc_41BC26
  15. .text:0041BC1F                 push    1               ; Code
  16. .text:0041BC21                 call    _exit
  17. .text:0041BC26 ; ----------------------------------------
  18. .text:0041BC26 loc_41BC26:
  19. .text:0041BC26                 call    sub_410EC4
  20. .text:0041BC2B                 pop     ebp
  21. .text:0041BC2C                 retn
  22. .text:0041BC2C sub_41BBFE      endp
Теперь мы знаем, почему пропало триальное окно при старте. Указатель пустой, значит сразу выполняется переход на запуск игры. Вот сюда мы и поместим инициализацию, но сперва надо имплантировать регистрационное имя прямо в исполняемый файл. Мы уже так делали, и на этот раз точно так же перебьем строку сообщения о незарегистрированной программе на наше имя. Не забывайте, что строка должна быть в формате ASCIIZ!

Заменяем строку регистрационного имени
Заменяем строку регистрационного имени

Осталось заменить код по адресу 0041BC01 на команды MOV DWORD [440BD0h], 427094h и заNOPить оставшиеся куски проверки, чтобы не нарушать логику программы. Условный переход по адресу 0041BC14 надо заменить на безусловный, чтобы после инициализации регистрациионного имени сразу же запускалась игра.

Прописываем адрес строки
Прописываем адрес строки

Сохраняем изменения, снова запускаем игру. Триального окна все так же нет, заглянем в окно "О программе". Какая прелесть!

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

Вот так мы осуществили действия, необходимые для функционирования программы или базы данных в соответствии с их назначением. А именно внесли в программу для ЭВМ или базу данных изменения исключительно в целях их функционирования на технических средствах пользователя. Как говорил Остап Бендер: "Уголовный кодекс надо чтить!"

Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 3320 | Комментариев: 7

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

Комментарии

Отзывы посетителей сайта о статье
morgot (31.08.2012 в 21:15):
кстати, не в тему, но заметил у себя в ХР (зверь сборка), что немало прог зарегистрированы на ManHunter / PCL :)
Voffka (31.08.2012 в 16:12):
Да и API в новых версиях аспра не далеко ушли. Чего только стоят GetRegistrationInformation и GetModeInformation
ManHunter (31.08.2012 в 16:00):
Voffka, это же хорошо.
Voffka (31.08.2012 в 15:59):
Таким макаром 90% всего софта со старыми аспрами можно зарегать.
Never (31.08.2012 в 09:20):
Очень подозреваю, что да, так как в определенный период почти все брал с региона, так с тех пор и пользуюсь.
ManHunter (31.08.2012 в 09:12):
Еще, наверное, в мой старый релиз играешь? :)
Never (31.08.2012 в 09:10):
Вах! Сколько лет в нее играю, думал она фриварная :-(

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

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

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