Blog. Just Blog

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

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

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

В дистрибутив авторы умудрились затолкать инсталляторы для MacOS и Windows, из-за этого размер архива получился вообще негуманный. Но ничего не поделаешь, все равно придется скачивать. Устанавливаем, запускаем.

Окно активации
Окно активации

При старте программы первым делом запускается какая-то мутная посторонняя приблуда под названием LicProtector500.exe, которая отвечает за активацию. Но никаких упоминаний об этой программе в основном исполняемом файле найти не удалось, я думаю, что если имя файла где-то и есть, то оно зашифровано. Franzis HDR Projects написан на Qt и здесь в качестве защиты задействуется готовый компонент Mirage Licence Protector с онлайн-активацией. Без интернета не получится даже просто запустить основную программу, поэтому для первоначального исследования мне придется активировать триальный режим.

Когда программа запустится, поищем что-нибудь, относящееся к индикации триального режима. Это строка "TRIAL" в заголовке. По ней ничего интересного не обнаруживается. Зато в языковых файлах найдется юникодная строка "TRIAL" и ее индекс "VERSION_DEMO":

Строка в языковом файле
Строка в языковом файле

Это уже лучше. Теперь поищем в листинге что-нибудь, связанное с индексом "VERSION_DEMO". Довольно быстро найдется следующий блок кода:
  1. .text:005E59B9                 lock xadd [eax], edx
  2. .text:005E59BD                 mov     byte ptr [esp+54h+var_4], 0Bh
  3. ; Вызвать функцию проверки
  4. .text:005E59C2                 call    sub_401530
  5. .text:005E59C7                 mov     ebp, ds:?translate
  6. ; Если она вернула EAX!=0, то перепрыгнуть упоминание о Demo-версии 
  7. .text:005E59CD                 test    eax, eax
  8. .text:005E59CF                 jnz     loc_5E5A84
  9. .text:005E59D5                 push    0
  10. .text:005E59D7                 push    0
  11. .text:005E59D9                 push    offset aVersion_demo ; "VERSION_DEMO"
  12. .text:005E59DE                 lea     eax, [esp+60h+var_30]
  13. .text:005E59E2                 push    offset aProgram ; "Program"
Выполняется какая-то функция проверки, на основании ее результата происходит или не происходит условный переход. Посмотрим функцию проверки.
  1. .text:00401530 sub_401530      proc near
  2. .text:00401530                 mov     eax, dword_D84BA4
  3. .text:00401535                 retn
  4. .text:00401535 sub_401530      endp
Это, оказывается, вовсе и не проверка, а просто занесение в регистр EAX какого-то значения из памяти. Скорее всего, это и есть флаг зарегистрированности. Значит надо узнать, где оно инициализируется. Открываем перекрестные ссылки:

Перекрестные ссылки
Перекрестные ссылки

Как видим, инициализация выполняется только в одном месте. Смотрим:
  1. .text:00401520 sub_401520      proc near
  2. .text:00401520
  3. .text:00401520 arg_0           = dword ptr  4
  4. .text:00401520
  5. .text:00401520                 mov     eax, [esp+arg_0]
  6. .text:00401524                 mov     dword_D84BA4, eax
  7. .text:00401529                 retn
  8. .text:00401529 sub_401520      endp
Тоже ничего сложного. Берется значение, переданное функции в качестве параметра, затем записывается в ячейку памяти. Теперь посмотрим, откуда это значение берется на стеке:
  1. .text:007A757D                 push    0
  2. .text:007A757F                 jmp     short loc_7A7583
  3. .text:007A7581 ; ----------------------------------------
  4. .text:007A7581 loc_7A7581:
  5. .text:007A7581                 push    1
  6. .text:007A7583 loc_7A7583:
  7. .text:007A7583                 call    sub_401520
Поднимаемся по листингу чуть выше и смотрим условные переходы, которые приводят к правильному или неправильному значению.
  1. .text:007A721B                 call    sub_7A3960
  2. .text:007A7220                 lea     ecx, [esp+24CCh+var_23CC]
  3. .text:007A7227                 mov     byte ptr [esp+24CCh+var_4], 0ACh
  4. ; Вызвать функцию проверки
  5. .text:007A722F                 call    sub_7A42B0
  6. .text:007A7234                 sub     eax, 1
  7. ; Условный переход выполнится при EAX=1
  8. .text:007A7237                 jz      loc_7A7581
  9. .text:007A723D                 sub     eax, 1
  10. .text:007A7240                 jz      loc_7A757D
  11. .text:007A7246                 lea     ecx, [esp+24CCh+var_23CC]
  12. .text:007A724D                 mov     byte ptr [esp+24CCh+var_4], 65h
Открываем функцию проверки sub_7A42B0 и вот он момент истины. Функция небольшая, но в ней видны отсылки к какому-то компоненту типа CLicenceHelper::CheckLicence и к файлу лицензии. По результатам всех проверок в регистр EAX заносится 1, 0 или 2. Нам нужно сделать так, чтобы функция всегда возвращала 1. Патчим ее начало сладкой парочкой MOV EAX,1 и RET. Сохраняем изменения, запускаем...

...и программа молча закрывается. Возможно переклинивает внешний компонент защиты, срабатывает какая-то внутренняя проверка целостности, да мало ли какие причины. Узнать это нам поможет отладчик. Но перед отладкой я обычно дополнительно подготавливаю файл, в частности проверяю, чтобы в свойствах файла в PE-заголовке был установлен флаг "Relocation stripped". Зачем это надо? В этом случае при загрузке в отладчик исполняемый файл будет размещен по своему ImageBase, а VirtualAddress в памяти отладчика и в файле будут совпадать. Лично мне так удобнее ориентироваться. Загоняем пропатченный файл в PE Tools, открываем свойства заголовка на редактирование.

Удаляем релоки из файла
Удаляем релоки из файла

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

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

Проверяем работоспособность переводом часов вперед, все нормально. Триальная версия также накладывает на готовые изображения водяные знаки, после всех изменений и это досадное недоразумение исчезает. Цель достигнута. Добавляем еще один неплохой инструмент в набор программ для работы с изображениями.

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

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

Комментарии

Отзывы посетителей сайта о статье
voffka (09.06.2018 в 13:39):
nubuser, самопал. Разбираться не охото, но перед строкой идет значение(скорее всего word)это длина строки включая 08, а 08 может быть как стоп-байтом, так и форматом строки.
nubuser (09.06.2018 в 12:59):
Это другое дело. Так нашлась.
Так что за формат тогда у этой надписи?
voffka (09.06.2018 в 12:48):
nubuser, Ищи по слову TRIA, т.к. TRIAL не попадает под формат юникода, последний байт 08 вместо 00
nubuser (08.06.2018 в 16:51):
У Вас на картинке поиск в TC, видимо. Так я пробовал и TC, и Far, и кучу других hex-редакторов. Не видят, и всё. В поиске. Unicode. А если вручную (недалеко надпись DEMO) - то видится. Не с системой у меня чего случилось?
nubuser (08.06.2018 в 16:11):
И что не так с надписью TRIAL в файле hdrprojects_en.qm?
Почему её не находят редакторы?
ManHunter (08.06.2018 в 10:45):
Стек виден в отладчике, а код, который выполняет действия со стеком, прекрасно анализируется в IDA. Если бы там было что-то типа push dword [eax+1234], то тут без вариантов, только отладчик. А в коде обычные push 1 и push 0.
nubuser (08.06.2018 в 10:37):
"Теперь посмотрим, откуда это значение берется на стеке:"
И это тоже поясните, пожалуйста.
Вы были в IDA.
А стек виден только в отладчике в период выполнения, или снова не так понял?
nubuser (08.06.2018 в 10:11):
У меня и с "Relocation stripped", и без него в отладчик загружается всегда по одному адресу 00800ССС. Или я не так всё понял?
voffka (07.06.2018 в 22:19):
Цитата1. Патчим ее начало сладкой парочкой MOV EAX,1 и RET. Сохраняем изменения, запускаем...

...и программа молча закрывается. Возможно переклинивает внешний компонент защиты, срабатывает какая-то внутренняя проверка целостности, да мало ли какие причины.

Своим любимым MOV EAX,1 и RET ты затер 007A42B2 PUSH 00844F2B,где 00844F2B попадает под релоки и во время инициализации MOV EAX,1 портится.
Чтоб не отключать релоки, по адресу 007A42B0 сделай джамп чуть выше, где куча INT3 и там уже... как всегда.
brute (06.06.2018 в 11:02):
наверное, можно было сразу mov eax, dword_D84BA4 заменить на:
push 1
pop eax
тогда, может, и последующая обработка не понадобится
ManHunter (06.06.2018 в 10:39):
nubuser, просто загрузи исходный и модифицированный файл в отладчик и все вопросы сразу отпадут.
nubuser (06.06.2018 в 10:03):
"...файл будет размещен по своему ImageBase"
Расскажите, пожалуйста, а если не делать этого в PE, то что может происходить с размещением файла?

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

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

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