Исследование защиты программы Shape Collage
Скриншот программы Shape Collage
Shape Collage - лучшая, на мой взгляд, программа для создания эффектных коллажей из набора фотографий. Коллаж в виде "разбросанных фотографий" создается буквально за несколько кликов, результаты ее работы я частенько использую при оформлении статей. Когда-то давно программа была бесплатной, затем аффтар решил подрезать с нее денег, в незарегистрированной версии добавил маркеры на готовый коллаж и запретил экспорт в .PSD-формат. Предыдущие версии были написаны на Java, регистрация с обязательной онлайн-активацией, поэтому нормально подкорректировать их мне не удавалось. С 3-й версии программа Shape Collage переписана на Qt, размер заметно подрос, но зато появилась возможность вносить в ее работу любые нужные нам изменения.
Скачиваем дистрибутив, устанавливаем, смотрим что у нас получилось. Среди мегатонн библиотек Qt находится главный исполняемый файл ShapeCollage.exe. Он ничем не упакован, отправляем его в дизассемблер и параллельно смотрим на поведение программы. А нам сразу же предлагают обновиться до версии "Pro", где нет маркеров и есть возможность сохранять коллажи в редактируемом формате PhotoShop.
Окно регистрации программы
При вводе ключа выполняется принудительная онлайн-проверка, она же активация. То есть какой бы мы ключ ни ввели, до момента проверки он будет считаться невалидным. Придется патчить, чтобы программа работала вообще без ключа или около того. Поскольку в Shape Collage заявлен так называемый режим "Pro", то есть полный, то искать надо что-нибудь связанное с этим словом. Например, по строке "Shape Collage Pro" поиск выводит нас на интересный участок кода, по всей видимости как раз отвечающий за реакцию на успешную или неуспешную активацию. Часть кода приходится пропускать, так как он не относится напрямую к интересующей нас ветке алгоритма.
Code (Assembler) : Убрать нумерацию
- .text:00490047 mov [esp+4], esi
- .text:0049004B lea ebx, [ebp+var_98]
- .text:00490051 mov [esp], ebx
- ; Вызвать функцию проверки
- .text:00490054 call sub_47F460
- ; Сохранить ее результат из регистра AL в регистре BL
- .text:00490059 mov bl, al
- ...
- ; Часть кода пропущена
- ...
- ; Значение BL нулевое?
- .text:00490097 test bl, bl
- ; Да, переход на сообщение о неправильной регистрации
- .text:00490099 jz loc_490B60
- ...
- ; Часть кода пропущена
- ...
- ; Установить в заголовок, что программа работает в полноценном Pro-режиме
- .text:00490163 mov dword ptr [esp+4], 0
- .text:0049016B lea ebx, [ebp+var_1DC]
- .text:00490171 mov [esp], ebx
- .text:00490174 call ds:_ZN11QMessageBoxC1EP7QWidget
- .text:0049017A mov dword ptr [esp+4], 0FFFFFFFFh
- .text:00490182 mov dword ptr [esp], offset aShapeCollage_5
- ; "Shape Collage Pro"
- .text:00490189 call [ebp+var_228]
- .text:0049018F mov [ebp+var_A4], eax
- .text:00490195 lea esi, [ebp+var_A4]
- .text:0049019B mov [esp+4], esi
- .text:0049019F mov [esp], ebx
- .text:004901A2 call ds:_ZN11QMessageBox7setTextERK7QString
- ...
- ...
- ; Сюда выполняется переход при BL=0
- .text:00490B60 loc_490B60:
- .text:00490B60 mov dword ptr [esp+4], 0
- .text:00490B68 lea ebx, [ebp+var_1DC]
- .text:00490B6E mov [esp], ebx
- ; Сообщение о неправильном серийном номере
- .text:00490B71 call ds:_ZN11QMessageBoxC1EP7QWidget
- .text:00490B77 lea edi, [ebp+var_C0]
- .text:00490B7D mov dword ptr [esp+0Ch], 0
- .text:00490B85 mov dword ptr [esp+8], offset aInvalidLicen_0
- ; "Invalid License Key"
- .text:00490B8D mov dword ptr [esp+4], offset dword_52E148
- .text:00490B95 mov [esp], edi
Программа успешно "зарегистрирована"
Патченная программа работает прекрасно, никаких ограничений по экспорту в .PSD, никаких маркеров при сохранении. Цель достигнута. При этом регистрационный ключ никуда вводить не пришлось, соответственно, онлайн-активация идет лесом. Но можно ли обойти момент активации, чтобы программа уже как бы проверила серийник и как бы признала его валидным? Предположим, что после активации введенные данные сохраняются где-то в сухом прохладном месте, и в дальнейшем программа проверяет их по мере возможности. Таких мест немного: или реестр, или файлы. Для отлова всех действий программы воспользуемся утилитой Process Monitor с фильтром по имени исполняемого файла.
Обращения программы к реестру
Как видно в логе работы монитора, программе надо проверить два ключа в реестре - "name" и "license". Ну раз надо, значит надо. Открываем Блокнот и рисуем в нем файл реестра, в котором по уже известному нам пути пропишем имя и лицензионный ключ. Естественно, значение ключа берется от балды. Сохраняем в файл, например, register.reg, и добавляем данные в реестр.
REGEDIT4
[HKEY_CURRENT_USER\Software\ShapeCollage\OrganizationDefaults]
"license"="1234567890"
"name"="ManHunter / PCL"
Возвращаемся в дизассемблер к функции, которую мы недавно пропатчили, но на этот раз будем работать с оригинальным неизмененным файлом. Посмотрим на функцию проверки повнимательнее, предварительно загуглив назначение некоторых функций Qt:
Code (Assembler) : Убрать нумерацию
- .text:0047F4B2 lea esi, [ebp+var_1C]
- .text:0047F4B5 mov eax, [ebp+arg_0]
- .text:0047F4B8 mov [esp+4], eax
- .text:0047F4BC mov [esp], esi
- ; Перевести строку в верхний регистр
- .text:0047F4BF call ds:_ZNK7QString7toUpperEv
- .text:0047F4C5 push ecx
- .text:0047F4C6 lea ebx, [ebp+var_20]
- .text:0047F4C9 mov [esp+4], esi
- .text:0047F4CD mov [esp], ebx
- .text:0047F4D0 call sub_47EA40
- .text:0047F4D5 push edx
- ; Записать в стек значение указателя из регистра EDI
- .text:0047F4D6 mov [esp+4], edi
- ; Записать в стек значение указателя из регистра EBX
- .text:0047F4DA mov [esp], ebx
- ; Вызвать функцию сравнения строк
- .text:0047F4DD call ds:_ZNK7QStringeqERKS_
- ; Сохранить в BL результат ее работы
- .text:0047F4E3 mov bl, al
- ...
- ; Часть кода пропущена
- ...
- ; Записать в AL сохраненный результат из BL
- .text:0047F543 mov al, bl
- .text:0047F545 lea esp, [ebp-0Ch]
- .text:0047F548 pop ebx
- .text:0047F549 pop esi
- .text:0047F54A pop edi
- .text:0047F54B leave
- .text:0047F54C retn
Переходим в дампе на адрес из стека
Переходим из стека в дамп по первому адресу.
Переходим в дампе на адрес из дампа
На строку это не очень похоже, зато похоже на адрес в памяти. Попробуем перейти по нему и посмотреть, что находится там.
Серийник из реестра
Вот, уже лучше. Значит в стек кладется не просто указатель на строку, а указатель на указатель на строку. Это Qt, детка, улыбаемся и машем. В дампе на небольшом смещении от адреса, на который указывает указатель, отчетливо виден наш левый серийник из реестра. Проделаем тот же фокус со вторым адресом из стека.
Строка для сравнения
Похожая структура, но строчка уже другая. Несмотря на все навороты Qt с какими-то префиксами данных, все сводится к сравнению двух юникодных строк: лицензионный ключ из реестра и строка "YXJT4QZDMA". Логично предположить, что это и есть правильный ключ для указанного имени. Заменяем строку лицензии в регистрационном файле на найденную строку из отладчика. Снова добавляем данные в реестр.
REGEDIT4
[HKEY_CURRENT_USER\Software\ShapeCollage\OrganizationDefaults]
"license"="YXJT4QZDMA"
"name"="ManHunter / PCL"
Запускаем программу, не забывая заблокировать онлайн-проверку фаерволом. На этот раз никаких окон регистрации нет, в заголовке указана Pro-версия, а в меню регистрационной информации красуется лицензионный ключ и имя из реестра.
Программа успешно зарегистрирована
Программа успешно зарегистрирована, на этот раз практически официально. Онлайн-проверку регистрации блокируем фаерволом. Можно было бы поставить точку, если бы не одно "НО". На своих компьютерах я наблюдал странное поведение программы, оно заключается в том, что при блокировке фаерволом, после завершения работы исполняемый файл ShapeCollage.exe остается в памяти. Не знаю, с чем связан такой косяк, кривизна рук аффтара, особенности работы библиотек Qt или все в совокупности, но факт остается фактом. Или патченный файл, выпущенный в интернет, или корректная регистрация под присмотром фаервола и последующие танцы с бубном по принудительному убиванию зависшего в памяти процесса. Для себя я решил проблему следующим образом. Я просто пропатчил в файле адрес URL, по которому выполняется проверка ключа.
URL для проверки ключа онлайн
Скучные логи снифферов трафика приводить не буду, главное, что был найден злополучный адрес. Теперь достаточно его пропатчить, забив нулями, и программу можно смело выпускать в сеть. Лицензия больше не слетит.
Просмотров: 8401 | Комментариев: 8
Метки: исследование защиты, графика
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(12.09.2014 в 20:25):
Никаких готовых патчей на этом сайте никогда не будет.
Евгений.
(12.09.2014 в 18:27):
Для непосвященных к таким мануалам неплохо бы и образец патчика прикладывать.
Для ознакомления, так сказать.;-)
Для ознакомления, так сказать.;-)
104261
(31.08.2014 в 00:15):
DagalProject,
Можно заменить MOV AL,BL по адресу 47А543 на MOV AL,1 без RET.
Спасибо за 'лекцию'.
Можно заменить MOV AL,BL по адресу 47А543 на MOV AL,1 без RET.
Спасибо за 'лекцию'.
ManHunter
(28.08.2014 в 07:38):
Не обязательно же нулить всю строку целиком, достаточно поменять первый символ, эффект будет точно такой же. Итог = 1 байт :)
AyTkACT
(28.08.2014 в 00:42):
Как-то не укладывается в голове понятие "элегантно" и зануление тридцати с лишним байт. Хотя, сабж не крутил и функцию обработки ответа сервера не видел.
Думаю, что Manhunter'у видней когда 30+ байт патчить, а когда ограничиться патчем в 1 (или 3) байт(а).
Думаю, что Manhunter'у видней когда 30+ байт патчить, а когда ограничиться патчем в 1 (или 3) байт(а).
voila
(27.08.2014 в 21:03):
ммм, какое элегантное решение)
И чтение доставило, спасибо, Хантер!
И чтение доставило, спасибо, Хантер!
ManHunter
(27.08.2014 в 17:48):
0047F460
DagalProject
(27.08.2014 в 17:47):
Здравствуйте! Скажите пожалуйста, для патча по какому адресу должна быть команда MOV AL,1 и команда RET. Спасибо.
Добавить комментарий
Заполните форму для добавления комментария