Blog. Just Blog

Исследование защиты игры Theseus and the Minotaur

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

Игра Theseus and the Minotaur от компании Kristanix - компьютерная реализация одной из классических головоломок, история которой ведется еще с 90-х годов прошлого века. Когда-то сайт Kristanix был отличным дистибьютером игр для различных платформ, там можно было скачать огромное количество оригинальных головоломок, аркад и других игр, а сейчас это какое-то унылое говно. И игру Theseus and the Minotaur вы там тоже не найдете, все ссылки битые. К счастью, у меня в закромах завалялся дистрибутив, осталось только найти Книгу Мертвых, чтобы воскресить проект из небытия.

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

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

На ввод левого серийника игра реагирует следующим сообщением:

Сообщение о неправильной регистрации
Сообщение о неправильной регистрации

Поищем строчку сообщения в исполняемом файле. Найдется одна юникодная строка. К слову, в дизассемблере эта строка превращается в нечитаемый набор символов, и найти ее просто так не получится. Кто там еще возмущался, зачем я до сих пор пользуюсь HiEW для поиска текстовых строк в файлах?

Строка сообщения
Строка сообщения

Теперь можно спокойно вернуться в дизассемблер и посмотреть, как эта строчка задействуется. Код будет следующий:
  1. code:004E4F52                 push    ebp
  2. code:004E4F53                 mov     ebp, esp
  3. code:004E4F55                 push    ebx
  4. code:004E4F56                 push    esi
  5. code:004E4F57                 mov     ebx, [ebp+arg_0]
  6. code:004E4F5A                 mov     esi, [ebp+arg_4]
  7. code:004E4F5D                 push    ebx
  8. ; Вызвать функцию проверки
  9. code:004E4F5E                 call    sub_4E4322
  10. code:004E4F63                 add     esp, 4
  11. code:004E4F66                 cmp     eax, 0
  12. ; Если она вернула 0, то серийник неправильный
  13. code:004E4F69                 jnz     short loc_4E4F8C
  14. ; Вывести сообщение о неправильной регистрации
  15. code:004E4F6B                 mov     ebx, offset off_541AD0
  16. code:004E4F70                 inc     dword ptr [ebx+4]
  17. code:004E4F73                 mov     eax, [esi]
  18. code:004E4F75                 dec     dword ptr [eax+4]
  19. code:004E4F78                 jnz     short loc_4E4F83
  20. code:004E4F7A                 push    eax
  21. code:004E4F7B                 call    sub_48868E
  22. code:004E4F80                 add     esp, 4
Бегло посмотрев функцию проверки, можно выяснить, что вызывается она два раза. Можно с большой уверенностью предположить, что первый вызов - это проверка сохраненного где-то серийника при старте программы, а второй - проверка введенного серийника при попытке регистрации. Самым простым решением будет классический патч функции проверки, чтобы она всегда возвращала ненулевое значение в регистре EAX. Забиваем по адресу 004E4322 сладкую парочку MOV EAX,1 и RET, сохраняем изменения, запускаем. Даже без регистрации можно заметить, что пропала кнопка "Buy Now", а также триальное окно при выходе из игры. Ограничение по количеству запусков также нейтрализовано. Малой кровью цель достигнута.

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

Теперь давайте попробуем отреверсить алгоритм проверки серийного номера. Откатываем из бэкапа исполняемый файл, загоняем его в отладчик, ставим точку останова по адресу 004E4322. Дальше запускаем игру, пропускаем первую проверку пустого серийника, и второй раз останавливаемся при проверке введенной строки регистрации. Переходим в пошаговую трассировку и аккуратно смотрим на все происходящее.
  1. code:004E4330                 call    sub_4BABDE
  2. code:004E4335                 add     esp, 4
  3. code:004E4338                 mov     ebx, eax
  4. code:004E433A                 push    ebx
  5. code:004E433B                 call    sub_486205
  6. code:004E4340                 add     esp, 4
  7. code:004E4343                 mov     ebx, eax
  8. code:004E4345                 cmp     dword ptr [ebx+8], 0Bh
  9. code:004E4349                 jz      short loc_4E4355
  10. code:004E434B                 mov     eax, 0
  11. code:004E4350                 jmp     loc_4E448B
Первая проверка - длина серийника без учета пробелов должна быть 0Bh символов, то есть 11 символов, если считать в десятичной системе. Не проблема, отпускаем отладчик, делаем тестовый серийник нужной длины и повторяем попытку регистрации.
  1. ; 7-й символ
  2. code:004E4355                 movzx   eax, word ptr [ebx+18h]
  3. code:004E4359                 mov     eax, eax
  4. code:004E435B                 push    eax
  5. code:004E435C                 call    sub_485D1C
  6. code:004E4361                 add     esp, 4
  7. code:004E4364                 push    eax
  8. code:004E4365                 call    sub_4863E1
  9. code:004E436A                 add     esp, 4
  10. code:004E436D                 add     esi, eax
  11. ; 8-й символ
  12. code:004E436F                 movzx   eax, word ptr [ebx+1Ah]
  13. code:004E4373                 mov     eax, eax
  14. code:004E4375                 push    eax
  15. code:004E4376                 call    sub_485D1C
  16. code:004E437B                 add     esp, 4
  17. code:004E437E                 push    eax
  18. code:004E437F                 call    sub_4863E1
  19. code:004E4384                 add     esp, 4
  20. code:004E4387                 add     esi, eax
  21. ; 9-й символ
  22. code:004E4389                 movzx   eax, word ptr [ebx+1Ch]
  23. code:004E438D                 mov     eax, eax
  24. code:004E438F                 push    eax
  25. code:004E4390                 call    sub_485D1C
  26. code:004E4395                 add     esp, 4
  27. code:004E4398                 push    eax
  28. code:004E4399                 call    sub_4863E1
  29. code:004E439E                 add     esp, 4
  30. code:004E43A1                 add     esi, eax
  31. ; 10-й символ
  32. code:004E43A3                 movzx   eax, word ptr [ebx+1Eh]
  33. code:004E43A7                 mov     eax, eax
  34. code:004E43A9                 push    eax
  35. code:004E43AA                 call    sub_485D1C
  36. code:004E43AF                 add     esp, 4
  37. code:004E43B2                 push    eax
  38. code:004E43B3                 call    sub_4863E1
  39. code:004E43B8                 add     esp, 4
  40. code:004E43BB                 add     esi, eax
  41. ; Разделить сумму на 10
  42. code:004E43BD                 mov     ecx, 0Ah
  43. code:004E43C2                 mov     eax, esi
  44. code:004E43C4                 cdq
  45. code:004E43C5                 idiv    ecx
  46. code:004E43C7                 mov     esi, edx
  47. ; Сравнить остаток с 11 символом
  48. code:004E43C9                 movzx   eax, word ptr [ebx+20h]
  49. code:004E43CD                 mov     eax, eax
  50. code:004E43CF                 push    eax
  51. code:004E43D0                 call    sub_485D1C
  52. code:004E43D5                 add     esp, 4
  53. code:004E43D8                 push    eax
  54. code:004E43D9                 call    sub_4863E1
  55. code:004E43DE                 add     esp, 4
  56. code:004E43E1                 cmp     esi, eax
  57. code:004E43E3                 jz      short loc_4E43EF
  58. code:004E43E5                 mov     eax, 0
  59. code:004E43EA                 jmp     loc_4E448B
Вторая проверка. Символы с 7 по 10 преобразуются в соответствующие им числа, затем суммируются. Полученный результат делится на 10, и остаток от деления должен равняться числовому значению 11 символа. Для простоты вычислений их можно записать последовательностью нулей.
  1. code:004E43EF                 push    offset off_5418A0
  2. ; 2-й символ
  3. code:004E43F4                 movzx   eax, word ptr [ebx+0Eh]
  4. code:004E43F8                 mov     eax, eax
  5. code:004E43FA                 push    eax
  6. code:004E43FB                 call    sub_485D1C
  7. code:004E4400                 add     esp, 4
  8. code:004E4403                 push    eax
  9. code:004E4404                 call    sub_485FA2
  10. code:004E4409                 add     esp, 8
  11. code:004E440C                 cmp     eax, 0
  12. code:004E440F                 jz      short loc_4E4418
  13. code:004E4411                 mov     eax, 0
  14. code:004E4416                 jmp     short loc_4E448B
Третья проверка выполняется со вторым символом серийника. После двух преобразований должно получиться нулевое значение. При этом из символа "0" получается значение 0FFFFFFDEh, из символа "1" получается 0FFFFFFDFh, и так далее. Нехитрым вычислением получаем, что искомый символ, дающий после преобразования нулевое значение, это "R".
  1. ; Символ "3"
  2. code:004E4418                 movzx   eax, ds:word_5418BC
  3. code:004E441F                 mov     eax, eax
  4. code:004E4421                 push    eax
  5. code:004E4422                 call    sub_485D1C
  6. code:004E4427                 add     esp, 4
  7. code:004E442A                 push    eax
  8. ; 4-й символ
  9. code:004E442B                 movzx   eax, word ptr [ebx+12h]
  10. code:004E442F                 mov     eax, eax
  11. code:004E4431                 push    eax
  12. code:004E4432                 call    sub_485D1C
  13. code:004E4437                 add     esp, 4
  14. code:004E443A                 push    eax
  15. code:004E443B                 call    sub_485FA2
  16. code:004E4440                 add     esp, 8
  17. code:004E4443                 cmp     eax, 0
  18. code:004E4446                 jz      short loc_4E444F
  19. code:004E4448                 mov     eax, 0
  20. code:004E444D                 jmp     short loc_4E448B
Следующая проверка. Четвертый символ серийника преобразуется в число, затем из него вычитается тройка, полученная из текстовой константы. Результат должен быть равен нулю. Очевидно, что этому условию соответствует только символ "3".
  1. ; Символ "8"
  2. code:004E444F                 movzx   eax, ds:word_5418BE
  3. code:004E4456                 mov     eax, eax
  4. code:004E4458                 push    eax
  5. code:004E4459                 call    sub_485D1C
  6. code:004E445E                 add     esp, 4
  7. code:004E4461                 push    eax
  8. ; 5-й символ
  9. code:004E4462                 movzx   eax, word ptr [ebx+14h]
  10. code:004E4466                 mov     eax, eax
  11. code:004E4468                 push    eax
  12. code:004E4469                 call    sub_485D1C
  13. code:004E446E                 add     esp, 4
  14. code:004E4471                 push    eax
  15. code:004E4472                 call    sub_485FA2
  16. code:004E4477                 add     esp, 8
  17. code:004E447A                 cmp     eax, 0
  18. code:004E447D                 jz      short loc_4E4486
  19. code:004E447F                 mov     eax, 0
  20. code:004E4484                 jmp     short loc_4E448B
И последняя проверка. Очень похожа на предыдущую, только берется 5-й символ серийника и константа "8". Правильное значение, надеюсь, объяснять не надо. Остальные символы в проверке не участвуют и могут быть любыми.

Осталось собрать все вместе. Итоговый серийный номер будет иметь вид "XRX38X00000". Закрываем отладчик, запускаем игру и пробуем регистрацию с найденным серийным номером.

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

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

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

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

Комментарии

Отзывы посетителей сайта о статье
бурундук (05.05.2018 в 03:13):
ЦитатаА мне такие вот игры не нравятся.
Они подразумевают, что решение существует, ( - иначе о чём игра ?..)
однако в жизни и так полно не менее сложных заморочек,
которые к тому же решение имеют далеко не всегда.

Как то у вас логики нету. Открою секрет - во всех играх существует решение. Иначе - зачем тогда игры?

Подскажите - сколько всего уровней в вылеченной игре? я прошёл только 87 уровней и дальше не видно уровней. Но я ее не ломал - использовал песочницу. После очистки песочницы - счетчик прекрасно скидывается.

Сам нашёл ответ - всего 87 уровней и есть. Жаль что так мало. Я их как орешки теперь щёлкаю.
user (21.04.2018 в 20:54):
Что-то игруля совсем паскудно работает - замирает, дёргается..
Наверное, требует дополнительно каких-то графических библиотек в системе.
user (21.04.2018 в 13:58):
Цитатабурундук (18.04.2018 в 05:25):
Спасибо за наводку. Очень интересная игра для мозгов. Собираю такие игры

А мне такие вот игры не нравятся.
Они подразумевают, что решение существует, ( - иначе о чём игра ?..)
однако в жизни и так полно не менее сложных заморочек,
которые к тому же решение имеют далеко не всегда.
user (21.04.2018 в 13:44):
Новая версия патчится похожим образом,
только строчки с месиджами они попрятали,
процедуру проверки найти сложнее.
user (21.04.2018 в 13:20):
Та ссылка, что я дал в прошлом посте, рабочая.
Правда, там уже качается другая версия, - не та, что описана в статье.
ManHunter (21.04.2018 в 13:16):
По моей истории загрузок ссылки битые, и на сайте нет ссылок на эту страницу. Да и версия другая, алгоритм подбора серийника не срабатывает.
user (21.04.2018 в 13:06):
>> И игру Theseus and the Minotaur вы там тоже не найдете, все ссылки битые.

--Ну почему же? - Скачивается нормально отсюда:
www.kristanix.com/theseusandtheminotaur/

Вот яндекс-диск как раз недоступен напрямую, а из-под проксей не качается.
бурундук (18.04.2018 в 05:25):
Спасибо за наводку. Очень интересная игра для мозгов. Собираю такие игры

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

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

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