Blog. Just Blog

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

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

Реверси - одна из моих любимых компьютерных игрушек. Чтобы не привыкать к одному алгоритму игры, периодически я ищу новые разновидности реверси от разных авторов, и вот однажды я обнаружил интересный вариант - Daisy Reversi. Необычность этой программы в том, что можно менять размер игровой доски, а главное, что можно настраивать логику игры компьютера. Весь кайф от игры портила необходимость выложить почти двадцатку баксов за регистрацию. Не то, чтобы для меня это какая-то запредельная сумма, просто я еще со времен MS-DOS придерживаюсь принципа "soft must be free".

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

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

Наг-скрин при выходе из программы
Наг-скрин при выходе из программы

При попытке неправильной регистрации игра показывает сообщение "Sorry, you entered a wrong registration code".

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

Главный исполняемый файл накрыт старой версией упаковщика ASPack. В автоматическом режиме он снимается как минимум несколькими инструментами, но если хватает навыков, то за несколько минут файл распаковывается вручную.

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

Теперь в распакованном файле можно поискать строку сообщения. Тут ничего сложного, все хранится в открытом виде.

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

Теперь посмотрим код, где эта строка используются. Код комментировать не буду, все должно быть понятно.
  1. CODE:004A4A2E                 call    sub_40526C
  2. CODE:004A4A33                 mov     eax, [ebp-14h]
  3. CODE:004A4A36                 mov     edx, offset dword_4A50E0
  4. CODE:004A4A3B                 call    sub_405158
  5. CODE:004A4A40                 jz      short loc_4A4A7F
  6. CODE:004A4A42 loc_4A4A42:
  7. CODE:004A4A42                 lea     edx, [ebp-1Ch]
  8. CODE:004A4A45                 mov     eax, [esi+30Ch]
  9. CODE:004A4A4B                 call    sub_4711F0
  10. CODE:004A4A50                 cmp     dword ptr [ebp-1Ch], 0
  11. CODE:004A4A54                 jnz     short loc_4A4A62
  12. CODE:004A4A56                 mov     eax, offset aYouHaveToEnt_0
  13. ; "You have to enter your registration cod"...
  14. CODE:004A4A5B                 call    sub_4358B8
  15. CODE:004A4A60                 jmp     short loc_4A4A6C
  16. CODE:004A4A62 ; ------------------------------
  17. CODE:004A4A62 loc_4A4A62:
  18. CODE:004A4A62                 mov     eax, offset aSorryYouEntere
  19. ; "Sorry, you entered a wrong registration"...
  20. CODE:004A4A67                 call    sub_4358B8
  21. CODE:004A4A6C loc_4A4A6C:
  22. CODE:004A4A6C                 mov     eax, [esi+30Ch]
  23. CODE:004A4A72                 mov     edx, [eax]
  24. CODE:004A4A74                 call    dword ptr [edx+0C4h]
  25. CODE:004A4A7A                 jmp     loc_4A5048
  26. CODE:004A4A7F ; ------------------------------
  27. ; Сообщение об успешной регистрации
  28. CODE:004A4A7F loc_4A4A7F:
  29. CODE:004A4A7F                 push    offset aPleaseCheckYou
  30. ; "Please check your registration data.\n\r\n"...
  31. CODE:004A4A84                 lea     edx, [ebp-20h]
  32. CODE:004A4A87                 mov     eax, [esi+300h]
  33. CODE:004A4A8D                 call    sub_4711F0
  34. CODE:004A4A92                 push    dword ptr [ebp-20h]
  35. CODE:004A4A95                 push    offset dword_4A51E0
Выполняется несколько проверок, чтобы был введен серийник и регистрационное имя, затем выполняется какая-то неявная проверка, после которой выводится или сообщение о неправильной регистрации или выводится запрос на подтверждение регистрационных данных. Это подтверждение и является признаком успешной регистрации. Вроде бы все понятно, но в коде нет вызовов функций явной проверки серийника, нет сравнений или установки флагов "зарегистрировано", привязаться совершенно не к чему. Так что здесь ограничимся патчами условных переходов, чтобы игра принимала абсолютно любые регистрационные данные.

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

Но, как вы можете догадаться, в конечном итоге нам это все равно ничего не даст. Игра остается незарегистрированной, все ограничения на месте. Надо искать зацепки в другом месте, например, в сообщении о невозможности загрузить сохраненную игру.
  1. ; Сравнить ячейку памяти с константой 450h
  2. CODE:004B2C37                 cmp     [ebp+var_8], 450h
  3. CODE:004B2C3E                 jz      short loc_4B2C4E
  4. CODE:004B2C40                 mov     eax, offset aYouWillBeAbleT
  5. ; "You will be able to load the saved posi"...
  6. CODE:004B2C45                 call    sub_490CB8
  7. CODE:004B2C4A                 test    al, al
Вот, уже интереснее. У нас появилась приметная константа 450h, с которой сравнивается какая-то ячейка памяти. Посмотрим и другие сообщения, которые появляются в триальной версии.
  1. CODE:004B37FD                 call    sub_4B2E34
  2. CODE:004B3802                 cmp     eax, 450h
  3. CODE:004B3807                 jz      short loc_4B384C
  4. CODE:004B3809                 mov     eax, offset aTheAbilityToLo
  5. ; "The ability to load the saved position "...
  6. CODE:004B380E                 call    sub_490CB8
  7. CODE:004B3813                 test    al, al
Ага, снова сравнение и снова с константой 450h. Смотрим дальше.
  1. CODE:004B490A                 cmp     eax, 3
  2. CODE:004B490D                 jl      short loc_4B4972
  3. CODE:004B490F                 call    sub_4B3EF8
  4. CODE:004B4914                 cmp     eax, 450h
  5. CODE:004B4919                 jz      short loc_4B4972
  6. CODE:004B491B                 mov     eax, offset aTheUndoFeature
  7. ; "The undo feature is restricted in the t"...
  8. CODE:004B4920                 call    sub_490CB8
  9. CODE:004B4925                 test    al, al
Во всех трех найденных участках кода вызываются разные функции, но неизменно выполняется проверка результата с константой 450h. Есть подозрение, что это число и есть признак зарегистрированной программы. Но в коде нет ни одной инициализации чего-либо этим значением, только сравнения, и это значительно усложняет анализ. Похоже, что в каждой проверке по какому-то алгоритму из серийника заново вычисляется некое контрольное значение, и оно должно быть 450h. Я не придумал ничего лучше, чем найти все операции сравнения вида CMP ???, 450h и пропатчить все условные переходы, основанные на этих сравнениях. Таких переходов у меня получилось больше десятка, это не считая патчей условных переходов в окне регистрации. Не самый красивый способ решения проблемы, знаю.

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

После всей этой обширной хирургии программа стала чувствовать себя намного лучше. Пропали наг-окна при запуске и выходе, разблокирована возможность сохранять и загружать игру, больше не ограничивается количество откатов хода, а в окне "О программе" красуется введенное регистрационное имя. Стоит отметить, что защита оказалась неплохой: неявные проверки, зашифрованные строки, "размазанные" по всему коду подсчеты контрольных значений. Если бы все это более грамотно реализовать, то для обхода всех проверок пришлось бы повозиться гораздо дольше. Так что спасибо автору за тренировку мозгов при копании кода и, конечно же, за увлекательную игрушку.

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

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

Комментарии

Отзывы посетителей сайта о статье
ManHunter (31.07.2016 в 22:29):
По прямой ссылке с сайта тоже не даст скачать. Только браузером и только через заход на исходную статью.
X-Wing Top Ace (31.07.2016 в 21:25):
Цитатане дает скачать

Скачивайте здесь: http://www.manhunter.ru/downlo...ACK.2.3.zip, а то рыгхост и впрямь не позволяет.
hatmaster (04.07.2015 в 23:13):
ЦитатаХотя прога действительно оказалась незаслуженно забыта и все ссылки дохлые. Закинул на рыгхост


X-Wing Top Ace, можешь поправить ссылку, не дает скачать
X-Wing Top Ace (07.03.2015 в 00:20):
Цитатадавай ссылку на сей мегапревад!

Какой "мегапревад"? Я написАл про UN-PACK 2.3 - распаковщик разработки SnowPanther'а, выложенный в паблик еще во времена бибиэсинга. Что-то он распаковывает сам, а на что-то натравливает готовые распаковщики, собранные в отдельный подкаталог.

Хотя прога действительно оказалась незаслуженно забыта и все ссылки дохлые. Закинул на рыгхост: http://rghost.ru/7sBpNfyv9
R U B O A R D M A N (06.03.2015 в 20:38):
ЦитатаС армой, в том числе последней, прекрасно справляется армагеддон

Иногда теряется OEP. Может есть способ его найти после Армы?
ManHunter (01.03.2015 в 18:58):
CHimpReс очень хорошо справляется с импортом, я обычно им восстанавливаю.
brute (01.03.2015 в 17:35):
Имхо, перспективным методом в программах такого типа может быть следующий: после распаковки удалить в ресурсах наг-окно и отлавливить сообщение об ошибке. В этом случае получается точка "ближе" к "байту зарегистрированности" программы.
п.с. с армой всё получилось: похоже, влияет кривость версии ХП, или лапы выпрямляются:). Тоже заметил, что ImpREC иногда не может восстановить импорт, Scylla_v0.9.6a - в этом плане получше будет.
п.с.2. файл с яндекс-диска удалил, так как в нем из-за кривого импорта не работал звук. Если файл правильно распакован, то  места патча (ниже) вполне вылечивают прогу.
brute (27.02.2015 в 19:15):
to X-Wing Top Ace
раз назвался, давай ссылку на сей мегапревад!
п.с. мне хочется ещё поломать эту прогу, восстановить как следует импорт и подумать над алгоритмом кейгена.
X-Wing Top Ace (27.02.2015 в 10:55):
Цитатамне QuickUnpack не помог

Мне тоже. ;) По той простой причине, что я им и не распаковывал. QuickUnpack и UN-PACK 2.3 - это два разных распаковщика, второй пользую постоянно. Ну и ManHunter уже написАл про ArmaGeddon.
ManHunter (25.02.2015 в 19:18):
С армой, в том числе последней, прекрасно справляется армагеддон, особенно хорошо он работает именно на XP. Он же и дампит, и восстанавливает все что надо, какой смысл делать это вручную?
brute (25.02.2015 в 17:07):
мне QuickUnpack не помог, на ХП криво анпакает, на W7 тоже дамп не рабочий/синька. Скрипты ОЛИ тоже утомился подбирать - их полсотни для ASP. Понажимал немного F8/F4, снял дамп плагином OllyDump (если бы не этот плагин, то не знаю что ещё делать). Затем запатчил пару мест:
Address         Old           New                                         
004A49D5     JNZ 4A49F4   JMP 4A49EF                 
004ABA44     JE 4ABA4B    JMP 4ABBF0
004B2C3E     JE 4B2C4E    JMP 4B2C4E
004B3807     JE 4B384C    JMP 4B384C
004B48AC     JE 4B48F4    JMP 4B4972
004B65C2     JNZ 4B6696   JMP 4B6696
регистрация не требуется.
п.с. ManHunter - научи правильно снимать дампы и восстанавливать импорт/ресурсы!!! Проги типа ImpREC не помогают (на последних версиях армы в том числе).

https://yadi.sk/d/h1jH7EmZetFnC
Doxtur (24.02.2015 в 11:31):
Ептить, простите за выражение, ввел любой серийник - поставил бряки и смотри что сравнивается с константой 450h. Хотел перебором взять - обломался, ну и плюс кейген есть, так что желание пропало.
X-Wing Top Ace (24.02.2015 в 08:51):
ЦитатаASPack. В автоматическом режиме он снимается как минимум несколькими инструментами

Старый добрый UN-PACK 2.3 распаковал без граблем.

Цитатаограничимся патчами условных переходов, чтобы игра принимала абсолютно любые регистрационные данные.

...и тут фигакс - и ничего не поломалось! Пришлось хирургически вмешиваться дальше, заменяя все новые коды команд условного перехода на 0EBh. Очень наглядный пример, почему, если можно не материться в коде, в нем не надо материться.

ЦитатаВо всех трех найденных участках кода вызываются разные функции, но неизменно выполняется проверка результата с константой 450h.

А сделать в этих трех рутинах принудительный возврат 450h не пробовали? Я сам еще гаму не смотрел (как раз сижу на бюллетне, несварение головы прилагается, порассуждать в каментах могу, а самому крякать... есть опыт, потом переделывать пришлось), но если эти рутины - только чекушки, без каких-то полезностей, то именно туда и надо врезАть код подмены результата. Сталкиваться с подобным тоже приходилось, правда, там подпрограмм было две.
ManHunter (23.02.2015 в 18:01):
Отличная работа, не перевелись еще светлые головы :)
CryptoMaN (23.02.2015 в 17:38):
Приветствую, ManHunter.

Защита мне показалась не такой уж и запутанной. Навряд ли можно сказать, что проверка "размазана" по разным частям кода, ведь алгоритм во всех случаях один и тот же. Особенно просто он выглядит в обработчике TfrmAbout.FormCreate (004A5948). Авторы могли, например, менять проверочную константу или проверять в разных случаях другие участки ключа (для их готовой реализации это не потребовало бы значительных усилий), но они решили этого не делать, чем здорово облегчили задачу разбора защиты.

В качестве небольшой разминки, сделал кейген: http://rghost.ru/7PRtCbvKj.

Вот к примеру, рег. данные для вашего ника:
ManHunter / PCL
IO558-HBU558
ManHunter (23.02.2015 в 12:31):
Более того, они вообще не похожи друг на друга, поэтому пришлось так много патчить.
alex768 (23.02.2015 в 06:49):
Подпрограммы, которые должны вернуть 450h при правильном серийнике, очень сложны для анализа.
ManHunter (21.02.2015 в 12:10):
Можно и CASPR, я вообще руками распаковывал. FFI тут для наглядности.
Doxtur (21.02.2015 в 11:57):
ManHunter ну CASPR же ;)
Ностальгия )
user (21.02.2015 в 04:29):
>> ManHunter File Format Identifier you can share?

See here: http://www.manhunter.ru/underg..._faylov.html

Мда.. Хирургия.
Там ещё можно поправить прыжок при сравнении длины ключа в 12 символов.
Для удобства.
NemesiS (21.02.2015 в 02:04):
ManHunter File Format Identifier you can share?

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

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

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