Blog. Just Blog

Исследование защиты программы Batch Watermark Creator

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

Как легко догадаться из названия, программа Batch Watermark Creator предназначена для нанесения водяных знаков на изображения. Действительно, это инструмент для пакетного нанесения графических и текстовых маркеров на изображения. Если вы публикуете фотографии на открытых ресурсах и не хотите, чтобы ими воспользовался кто-то еще без вашего ведома, то такая маркировка в большинстве случаев может вам помочь. О других возможностях программы вы можете прочитать на ее офсайте. О том, как сделать ее бесплатной, вы можете прочитать здесь.

Как обычно начинаем со скачивания дистрибутива, устанавливаем, смотрим, что у нас получается. У нас получается ничем не упакованный основной файл BWC.exe, два каких-то редактора и вспомогательная утилита для регистрации RegNow.exe. Начнем с главного файла, отправляем его в дизассемблер и параллельно посмотрим на проявления триальности.

Ограничения триальной версии программы
Ограничения триальной версии программы

Их два. Надпись о том, что программа не зарегистрирована в окне "О программе" и водяной знак в виде пунктирной линии на всех сохраненных фотографиях.

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

Модуль ввода и проверки серийного номера вынесен в отдельную утилиту, которая вызывается при попытке регистрации. Обратите внимание, что в программе используется привязка к компьютеру, на скриншоте она обозначена как "Machine Code". Это не есть хорошо. Поищем какую-нибудь из строчек, которые относятся к незарегистрированной программе.

Строчки в ресурсах
Строчки в ресурсах

В ресурсах обнаруживаются строчки из окна "О программе" для зарегистрированной и незарегистрированной версий программы. Нас интересует та, которая "UNREGISTERED". Она имеет индекс 64871 или 0FD67h в шестнадцатеричной системе счисления. Ищем что-то подобное в дизассемблере. Как и положено для программ на Дельфи, сперва находится указатель на ресурс:
  1. CODE:0059A8E4 off_59A8E4      dd offset hModule
  2. CODE:0059A8E8                 dd 0FD67h
Дальше идет указатель на указатель:
  1. DATA:005DDA58 off_5DDA58      dd offset off_59A8E4
  2. ; DATA XREF: _TfrmAbout_FormCreate+EE
Теплее, теплее, уже видна ссылка на форму "О программе". Еще один переход по перекрестной ссылке и вот долгожданный код с условными переходами:
  1. ; Проверить байт по адресу off_5DDD90
  2. CODE:0059B87B                 mov     eax, ds:off_5DDD90
  3. CODE:0059B880                 cmp     byte ptr [eax], 0
  4. ; Если он равен нулю, то вывести сообщение "UNREGISTERED"
  5. CODE:0059B883                 jz      short loc_59B8D3
  6. CODE:0059B885                 lea     edx, [ebp+var_10]
  7. CODE:0059B888                 mov     eax, ds:off_5DDD7C
  8. ; Загрузить сообщение "REGISTERED"
  9. CODE:0059B88D                 call    @System@LoadResString
  10. CODE:0059B892                 mov     edx, [ebp+var_10]
  11. CODE:0059B895                 mov     eax, [ebp+var_4]
  12. CODE:0059B898                 mov     eax, [eax+324h]
  13. CODE:0059B89E                 call    @Controls@TControl@SetText
  14. ; Controls::TControl::SetText(System::AnsiString)
  15. CODE:0059B8A3                 lea     edx, [ebp+var_14]
  16. CODE:0059B8A6                 mov     eax, ds:off_5DD564
  17. CODE:0059B8AB                 call    @System@LoadResString
  18. ; System::LoadResString(System::TResStringRec *)
  19. CODE:0059B8B0                 lea     eax, [ebp+var_14]
  20. CODE:0059B8B3                 mov     edx, ds:off_5DD638
  21. CODE:0059B8B9                 mov     edx, [edx]
  22. CODE:0059B8BB                 call    @System@@LStrCat$qqrv
  23. ; System::__linkproc__ LStrCat(void)
  24. CODE:0059B8C0                 mov     edx, [ebp+var_14]
  25. CODE:0059B8C3                 mov     eax, [ebp+var_4]
  26. CODE:0059B8C6                 mov     eax, [eax+328h]
  27. CODE:0059B8CC                 call    @Controls@TControl@SetText
  28. ; Controls::TControl::SetText(System::AnsiString)
  29. CODE:0059B8D1                 jmp     short loc_59B901
  30. CODE:0059B8D3 ; ---------------------------------------------
  31. CODE:0059B8D3 loc_59B8D3:
  32. CODE:0059B8D3                 lea     edx, [ebp+var_18]
  33. CODE:0059B8D6                 mov     eax, ds:off_5DDA58
  34. ; Загрузить сообщение "UNREGISTERED"
  35. CODE:0059B8DB                 call    @System@LoadResString
  36. ; System::LoadResString(System::TResStringRec *)
  37. CODE:0059B8E0                 mov     edx, [ebp+var_18]
  38. CODE:0059B8E3                 mov     eax, [ebp+var_4]
  39. CODE:0059B8E6                 mov     eax, [eax+324h]
  40. CODE:0059B8EC                 call    @Controls@TControl@SetText
  41. ; Controls::TControl::SetText(System::AnsiString)
  42. CODE:0059B8F1                 mov     eax, [ebp+var_4]
  43. CODE:0059B8F4                 mov     eax, [eax+328h]
  44. CODE:0059B8FA                 xor     edx, edx
  45. CODE:0059B8FC                 call    @Controls@TControl@SetText
  46. ; Controls::TControl::SetText(System::AnsiString)
Код понятный. Проверяется байт по определенному адресу, если он равен нулю, то программа работает в триальном режиме, если он не равен нулю. то программа считается зарегистрированной. Значит нам надо найти код, который записывает в этот байт нулевое или ненулевое значение.

Перекрестные ссылки на проверочный байт
Перекрестные ссылки на проверочный байт

Глянем на перекрестные ссылки, касающиеся этого байта. Их не так много. По трем из них выполняются проверки, типа:
  1. CODE:005C6EA4                 mov     eax, ds:off_5DDD90
  2. CODE:005C6EA9                 cmp     byte ptr [eax], 0
  3. CODE:005C6EAC                 jnz     short loc_5C6EBC
А два участка кода как раз отвечают за инициализацию:
  1. CODE:005C8629                 mov     eax, ds:off_5DDD90
  2. CODE:005C862E                 mov     byte ptr [eax], 0
  3. ...
  4. ...
  5. ...
  6. CODE:005C8686                 mov     eax, ds:off_5DDD90
  7. CODE:005C868B                 mov     byte ptr [eax], 1
Не мудрствуя лукаво, заменим команду mov byte ptr [eax],0 по адресу 005C862E на инициализацию нужным нам значением, а именно mov byte ptr [eax],1

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

Сохраняем изменения и запускаем пропатченную программу. В окне "О программе" теперь надпись, что программа зарегистрирована (нет регистрационного имени, но это и не так важно), при сохранении файлов никаких предупреждений не выводится и никаких искажений на фотографии не накладывается. Значит цель достигнута. Все эти привязки к железу, вспомогательные утилиты для регистрации и прочие навороты удалось обойти изменением не то что одного байта, а даже одного единственного бита.

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

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

Комментарии

Отзывы посетителей сайта о статье
ManHunter (05.07.2014 в 00:00):
Там и без кейгена все патчится на раз-два. Я его релизил уже лет 7 назад. А вот строки всех сообщений пошифрованы. brute же этого хотел.
DimitarSerg (04.07.2014 в 23:54):
> поразбирай BWMeter
Не знаю какая там сложность по патчинку, патч-кейген делается за час, находим стандартные функции проверки подпсии Crypt*, заменяем rsa-1024 на свой, ваяем кейген. (конечно там есть один интересный момент, который я увидел впервые в защитах программа с проверкой сигны на МСКриптоАпи).
DagalProject (04.07.2014 в 09:05):
2655847 еще раз Спасибо. Прочитал эту статью, и больше таких глупых вопросов не задам.

Способы представления чисел

Двоичные (binary) числа – каждая цифра означает значение одного бита (0 или 1), старший бит всегда пишется слева, после числа ставится буква «b». Для удобства восприятия тетрады могут быть разделены пробелами. Например, 1010 0101b.
Шестнадцатеричные (hexadecimal) числа – каждая тетрада представляется одним символом 0...9, А, В, ..., F. Обозначаться такое представление может по-разному, здесь используется только символ «h» после последней шестнадцатеричной цифры. Например, A5h. В текстах программ это же число может обозначаться и как 0хА5, и как 0A5h, в зависимости от синтаксиса языка программирования. Незначащий ноль (0) добавляется слева от старшей шестнадцатеричной цифры, изображаемой буквой, чтобы различать числа и символические имена.
Десятичные (decimal) числа – каждый байт (слово, двойное слово) представляется обычным числом, а признак десятичного представления (букву «d») обычно опускают. Байт из предыдущих примеров имеет десятичное значение 165. В отличие от двоичной и шестнадцатеричной формы записи, по десятичной трудно в уме определить значение каждого бита, что иногда приходится делать.
Восьмеричные (octal) числа – каждая тройка бит (разделение начинается с младшего) записывается в виде цифры 0–7, в конце ставится признак «о». То же самое число будет записано как 245о. Восьмеричная система неудобна тем, что байт невозможно разделить поровну.
DagalProject (02.07.2014 в 23:21):
2655847

Спасибо.
2655847 (02.07.2014 в 22:59):
DagalProject

Преобразование 64871 = 0FD67h [h - шестнадцатеричное] для поиска в дизассемблере, IDA например.
DagalProject (02.07.2014 в 18:29):
Извините меня за глупый вопрос, но 64871 это FD67 в шестнадцатеричной системе счисления. Откуда взялось 0FD67h. Спасибо.
ManHunter (01.07.2014 в 09:13):
ЦитатаКогда на одну строку "UNREGISTERED" приходится несколько сотен левых (или нет) ссылок.

Точка останова на участок памяти. Сработает при фактическом обращении.
ЦитатаМожет, есть какие-нибудь "легкие" решения в этих случаях?

Если хочется чем-нибудь заняться, то посиди поразбирай BWMeter, там таких шифрованных строчек дофига и больше.
brute (01.07.2014 в 09:08):
ЦитатаВ ресурсах обнаруживаются строчки...

хочется увидеть более сложные примеры, когда ресурсы пошифрованы и строки в секции data пошифрованы (самой программой, без пакера). Когда на одну строку "UNREGISTERED" приходится несколько сотен левых (или нет) ссылок. Может, есть какие-нибудь "легкие" решения в этих случаях?
kaktustv (01.07.2014 в 00:59):
Для красоты можно создать в папке с программой файл User.dat с содержимым типа

[Setup]
RegCode=F751EE14C728
UserEmail=mail@mail.ru
UserName=Registered Userr

и окно "О программе" будет выглядеть наряднее!

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

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

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