Blog. Just Blog

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

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

ФотоВИНТАЖ - программа для реставрации фотографий. Она обладает простейшим интерфейсом, который освоит даже новичок, но при этом несет на борту большой набор инструментов для автоматической и ручной коррекции. До идеала далеко, но работать можно. Удаление пятен, царапин, разрывов и других дефектов, колоризация черно-белых снимков в один клик, исправление искаженных цветов на фотографиях - вот лишь малая часть возможностей. А большАя часть заключается в необходимости выкладывать больше двух косарей за максимальный вариант лицензии.

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

Визуальный осмотр начнем с поиска в файле характерных сигнатур типа "license", "trial", "registered" и тому подобных. Поиск выводит нас на вот такой любопытный блок в сегменте данных:
  1. .rdata:054404CA ; char aIstrial1[]
  2. .rdata:054404CA aIstrial1       db 'isTrial1',0
  3. .rdata:054404D3 a82r1           db '82R1',0
  4. .rdata:054404D8 aGl28           db 'GL28',0
  5. .rdata:054404DD a6hsd           db '6HSD',0
  6. .rdata:054404E2 ; char aStartcheck1[]
  7. .rdata:054404E2 aStartcheck1    db 'startCheck1',0
  8. .rdata:054404EE ; char aStartcheck1Tim[]
  9. .rdata:054404EE aStartcheck1Tim db 'startCheck1 timout',0
  10. .rdata:05440501 ; char aStartcheck2[]
  11. .rdata:05440501 aStartcheck2    db 'startCheck2',0
  12. .rdata:0544050D ; char aStartcheck2Tim[]
  13. .rdata:0544050D aStartcheck2Tim db 'startCheck2 timout',0
  14. .rdata:05440520 ; char aReadkey2[]
  15. .rdata:05440520 aReadkey2       db 'readKey2',0
  16. .rdata:05440529 ; char aIstrial2[]
  17. .rdata:05440529 aIstrial2       db 'isTrial2',0
  18. .rdata:05440532 aG2ua           db 'G2UA',0
  19. .rdata:05440537 a263s           db '263S',0
  20. .rdata:0544053C aCfgu           db 'CFGU',0
  21. .rdata:05440541 ; char aSendlicense[]
  22. .rdata:05440541 aSendlicense    db 'sendLicense',0
  23. .rdata:0544054D ; char aSendlicenseErr[]
  24. .rdata:0544054D aSendlicenseErr db 'sendLicense ERR_EMPTY_EMAIL',0
  25. .rdata:05440569 ; char aSendlicenseE_0[]
  26. .rdata:05440569 aSendlicenseE_0 db 'sendLicense ERR_EMPTY_SERIAL',0
  27. .rdata:05440586 ; char aSendlicenseE_1[]
  28. .rdata:05440586 aSendlicenseE_1 db 'sendLicense ERR_LICENSE_KEY',0
  29. .rdata:054405A2 ; char aLibistrial3[]
  30. .rdata:054405A2 aLibistrial3    db 'libIsTrial3',0
  31. .rdata:054405AE a1af            db '1AF',0
  32. .rdata:054405B2 a2rk            db '2RK',0
  33. .rdata:054405B6 a3np            db '3NP',0
  34. .rdata:054405BA ; char aLibisprofessio[]
  35. .rdata:054405BA aLibisprofessio db 'libIsProfessionalVersion',0
  36. .rdata:054405D3 ; char aIsprofessional[]
  37. .rdata:054405D3 aIsprofessional db 'isProfessionalVersion',0
  38. .rdata:054405E9 ; char aLibisstandardv[]
  39. .rdata:054405E9 aLibisstandardv db 'libIsStandardVersion',0
  40. .rdata:054405FE ; char aIsstandardvers[]
  41. .rdata:054405FE aIsstandardvers db 'isStandardVersion',0
  42. .rdata:05440610 ; char aLibispremiumve[]
  43. .rdata:05440610 aLibispremiumve db 'libIsPremiumVersion',0
  44. .rdata:05440624 a2638           db '2638',0
  45. .rdata:05440629 ; char aIspremiumversi[]
  46. .rdata:05440629 aIspremiumversi db 'isPremiumVersion',0
  47. .rdata:0544063A ; char aType_dd[]
  48. .rdata:0544063A aType_dd        db 'Type_DD',0
и к нему целая куча перекрестных ссылок. Я их тут почистил, чтобы не перегружать листинг. Начнем с первой строки "isTrial1". Она используется в двух функциях. Их текст целиком я приводить не буду, для понимания достаточно самого начала.
  1. .text:0052A2B0                 push    ebp
  2. .text:0052A2B1                 mov     ebp, esp
  3. .text:0052A2B3                 push    edi
  4. .text:0052A2B4                 push    esi
  5. .text:0052A2B5                 push    ebx
  6. .text:0052A2B6                 lea     esi, [ebp+var_2C]
  7. .text:0052A2B9                 lea     ebx, [ebp+var_30]
  8. .text:0052A2BC                 mov     edi, ecx
  9. .text:0052A2BE                 sub     esp, 6Ch
  10. .text:0052A2C1                 mov     ecx, ebx
  11. .text:0052A2C3                 mov     [ebp+var_2C], 2
  12. .text:0052A2CA                 mov     [ebp+var_28], 1D0h
  13. .text:0052A2D1                 mov     [ebp+var_24], offset a__VintageProte
  14. ; "../vintage/protect.cpp"
  15. .text:0052A2D8                 mov     [ebp+var_20], offset aBoolProtectIst
  16. ; "bool Protect::isTrial1()"
  17. .text:0052A2DF                 mov     [ebp+var_1C], offset aDefault_23
  18. ; "default"
  19. .text:0052A2E6                 mov     [esp], esi
  20. .text:0052A2E9                 call    ds:_ZNK14QMessageLogger5debugEv
  21. .text:0052A2EF                 sub     esp, 4
  22. .text:0052A2F2                 mov     ecx, ebx
  23. .text:0052A2F4                 mov     dword ptr [esp], offset a385213m_2
  24. ; "\x1B[38;5;213m"
  25. .text:0052A2FB                 call    sub_7AEC00
  26. .text:0052A300                 sub     esp, 4
  27. .text:0052A303                 mov     ecx, eax
  28. .text:0052A305                 mov     dword ptr [esp], offset aIstrial1
  29. ; "isTrial1"
  30. .text:0052A30C                 call    sub_7AEC00
  31. .text:0052A311                 sub     esp, 4
Как видно из названий модулей, этот код относится к защите и должен возвращать true или false. И, как легко догадаться, в случае зарегистрированной программы он должен вернуть именно false. Впечатываем в начало функции по адресу 0052A2B0 пару команд XOR EAX,EAX и RET.

Едем дальше. Вторая функция, где используется эта строка, также относится к защите, также возвращает true или false и, судя по названию, отвечает за проверку новых версий.
  1. .text:0052CB90                 push    ebp
  2. .text:0052CB91                 mov     ebp, esp
  3. .text:0052CB93                 push    edi
  4. .text:0052CB94                 push    esi
  5. .text:0052CB95                 push    ebx
  6. .text:0052CB96                 lea     eax, [ebp+var_30]
  7. .text:0052CB99                 sub     esp, 0CCh
  8. .text:0052CB9F                 mov     [ebp+var_AC], ecx
  9. .text:0052CBA5                 mov     [ebp+var_30], 2
  10. .text:0052CBAC                 mov     [esp], eax
  11. .text:0052CBAF                 mov     eax, ds:_ZNK14QMessageLogger5debugEv
  12. .text:0052CBB4                 lea     ecx, [ebp+var_40]
  13. .text:0052CBB7                 mov     [ebp+var_2C], 434h
  14. .text:0052CBBE                 mov     [ebp+var_28], offset a__VintageProte
  15. ; "../vintage/protect.cpp"
  16. .text:0052CBC5                 mov     [ebp+var_24], offset aBoolProtectChe
  17. ; "bool Protect::checkAndShowNews()"
  18. .text:0052CBCC                 mov     [ebp+var_20], offset aDefault_23
  19. ; "default"
  20. .text:0052CBD3                 mov     [ebp+var_B0], eax
  21. .text:0052CBD9                 call    eax ; _ZNK14QMessageLogger5debugEv
  22. .text:0052CBDB                 lea     ecx, [ebp+var_40]
  23. .text:0052CBDE                 sub     esp, 4
  24. .text:0052CBE1                 mov     dword ptr [esp], offset a385213m_2
  25. ; "\x1B[38;5;213m"
  26. .text:0052CBE8                 call    sub_7AEC00
  27. .text:0052CBED                 sub     esp, 4
  28. .text:0052CBF0                 mov     ecx, eax
  29. .text:0052CBF2                 mov     dword ptr [esp], offset aCheckandshowne
  30. ; "checkAndShowNews"
  31. .text:0052CBF9                 call    sub_7AEC00
  32. .text:0052CBFE                 sub     esp, 4
Новых версий мы не ожидаем, поэтому точно так же меняем ее начало на пару команд XOR EAX,EAX и RET.

По аналогии разбираемся с функциями, которые ссылаются на строки "isTrial2" и "libIsTrial3". Они очень похожи, приводить их тут не буду. На каждую строку по одной функции. Единственное отличие, что в функции "isTrial2" надо будет восстановить стек при возврате, там команды будут XOR EAX,EAX и RET 4.

Теперь разбираемся с типом лицензии. Если посмотреть на сайте, то наивысшая категория доступа ко всем инструментам - Professional. Возвращаемся к списку строк, находим "isProfessionalVersion", "isStandardVersion" и "isPremiumVersion". Все они должны вернуть true или false. Так как нам надо получить профессиональную лицензию, в начало функции "isProfessionalVersion" впечатываем MOV EAX,1 и RET, а в начала других - XOR EAX,EAX и RET. Тем самым при любом раскладе у нас будет нужный тип лицензии. Сохраняем изменения, запускаем. Триальных окон нет, сканирование и прочие инструменты работают, но не тут-то было.

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

Через некоторое время программа осчастливливает нас вот таким сообщением, после чего без вариантов завершает работу. По всей видимости одного факта наличия "лицензии" тут недостаточно, нужны какие-то реальные данные. По тексту ошибки выходим на следующий код:
  1. .text:00530CE0                 mov     dword ptr [esp+0Ch], 0FFFFFFFFh
  2. .text:00530CE8                 mov     dword ptr [esp+8], 0
  3. .text:00530CF0                 lea     ecx, [ebp+var_7C]
  4. .text:00530CF3                 mov     dword ptr [esp+4], offset aEnterYourEmail
  5. ; "Enter your Email."
  6. .text:00530CFB                 mov     dword ptr [esp], offset dword_8272AC
  7. .text:00530D02                 call    ds:_ZNK11QMetaObject2trEPKcS1_i
  8. .text:00530D08                 mov     eax, [ebp+var_80]
  9. .text:00530D0B                 mov     edx, [ebp+var_7C]
  10. .text:00530D0E                 lea     ecx, [ebp+var_7C]
  11. .text:00530D11                 sub     esp, 10h
  12. .text:00530D14                 mov     [ebp+var_80], edx
Выше и ниже еще куча вариантов ошибок, типа забаненных лицензий, уже активированных, неправильных форматов ключа, электронных почт и прочее. Прокручиваем это все до начала функции проверки.
  1. .text:00530940                 push    ebp
  2. .text:00530941                 mov     ebp, esp
  3. .text:00530943                 push    edi
  4. .text:00530944                 push    esi
  5. .text:00530945                 push    ebx
  6. .text:00530946                 lea     esi, [ebp+var_48]
  7. .text:00530949                 mov     edi, ecx
  8. .text:0053094B                 lea     ecx, [ebp+var_4C]
  9. .text:0053094E                 sub     esp, 8Ch
  10. .text:00530954                 mov     [ebp+var_48], 2
  11. .text:0053095B                 mov     ebx, [ebp+arg_0]
  12. .text:0053095E                 mov     [ebp+var_44], 555h
  13. .text:00530965                 mov     [ebp+var_40], offset a__VintageProte
  14. ; "../vintage/protect.cpp"
  15. .text:0053096C                 mov     [ebp+var_3C], offset aVoidProtectFin
  16. ; "void Protect::finishCheckLicense(CheckL"...
  17. .text:00530973                 mov     [ebp+var_38], offset aDefault_23
  18. ; "default"
  19. .text:0053097A                 mov     [esp], esi
  20. .text:0053097D                 call    ds:_ZNK14QMessageLogger5debugEv
  21. .text:00530983                 lea     ecx, [ebp+var_4C]
  22. .text:00530986                 sub     esp, 4
Тут возврат не предусмотрен, это уже финальный обработчик результата проверки лицензии. Так что впечатываем в начало команду RET 4, чтобы при возврате не поломать стек. Теперь на любой результат проверки будет делаться ничего.

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

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

Комментарии

Отзывы посетителей сайта о статье
Жека (13.04.2024 в 23:01):
Приветствую автора и тех кто в этой теме. Ломал я эту программу в 2022. Версия тогда была ФотоВИНТАЖ 3.25. Не знаю, как сейчас там обстоят дела, но в той была одна ненужная на мой взгляд и очень вредная кнопка Set as wallpaper - делает из просматриваемой или редактируемой фотки в редакторе фоновое изображение на вашем рабочего столе. Фиксил я её по наводки на строчку wallpaper.jpg. Может кому пригодится, помню, сам долго мучился, пока нашёл где копать.

на вашем рабочем столе (ой бля ошибка)

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

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

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