Исследование защиты программы PhotoVINTAGE
Скриншот программы
ФотоВИНТАЖ - программа для реставрации фотографий. Она обладает простейшим интерфейсом, который освоит даже новичок, но при этом несет на борту большой набор инструментов для автоматической и ручной коррекции. До идеала далеко, но работать можно. Удаление пятен, царапин, разрывов и других дефектов, колоризация черно-белых снимков в один клик, исправление искаженных цветов на фотографиях - вот лишь малая часть возможностей. А большАя часть заключается в необходимости выкладывать больше двух косарей за максимальный вариант лицензии.
С сайта забираем дистрибутив, но на этом установка не заканчивается, инсталлятор скачивает дополнительно еще пару сотен мегов всяких нужных для работы данных. Во время установки будьте предельно внимательны, чтобы случайно не наинсталлировать всякого сопутствующего говнища от хуяндекса. Когда все наконец-то установится, смотрим, что получилось. Программа написана на Qt, главный исполняемый файл ничем не упакован, отправляем его в дизассемблер и уходим пить кофе, чтобы переварить 80 с лишним мегов кода даже на шустрых машинах потребуется время.
Визуальный осмотр начнем с поиска в файле характерных сигнатур типа "license", "trial", "registered" и тому подобных. Поиск выводит нас на вот такой любопытный блок в сегменте данных:
Code (Assembler) : Убрать нумерацию
- .rdata:054404CA ; char aIstrial1[]
- .rdata:054404CA aIstrial1 db 'isTrial1',0
- .rdata:054404D3 a82r1 db '82R1',0
- .rdata:054404D8 aGl28 db 'GL28',0
- .rdata:054404DD a6hsd db '6HSD',0
- .rdata:054404E2 ; char aStartcheck1[]
- .rdata:054404E2 aStartcheck1 db 'startCheck1',0
- .rdata:054404EE ; char aStartcheck1Tim[]
- .rdata:054404EE aStartcheck1Tim db 'startCheck1 timout',0
- .rdata:05440501 ; char aStartcheck2[]
- .rdata:05440501 aStartcheck2 db 'startCheck2',0
- .rdata:0544050D ; char aStartcheck2Tim[]
- .rdata:0544050D aStartcheck2Tim db 'startCheck2 timout',0
- .rdata:05440520 ; char aReadkey2[]
- .rdata:05440520 aReadkey2 db 'readKey2',0
- .rdata:05440529 ; char aIstrial2[]
- .rdata:05440529 aIstrial2 db 'isTrial2',0
- .rdata:05440532 aG2ua db 'G2UA',0
- .rdata:05440537 a263s db '263S',0
- .rdata:0544053C aCfgu db 'CFGU',0
- .rdata:05440541 ; char aSendlicense[]
- .rdata:05440541 aSendlicense db 'sendLicense',0
- .rdata:0544054D ; char aSendlicenseErr[]
- .rdata:0544054D aSendlicenseErr db 'sendLicense ERR_EMPTY_EMAIL',0
- .rdata:05440569 ; char aSendlicenseE_0[]
- .rdata:05440569 aSendlicenseE_0 db 'sendLicense ERR_EMPTY_SERIAL',0
- .rdata:05440586 ; char aSendlicenseE_1[]
- .rdata:05440586 aSendlicenseE_1 db 'sendLicense ERR_LICENSE_KEY',0
- .rdata:054405A2 ; char aLibistrial3[]
- .rdata:054405A2 aLibistrial3 db 'libIsTrial3',0
- .rdata:054405AE a1af db '1AF',0
- .rdata:054405B2 a2rk db '2RK',0
- .rdata:054405B6 a3np db '3NP',0
- .rdata:054405BA ; char aLibisprofessio[]
- .rdata:054405BA aLibisprofessio db 'libIsProfessionalVersion',0
- .rdata:054405D3 ; char aIsprofessional[]
- .rdata:054405D3 aIsprofessional db 'isProfessionalVersion',0
- .rdata:054405E9 ; char aLibisstandardv[]
- .rdata:054405E9 aLibisstandardv db 'libIsStandardVersion',0
- .rdata:054405FE ; char aIsstandardvers[]
- .rdata:054405FE aIsstandardvers db 'isStandardVersion',0
- .rdata:05440610 ; char aLibispremiumve[]
- .rdata:05440610 aLibispremiumve db 'libIsPremiumVersion',0
- .rdata:05440624 a2638 db '2638',0
- .rdata:05440629 ; char aIspremiumversi[]
- .rdata:05440629 aIspremiumversi db 'isPremiumVersion',0
- .rdata:0544063A ; char aType_dd[]
- .rdata:0544063A aType_dd db 'Type_DD',0
Code (Assembler) : Убрать нумерацию
- .text:0052A2B0 push ebp
- .text:0052A2B1 mov ebp, esp
- .text:0052A2B3 push edi
- .text:0052A2B4 push esi
- .text:0052A2B5 push ebx
- .text:0052A2B6 lea esi, [ebp+var_2C]
- .text:0052A2B9 lea ebx, [ebp+var_30]
- .text:0052A2BC mov edi, ecx
- .text:0052A2BE sub esp, 6Ch
- .text:0052A2C1 mov ecx, ebx
- .text:0052A2C3 mov [ebp+var_2C], 2
- .text:0052A2CA mov [ebp+var_28], 1D0h
- .text:0052A2D1 mov [ebp+var_24], offset a__VintageProte
- ; "../vintage/protect.cpp"
- .text:0052A2D8 mov [ebp+var_20], offset aBoolProtectIst
- ; "bool Protect::isTrial1()"
- .text:0052A2DF mov [ebp+var_1C], offset aDefault_23
- ; "default"
- .text:0052A2E6 mov [esp], esi
- .text:0052A2E9 call ds:_ZNK14QMessageLogger5debugEv
- .text:0052A2EF sub esp, 4
- .text:0052A2F2 mov ecx, ebx
- .text:0052A2F4 mov dword ptr [esp], offset a385213m_2
- ; "\x1B[38;5;213m"
- .text:0052A2FB call sub_7AEC00
- .text:0052A300 sub esp, 4
- .text:0052A303 mov ecx, eax
- .text:0052A305 mov dword ptr [esp], offset aIstrial1
- ; "isTrial1"
- .text:0052A30C call sub_7AEC00
- .text:0052A311 sub esp, 4
Едем дальше. Вторая функция, где используется эта строка, также относится к защите, также возвращает true или false и, судя по названию, отвечает за проверку новых версий.
Code (Assembler) : Убрать нумерацию
- .text:0052CB90 push ebp
- .text:0052CB91 mov ebp, esp
- .text:0052CB93 push edi
- .text:0052CB94 push esi
- .text:0052CB95 push ebx
- .text:0052CB96 lea eax, [ebp+var_30]
- .text:0052CB99 sub esp, 0CCh
- .text:0052CB9F mov [ebp+var_AC], ecx
- .text:0052CBA5 mov [ebp+var_30], 2
- .text:0052CBAC mov [esp], eax
- .text:0052CBAF mov eax, ds:_ZNK14QMessageLogger5debugEv
- .text:0052CBB4 lea ecx, [ebp+var_40]
- .text:0052CBB7 mov [ebp+var_2C], 434h
- .text:0052CBBE mov [ebp+var_28], offset a__VintageProte
- ; "../vintage/protect.cpp"
- .text:0052CBC5 mov [ebp+var_24], offset aBoolProtectChe
- ; "bool Protect::checkAndShowNews()"
- .text:0052CBCC mov [ebp+var_20], offset aDefault_23
- ; "default"
- .text:0052CBD3 mov [ebp+var_B0], eax
- .text:0052CBD9 call eax ; _ZNK14QMessageLogger5debugEv
- .text:0052CBDB lea ecx, [ebp+var_40]
- .text:0052CBDE sub esp, 4
- .text:0052CBE1 mov dword ptr [esp], offset a385213m_2
- ; "\x1B[38;5;213m"
- .text:0052CBE8 call sub_7AEC00
- .text:0052CBED sub esp, 4
- .text:0052CBF0 mov ecx, eax
- .text:0052CBF2 mov dword ptr [esp], offset aCheckandshowne
- ; "checkAndShowNews"
- .text:0052CBF9 call sub_7AEC00
- .text:0052CBFE sub esp, 4
По аналогии разбираемся с функциями, которые ссылаются на строки "isTrial2" и "libIsTrial3". Они очень похожи, приводить их тут не буду. На каждую строку по одной функции. Единственное отличие, что в функции "isTrial2" надо будет восстановить стек при возврате, там команды будут XOR EAX,EAX и RET 4.
Теперь разбираемся с типом лицензии. Если посмотреть на сайте, то наивысшая категория доступа ко всем инструментам - Professional. Возвращаемся к списку строк, находим "isProfessionalVersion", "isStandardVersion" и "isPremiumVersion". Все они должны вернуть true или false. Так как нам надо получить профессиональную лицензию, в начало функции "isProfessionalVersion" впечатываем MOV EAX,1 и RET, а в начала других - XOR EAX,EAX и RET. Тем самым при любом раскладе у нас будет нужный тип лицензии. Сохраняем изменения, запускаем. Триальных окон нет, сканирование и прочие инструменты работают, но не тут-то было.
Сообщение о неправильной активации
Через некоторое время программа осчастливливает нас вот таким сообщением, после чего без вариантов завершает работу. По всей видимости одного факта наличия "лицензии" тут недостаточно, нужны какие-то реальные данные. По тексту ошибки выходим на следующий код:
Code (Assembler) : Убрать нумерацию
- .text:00530CE0 mov dword ptr [esp+0Ch], 0FFFFFFFFh
- .text:00530CE8 mov dword ptr [esp+8], 0
- .text:00530CF0 lea ecx, [ebp+var_7C]
- .text:00530CF3 mov dword ptr [esp+4], offset aEnterYourEmail
- ; "Enter your Email."
- .text:00530CFB mov dword ptr [esp], offset dword_8272AC
- .text:00530D02 call ds:_ZNK11QMetaObject2trEPKcS1_i
- .text:00530D08 mov eax, [ebp+var_80]
- .text:00530D0B mov edx, [ebp+var_7C]
- .text:00530D0E lea ecx, [ebp+var_7C]
- .text:00530D11 sub esp, 10h
- .text:00530D14 mov [ebp+var_80], edx
Code (Assembler) : Убрать нумерацию
- .text:00530940 push ebp
- .text:00530941 mov ebp, esp
- .text:00530943 push edi
- .text:00530944 push esi
- .text:00530945 push ebx
- .text:00530946 lea esi, [ebp+var_48]
- .text:00530949 mov edi, ecx
- .text:0053094B lea ecx, [ebp+var_4C]
- .text:0053094E sub esp, 8Ch
- .text:00530954 mov [ebp+var_48], 2
- .text:0053095B mov ebx, [ebp+arg_0]
- .text:0053095E mov [ebp+var_44], 555h
- .text:00530965 mov [ebp+var_40], offset a__VintageProte
- ; "../vintage/protect.cpp"
- .text:0053096C mov [ebp+var_3C], offset aVoidProtectFin
- ; "void Protect::finishCheckLicense(CheckL"...
- .text:00530973 mov [ebp+var_38], offset aDefault_23
- ; "default"
- .text:0053097A mov [esp], esi
- .text:0053097D call ds:_ZNK14QMessageLogger5debugEv
- .text:00530983 lea ecx, [ebp+var_4C]
- .text:00530986 sub esp, 4
Сохраняем изменения, запускаем программу. Ограничений по функционалу нет, триальных проявлений нет, тайм-бомба не срабатывает. Ну и в интернет программу выпускать не надо, ей там делать нечего. Цель достигнута, можно поиграться с картинками.
Просмотров: 461 | Комментариев: 1
Метки: исследование защиты, графика
Комментарии
Отзывы посетителей сайта о статье
Добавить комментарий
Заполните форму для добавления комментария
на вашем рабочем столе (ой бля ошибка)