Blog. Just Blog

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

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

Программа DeblurMyImage позволяет усилить резкость фотографий при ошибочном выборе точки фокусировки или при съемке в движении. Чудесного и кристально четкого результата, конечно, ожидать не стоит, но немного улучшить качество снимков для печати или публикации вполне можно. Особенно, когда это единственный кадр, а переснять нет никакой возможности. Главная шутка юмора в том, что DeblurMyImage по сути - всего лишь графическая надстройка над бесплатной библиотекой для работы с изображениями FreeImage. Так какого хрена мы должны выкладывать за эту надстройку почти 15 евро? Тем более, что со стороны аффтара DeblurMyImage были допущены грубейшие нарушения лицензии и условий использования библиотеки FreeImage.

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

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

Дальше нас оповещают, что незарегистрированная версия DeblurMyImage не будет сохранять отредактированные файлы. Это, собственно, и есть главное ограничение программы. И действительно, файл можно отредактировать, посмотреть что получилось, но при попытке сохранения вместо него появляется вот такое сообщение:

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

Это уже более удобная зацепка для анализа защиты, поищем текст сообщения в исполняемом файле. Он ничем не упакован, поэтому найдется строка в юникоде:

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

Переходим к дизассемблеру. Посмотрим, где и как эта строка используется.
  1. .text:0042187B                 push    ecx             ; lpFileName
  2. .text:0042187C                 push    400h            ; nSize
  3. .text:00421881                 push    offset word_4A481C
  4. ; lpReturnedString
  5. .text:00421886                 push    offset aCannotSaveTheI
  6. ; "Cannot save the image due to unregister"...
  7. .text:0042188B                 push    offset aString72 ; "string72"
  8. .text:00421890                 lea     edx, [esp+830h+Dst]
  9. .text:00421894                 push    edx             ; lpAppName
  10. .text:00421895                 call    esi ; GetPrivateProfileStringW
Если посмотреть документацию по функции GetPrivateProfileString, то станет ясно, что тут программа пытается загрузить строку из внешнего языкового файла, а, если такого не найдено, то по умолчанию используется искомая строка. И word_4A481C - это указатель на участок памяти, куда эта строка будет записана для дальнейшего использования. Значит теперь посмотрим на него:
  1. .data:004A481C ; const WCHAR word_4A481C
  2. .data:004A481C word_4A481C     dw ?
  3. ; DATA XREF: sub_40DDB0+2276
  4. ; sub_420F10+971
Всего две перекрестные ссылки. Одна, как мы уже выяснили, это инициализация строки. Очевидно, что оставшаяся - место, где эта строка используется, то есть выводится на экран в виде сообщения. Так и есть:
  1. ; Вызвать какую-то функцию проверки
  2. .text:00410011                 call    sub_40D170
  3. ; Если она вернула AL=0, то вывести сообщение на экран, иначе перейти
  4. ; к сохранению файла 
  5. .text:00410016                 test    al, al
  6. .text:00410018                 mov     byte_4C5734, al
  7. .text:0041001D                 jnz     short loc_41004B
  8. .text:0041001F                 push    0               ; uType
  9. .text:00410021                 push    offset word_49481C ; lpCaption
  10. ; Вот она наша строка сообщения
  11. .text:00410026                 push    offset word_4A481C ; lpText
  12. .text:0041002B                 push    edi             ; hWnd
  13. ; А вот и функция показа сообщения
  14. .text:0041002C                 call    ds:MessageBoxW
  15. .text:00410032                 xor     eax, eax
  16. .text:00410034                 pop     edi
  17. .text:00410035                 pop     esi
  18. .text:00410036                 pop     ebx
  19. .text:00410037                 mov     ecx, [esp+3DF4h+var_4]
  20. .text:0041003E                 xor     ecx, esp
  21. .text:00410040                 call    sub_425146
  22. .text:00410045                 mov     esp, ebp
  23. .text:00410047                 pop     ebp
  24. .text:00410048                 retn    10h
  25. .text:0041004B ; ------------------------------------------
  26. .text:0041004B loc_41004B:
  27. .text:0041004B                 push    800h            ; size_t
  28. .text:00410050                 lea     eax, [esp+3E04h+Dst]
  29. .text:00410057                 push    0               ; int
  30. .text:00410059                 push    eax             ; void *
  31. ...
Дальше и ходить никуда не надо, все и так ясно. Вызывается функция проверки, по ее результату или выводится на экран сообщение о невозможности сохранения по причине незарегистрированности или выполняется переход на сохранения файла. Осталось посмотреть на функицю проверки по адресу 40D170:
  1. .text:0040D170                 push    ecx
  2. .text:0040D171                 push    ebx
  3. .text:0040D172                 push    1
  4. .text:0040D174                 call    sub_40C980
  5. .text:0040D179                 push    0
  6. .text:0040D17B                 mov     bl, al
  7. .text:0040D17D                 call    sub_40C980
  8. .text:0040D182                 add     esp, 8
  9. .text:0040D185                 mov     [esp+8+var_1], al
  10. .text:0040D189                 call    sub_40D030
  11. .text:0040D18E                 test    bl, bl
  12. .text:0040D190                 pop     ebx
  13. .text:0040D191                 jnz     short loc_40D19A
  14. .text:0040D193                 cmp     [esp+4+var_1], 0
  15. .text:0040D198                 jz      short loc_40D1A5
  16. .text:0040D19A loc_40D19A:
  17. .text:0040D19A                 test    al, al
  18. .text:0040D19C                 jnz     short loc_40D1A5
  19. .text:0040D19E                 mov     eax, 1
  20. .text:0040D1A3                 pop     ecx
  21. .text:0040D1A4                 retn
  22. .text:0040D1A5 ; ---------------------------------------------------
  23. .text:0040D1A5 loc_40D1A5:
  24. .text:0040D1A5                 xor     eax, eax
  25. .text:0040D1A7                 pop     ecx
  26. .text:0040D1A8                 retn
Если посмотреть все перекрестные ссылки на нее, то видно, что все они так или иначе связаны с триальным статусом. Это показ сообщений, открытие первого диалогового окна с регистрацией, активация пунктов меню. И везде используется регистр AL. Значит просто пропатчим эту функцию, чтобы она всегда возвращала AL=1. Это уже хорошо знакомая нам пара команд MOV AL,1 и RET, которые надо записать по адресу 0040D170. Сохраняем изменения, запускаем. Окно с предложением регистрации пропало, а при сохранении отредактированного файла вместо сообщения об ошибке появляется диалог выбора имени сохраняемого файла.

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

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

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

Комментарии

Отзывы посетителей сайта о статье
JokerBaD (01.03.2013 в 17:28):
Да, IDA вещь, спасибо!А есть действительно непобедимое ПО, 3-и дня провел в IDA'шки!Весь листок изрисовал схемами.Привязка к железу + проверка суммы CRC+Ген.ключа через инет.Полная ж.Будем набираться опыта.Спсибо за статьи.
Сэнан (19.02.2013 в 00:55):
Понял, действительно, спасибо.
ManHunter (18.02.2013 в 14:27):
Сэнан, видимо потому что правильнее патчить процедуру проверки, а нее вызовы. Это хорошо что здесь вызов один, а если их 100500 и из них треть на виду, треть отрабатывает по таймеру, а треть дергаются еще как-нибудь неявно? Надо приучаться делать правильно.
Сэнан (18.02.2013 в 09:59):
Хотел бы все-таки уточнить, вариант, предложенный мной ниже, чем-то не подходит?
ManHunter (17.02.2013 в 04:59):
IDA Pro, лучше пока не придумали
JokerBaD (17.02.2013 в 01:20):
ManHunter, прошу прощения, какой софтиной дизассемблеруйте?
ManHunter (15.02.2013 в 16:34):
Ну ясен хуй, это же только для лохов Правила написаны, чётким пацанам буковки читать западло. MaddMaxx у нас чёткий и занятой пацан, чо ему вникать в какие-то писанины, надо ж армадиллу быстрее ломать. Только руки кривые, и даже качественным инструментарием пользоваться не в состоянии. А это тебе небольшой пруфец, чтобы болтал поменьше:
http://s020.radikal.ru/i717/13...c0cf3c6f.gif
Остальным под эту канитель не подписываться, она вас не касается.
MaddMaxx (15.02.2013 в 12:44):
Ни хера не могу попасть в приватную помощь ...
Изначально - ТЫСЯЧУ ИЗВИНЕНИЙ ! Я НЕ ПО ТЕМЕ !!!

[весь остальной бред удален]
Сэнан (14.02.2013 в 16:52):
А почему нельзя просто сделать от адреса 00410011 сделать JMP loc_41004B ?
Даже в функцию проверки заходить не понадобится, или не так?
Never (11.02.2013 в 12:27):
Ну мало ли, мож прорыв! А так хз что хуже шум или софт.
ManHunter (11.02.2013 в 12:09):
И шум повышается. Очевидно же. -КО
Never (11.02.2013 в 12:09):
Резкость повышается, а что на счет шума?
ManHunter (11.02.2013 в 00:44):
Угу, а следующий абзац гласит:

When using FreeImage in your open source or commercial application, you are REQUIRED to :
- distribute the license (GNU GPL or FIPL) you choosed with your application (i.e. the TXT file)
- provide a suitable acknowledgement, either in the program's "About" box or in the user's manual (or both).

И чо-то я никаких упоминаний об использовании библиотеки и файла лицензии не наблюдаю.
Anon (11.02.2013 в 00:38):
У FreeImage двойное лицензирование и FreeImage Public License (FIPL) вроде бы позволяет "to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, or as part of a Larger Work".
ManHunter (10.02.2013 в 14:03):
Я в фотошопе пользуюсь только контурной резкостью, так что не могу сравнить. DeblurMyImage, кстати, есть и в виде плагина для фотошопа.
Zhelezyaka (10.02.2013 в 10:53):
Скриншот зачётный)))
Если сравнивать с фотошопом, резкость качественней увеличивается?

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

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

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