Исследование защиты программы Actual Search & Replace


Скриншот программы Actual Search & Replace

Программа Actual Search & Replace - мощная программа для поиска и замены фрагментов текста в файлах. Поиск можно осуществлять как по отдельным словам, так и по целым фразам или регулярным выражениям. В общем, полезный инструмент для тех, кому приходится часто что-то искать в куче текстовых или HTML-файлов. Программа действительно хорошая, что подтверждают многочисленные награды от различных интернет-изданий, если бы не одно "но". Бесплатно программа будет работать только в течение 30 дней, после чего потребует оплату.

Скачиваем дистрибутив, распаковываем, устанавливаем, запускаем. Сразу же получаем окно с предложением купить или ввести серийный номер:


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

Попробуем ввести какие-нибудь левые данные. Получим сообщение об ошибке "Incorrect key". Исполняемый файл ничем не упакован, поищем в нем эту строку. Никаких проблем, строка находится с первого раза:


Нехорошая строка найдена

Переходим к дизассемблеру. Вот так выглядит кусок кода, отвечающий за вывод сообщения о неправильном ключе регистрации:
...
CODE:004E746A                 push    ebp
CODE:004E746B                 push    offset loc_4E74A3
CODE:004E7470                 push    dword ptr fs:[eax]
CODE:004E7473                 mov     fs:[eax], esp
CODE:004E7476                 mov     eax, ds:off_4E9578
CODE:004E747B                 mov     eax, [eax]
CODE:004E747D                 mov     edx, [eax+2164h]
CODE:004E7483                 mov     eax, [ebp+var_10]
CODE:004E7486                 call    sub_48D3C4
CODE:004E748B                 lea     ecx, [ebp+var_8]
CODE:004E748E                 mov     edx, [ebp+var_C]
CODE:004E7491                 mov     eax, [ebp+var_10]
CODE:004E7494                 call    sub_48CBC8
CODE:004E7499                 xor     eax, eax
CODE:004E749B                 pop     edx
CODE:004E749C                 pop     ecx
CODE:004E749D                 pop     ecx
CODE:004E749E                 mov     fs:[eax], edx
CODE:004E74A1                 jmp     short loc_4E74EA
CODE:004E74A3 ; --------------------------------------------
CODE:004E74A3 loc_4E74A3:
CODE:004E74A3                 jmp     sub_403468
CODE:004E74A8 ; --------------------------------------------
; Первое сообщение о неправильном серийном номере
CODE:004E74A8                 push    0
CODE:004E74AA                 mov     cx, word_4E7638
CODE:004E74B1                 mov     dl, 1
CODE:004E74B3                 mov     eax, offset aIncorrectKey
; "Incorrect key"
CODE:004E74B8                 call    sub_45AA54
CODE:004E74BD                 mov     eax, [ebp+var_10]
CODE:004E74C0                 call    sub_48CB60
CODE:004E74C5                 mov     eax, [ebp+var_10]
CODE:004E74C8                 call    sub_402FBC
CODE:004E74CD                 mov     eax, ds:off_4E9578
CODE:004E74D2                 mov     eax, [eax]
CODE:004E74D4                 mov     byte ptr [eax+2170h], 0
CODE:004E74DB                 call    sub_4037C4
CODE:004E74E0                 jmp     loc_4E7600
CODE:004E74E5 ; ----------------------------------------------
CODE:004E74E5                 call    sub_4037C4
CODE:004E74EA loc_4E74EA:
CODE:004E74EA                 mov     eax, [ebp+var_10]
CODE:004E74ED                 call    sub_48CB60
CODE:004E74F2                 mov     eax, [ebp+var_10]
CODE:004E74F5                 call    sub_402FBC
CODE:004E74FA                 mov     edx, [ebp+var_8]
CODE:004E74FD                 mov     eax, offset aAcsearchRepl_0
; "AcSearch&Replace;"
CODE:004E7502                 call    sub_40420C
CODE:004E7507                 mov     ebx, eax
CODE:004E7509                 test    ebx, ebx
CODE:004E750B                 jz      short loc_4E751C
; Сравнить введенный серийный номер со строкой
CODE:004E750D                 mov     eax, [ebp+var_C]
CODE:004E7510                 mov     edx, offset aIkizhzl170uu_0
; "IKiZhZL170UUvtoyVN5ginTgPygyaoVTh1+lRil"...
CODE:004E7515                 call    sub_404030
; Если они не равны, то все в порядке
CODE:004E751A                 jnz     short loc_4E7574
CODE:004E751C loc_4E751C:
; Второе сообщение о неправильном серийном номере
CODE:004E751C                 xor     eax, eax
CODE:004E751E                 push    ebp
CODE:004E751F                 push    offset loc_4E7549
CODE:004E7524                 push    dword ptr fs:[eax]
CODE:004E7527                 mov     fs:[eax], esp
CODE:004E752A                 push    0
CODE:004E752C                 mov     eax, offset aIncorrectKey
; "Incorrect key"
CODE:004E7531                 mov     cx, word_4E7638
CODE:004E7538                 mov     dl, 1
CODE:004E753A                 call    sub_45AA54
CODE:004E753F                 xor     eax, eax
CODE:004E7541                 pop     edx
CODE:004E7542                 pop     ecx
...

Обратите внимание, что здесь два блока кода, в которых выводятся сообщения "Incorrect key". В первом случае проверяется ключ на корректность, и, если ключ неправильный, то взводится исключение и управление передается на адрес 004E74A8. Команды условных переходов не используются, что несколько затрудняет анализ. Посмотрим дальше. А дальше выполняется сравнение введенного серийного номера с какой-то хитрой строкой, причем, если они совпадают, то снова выдается сообщение о неправильном серийном номере. К чему бы это? Забегая вперед, скажу, что здесь используется "черный список" ключей. То есть разработчики блокируют ключи к своим программам, которые были получены незаконным путем, например, куплены по левым кредитным картам или выложены в свободный доступ.


Заблокированный регистрационный ключ

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


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

Догадка подтвердилась. Это действительно правильный серийный номер. В программе пропали все внешние признаки триальности, в окне About написано, что она зарегистрирована. Выходим из программы, запускаем снова. Оп-па! Триальное окно снова на месте. Можно повторять регистрацию сколько угодно раз, она будет сохраняться только на текущий сеанс работы с программой. Значит где-то выполняется дополнительная проверка на заблокированный ключ. Сперва поищем строку заблокированного ключа. Найдется еще одно совпадение. С ней выполняем те же самые манипуляции по замене символов, что и с первой строкой.


Изменяем заблокированный ключ в файле

Повторяем регистрацию - то же самое, то есть все плохо. Попробуем поискать какие-нибудь другие зацепки, например, по строке из заголовка программы "Unregistered". Найдется такой код:
...
CODE:004C0444                 mov     eax, ds:off_4E9578
CODE:004C0449                 mov     eax, [eax]
CODE:004C044B                 mov     eax, [eax+216Ch]
CODE:004C0451                 mov     edx, offset aDavidLeeSingle
; "David Lee - single user license"
CODE:004C0456                 call    sub_404030
CODE:004C045B                 jnz     loc_4C04F7
CODE:004C0461                 lea     edx, [ebp+var_34]
CODE:004C0464                 mov     eax, ds:off_4E9578
CODE:004C0469                 mov     eax, [eax]
CODE:004C046B                 call    sub_434894
CODE:004C0470                 mov     eax, [ebp+var_34]
CODE:004C0473                 mov     edx, offset aActualSearch_1
; "Actual Search & Replace (Unregistered)"
CODE:004C0478                 call    sub_404030
CODE:004C047D                 jz      short loc_4C04F7
CODE:004C047F                 lea     eax, [ebp+var_2C]
CODE:004C0482                 mov     edx, offset aUnregistered
; "Unregistered"
CODE:004C0487                 call    sub_403D38
CODE:004C048C                 mov     eax, [ebp+var_2C]
...

Ага, знакомая нам строчка "David Lee - single user license". Ее мы видели после регистрации. Значит на "черный список" проверяется не только ключ при вводе, но и регистрационное имя в уже работающей программе. Логично, ведь ключ можно записать через реестр, или же подобная незаконная регистрация могла сохраниться от предыдущей установки, где она еще не была заблокирована. Поищем в исполняемом файле все упоминания несчастного Дэвида и также затрем в каждом из них по несколько символов. Таких проверок будет как минимум три. Зато теперь, после стирания из файла всех упоминаний имени Дэвида Ли и его регистрационного ключа, программа спокойно регистрируется заблокированным ранее ключом и работает как ни в чем не бывало.

Вот так жадность в очередной раз была наказана, а мы познакомились с новым способом обхода защиты программ через разблокировку ключей.
Теги:
защита, взлом
Добавлено: 19 Сентября 2013 12:18:31 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...