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


Скриншот программы Grungetastic

Программа Grungetastic предназначена для добавления к вашим фотографиям эффектов в стиле Grunge. В результате получается нечто мрачное, похожее на кадры из Silent Hill, и даже от самой доброй фотографии начинают бегать мурашки по коже. Цена, к счастью, невысока, но на сайте разработчиков еще целая груда аналогичных программ, и если покупать каждую, то итоговая сумма набегает более чем приличная. Попробуем обойтись вообще без покупки.

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

Окно регистрации вызывается через меню Help. Регистрационного имени нет, только серийный номер. Причем программа сама подсказывает правильную длину серийника - 16 символов.


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

На неправильный ввод программа реагирует сообщением "Invalid Serial Number".


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

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


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

В листинге дизассемблера находим место, где есть указатель на эту строчку. Тоже никаких проблем:
...
.text:0044CBF2                 call    sub_58BD4D
.text:0044CBF7                 mov     esi, eax
.text:0044CBF9                 add     esp, 4
.text:0044CBFC                 mov     [ebp+var_1C], esi
.text:0044CBFF                 mov     bl, 4
.text:0044CC01                 mov     byte ptr [ebp+var_4], bl
.text:0044CC04                 test    esi, esi
.text:0044CC06                 jz      loc_44CCD5
.text:0044CC0C                 push    0
.text:0044CC0E                 push    ecx
.text:0044CC0F                 mov     eax, esp
.text:0044CC11                 lea     edx, [ebp+var_10]
.text:0044CC14                 mov     [ebp+var_18], esp
.text:0044CC17                 push    edx
.text:0044CC18                 push    eax
.text:0044CC19                 mov     [ebp+var_10], offset aInvalidSerialN
; "Invalid Serial Number."
.text:0044CC20                 call    sub_46BD00
.text:0044CC25                 add     esp, 4
.text:0044CC28                 mov     byte ptr [ebp+var_4], 5
.text:0044CC2C                 mov     eax, esp
.text:0044CC2E                 lea     ecx, [ebp+var_10]
.text:0044CC31                 mov     [ebp+var_14], esp
.text:0044CC34                 push    ecx
.text:0044CC35                 push    eax
.text:0044CC36                 mov     [ebp+var_10], offset aInvalidSerial
; "Invalid Serial"
.text:0044CC3D                 call    sub_46BD00
.text:0044CC42                 add     esp, 4
.text:0044CC45                 mov     byte ptr [ebp+var_4], 6
.text:0044CC49                 mov     [ebp+var_10], esp
.text:0044CC4C                 lea     edx, [ebp+var_10]
.text:0044CC4F                 mov     eax, esp
...

Чуть выше несколько условных переходов, один из которых ведет на сообщение о неправильной регистрации, а другой - на сообщение о правильной.
.text:0044CB47                 mov     edx, [eax+0B8h]
.text:0044CB4D                 add     esp, 8
.text:0044CB50                 mov     ecx, esi
; Неявно вызвать какую-то функцию
.text:0044CB52                 call    edx
; Проверить ее результат
.text:0044CB54                 test    al, al
; Если AL!=0, то переход на сообщение о правильной регистрации
.text:0044CB56                 jnz     loc_44CC5B
.text:0044CB5C                 lea     eax, [ebp+arg_0]
; Проверить длину введенного серийника
.text:0044CB5F                 call    sub_45BB00
.text:0044CB64                 push    0D0h
; Если длина 16 символов, то серийник просто неправильный
.text:0044CB69                 cmp     eax, 10h
.text:0044CB6C                 jz      loc_44CBF2
; Иначе сообщение о неправильной длине введенного серийника

А вот тут возникает небольшая проблемка. Как вы уже увидели в листинге дизассемблера, функция проверки вызывается неявным образом, через содержимое регистра EDX. Статичный анализ тут не поможет, так как искомый адрес в этом случае остается неизвестным. Но ведь отладчики придумали как раз для подобных случаев! Запускаем программу под отладчиком, ставим точку останова по адресу 0044CB52, пробуем зарегистрировать любым серийником. В момент срабатывания точки останова узнаем адрес вызываемой функции. Вот она:
.text:00401560                 push    ebp
.text:00401561                 mov     ebp, esp
.text:00401563                 push    ecx
.text:00401564                 push    esi
.text:00401565                 push    ecx
.text:00401566                 mov     esi, ecx
.text:00401568                 mov     eax, [esi]
.text:0040156A                 mov     edx, [eax+0BCh]
.text:00401570                 mov     ecx, esp
.text:00401572                 mov     [ebp+var_4], esp
.text:00401575                 push    ecx
.text:00401576                 mov     ecx, esi
.text:00401578                 call    edx
.text:0040157A                 push    47525431h
.text:0040157F                 call    sub_425120
.text:00401584                 add     esp, 8
.text:00401587                 test    al, al
.text:00401589                 jz      short loc_401592
.text:0040158B                 mov     al, 1
.text:0040158D                 pop     esi
.text:0040158E                 mov     esp, ebp
.text:00401590                 pop     ebp
.text:00401591                 retn
.text:00401592 ; -----------------------------------------
.text:00401592 loc_401592:
.text:00401592                 mov     eax, [esi]
.text:00401594                 mov     edx, [eax+0BCh]
.text:0040159A                 push    ecx
.text:0040159B                 mov     ecx, esp
.text:0040159D                 mov     [ebp+var_4], esp
.text:004015A0                 push    ecx
.text:004015A1                 mov     ecx, esi
.text:004015A3                 call    edx
.text:004015A5                 push    424E4431h
.text:004015AA                 call    sub_425120
.text:004015AF                 add     esp, 8
.text:004015B2                 test    al, al
.text:004015B4                 setnz   al
.text:004015B7                 pop     esi
.text:004015B8                 mov     esp, ebp
.text:004015BA                 pop     ebp
.text:004015BB                 retn

Первый вариант патча: записать в самое начало команды MOV AL,1 и RET. Второй вариант патча: заNOPить условный переход по адресу 00401589. В обоих случаях функция проверки всегда будет возвращать нужное нам значение AL=1.


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

Пункт регистрации в меню пропал, вместе с ним пропало ограничение при попытке сохранения отредактированного файла. Цель достигнута. Сигнатура для патча очень приметная, так что можно сделать универсальный патч. Кроме того, аналогичным образом исцеляются от жадности и другие программы этого разработчика.
Добавлено: 11 Сентября 2013 09:39:43 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...