Исследование защиты программы EasyBoot
Скриншот программы EasyBoot
EZB Systems EasyBoot - очень мощная программа для создания мультизагрузочных CD/DVD дисков. Я с помощью Easyboot делал для себя "реанимационный" диск с Windows XP, на котором был дистрибутив системы, различные программы для сброса пароля, работающие при загрузке с дискеты, аварийная дискета с MS-DOS и другие полезные утилиты для восстановления системы. Неудивительно, что за такой мощный инструмент разработчики просят денег, в принципе, я даже готов их поддержать, но предпочитаю делать это морально.
Особенностью программы является то, что она распространяется в виде двух разных дистрибутивов - общедоступного триального, который качается с сайта, и ретайлового, который выдается зарегистрированным пользователям после покупки. Разница только в системе лицензирования: в триальном дистрибутиве жестко прописан список всех ранее купленных ключей и с другими он работать не будет, а в ретайловый дистрибутив принимает ключи из кейгенов. По основному функционалу они ничем не отличаются.
Так как к зарегистрированным пользователям мы никаким боком не относимся, работать будем с триальным дистрибутивом. Скачиваем, устанавливаем, запускаем. Видимые признаки незарегистрированной версии - это соответствующая надпись на вкладке "About" и неубираемая надпись на главном экране готового меню.
Программа не зарегистрирована
Попробуем зарегистрировать программу каким-нибудь левым серийником. Она его принимает, но просит перезапуститься для проверки его правильности. Никаких других сообщений о том, правильный серийник или нет, не выводится. С точки зрения защиты это самый правильный ход.
Окно регистрации
Раз здесь нам ловить нечего, поищем надпись "Unregistered" из окна "About". Отправляем исполняемый файл в дизассемблер, а когда он закончит свою работу, поищем нужную строку. Находится следующая конструкция:
Code (Assembler) : Убрать нумерацию
- .data:005283A4 dd 4654h
- .data:005283A8 dd offset aUnregisteredVe
- ; "Unregistered Version."
- .data:005283AC dd 4655h
- .data:005283B0 dd offset aThisProductIsA
- ; "This Product is Authorized to: "
Code (Assembler) : Убрать нумерацию
- .text:00441D74 lea eax, [ebp+var_4]
- .text:00441D77 mov edx, 2
- .text:00441D7C call sub_509874
- ; Загрузить в регистр ECX значение из памяти
- .text:00441D81 mov ecx, dword_52A494
- .text:00441D87 test ecx, ecx
- ; Если оно не нулевое, то вывести текст о зарегистрированной программе
- .text:00441D89 jnz short loc_441DCB
- .text:00441D8B mov [ebp+var_24], 14h
- ; Загрузить строку с индексом 4654h (Unregistered Version)
- .text:00441D91 push 4654h
- .text:00441D96 call sub_402578
- .text:00441D9B pop ecx
- .text:00441D9C mov edx, eax
- .text:00441D9E lea eax, [ebp+var_8]
- .text:00441DA1 call sub_5097B8
- .text:00441DA6 inc [ebp+var_18]
- .text:00441DA9 mov edx, [eax]
- .text:00441DAB mov eax, [ebp+var_38]
- .text:00441DAE mov eax, [eax+534h]
- .text:00441DB4 call @Controls@TControl@SetText
- .text:00441DB9 dec [ebp+var_18]
- .text:00441DBC lea eax, [ebp+var_8]
- .text:00441DBF mov edx, 2
- .text:00441DC4 call sub_509874
- .text:00441DC9 jmp short loc_441E47
- .text:00441DCB ; -------------------------------
- .text:00441DCB loc_441DCB:
- .text:00441DCB push offset byte_571670
- ; Загрузить строку с индексом 4655h (This Product is Authorized to:)
- .text:00441DD0 push 4655h
- .text:00441DD5 call sub_402578
- .text:00441DDA pop ecx
- .text:00441DDB push eax
- .text:00441DDC push offset aSS_16 ; "%s %s"
- .text:00441DE1 lea ecx, [ebp+buffer]
- .text:00441DE7 push ecx ; buffer
- .text:00441DE8 call _sprintf
- .text:00441DED add esp, 10h
- .text:00441DF0 mov [ebp+var_24], 20h
- .text:00441DF6 lea edx, [ebp+buffer]
- .text:00441DFC lea eax, [ebp+var_C]
- .text:00441DFF call sub_5097B8
- .text:00441E04 inc [ebp+var_18]
- .text:00441E07 mov edx, [eax]
- .text:00441E09 mov eax, [ebp+var_38]
- .text:00441E0C mov eax, [eax+534h]
- .text:00441E12 call @Controls@TControl@SetText
- .text:00441E17 dec [ebp+var_18]
- .text:00441E1A lea eax, [ebp+var_C]
- .text:00441E1D mov edx, 2
Code (Assembler) : Убрать нумерацию
- .text:0044247D mov dword_52A3F8, edx
- .text:00442483 mov ecx, dword_54E0F8
- .text:00442489 cmp ecx, 5000h
- ; Первая проверка
- .text:0044248F jnz short loc_44249D
- .text:00442491 mov eax, dword_533C58
- .text:00442496 cmp eax, 5600h
- ; Вторая проверка
- .text:0044249B jz short loc_4424A7
- .text:0044249D loc_44249D:
- ; Установить флаг "программа не зарегистрирована"
- .text:0044249D xor edx, edx
- .text:0044249F mov dword_52A494, edx
- .text:004424A5 jmp short loc_4424B1
- .text:004424A7 ; -------------------------------
- .text:004424A7 loc_4424A7:
- ; Установить флаг "программа зарегистрирована"
- .text:004424A7 mov dword_52A494, 1
- .text:004424B1 loc_4424B1:
- .text:004424B1 mov ecx, [ebp+var_4]
- .text:004424B4 mov eax, [ecx+6D4h]
- .text:004424BA mov dword_52A404, eax
Программа успешно "зарегистрирована"
В окне "About" мы наблюдаем введенное ранее регистрационное имя, в главном загрузочном меню пропала надпись о программе, то есть программа считает себя зарегистрированной. Более того, она теперь принимает любое имя и любой серийный номер. Сигнатура для поиска очень приметная, можно легко сделать универсальный патч для всех версий.
Мои благодарности разработчикам за отличную программу и отдельное спасибо за не слишком навороченную защиту :)
Просмотров: 6578 | Комментариев: 9
Метки: исследование защиты, система
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
X-Wing Top Ace
(25.11.2014 в 16:38):
Точнее говоря, вы поняли, что я пишу дело - в чем я не сомневался и писАл свои соображения не для того, чтобы перед кем-нибудь выпендриться, а по существу.
А при более надежном варианте с подменой команд инита можно вообще не заморачиваться, есть выкрутасы (вернее, часто применяемая их разновидность) или нет - кряк будет рабочий.
Можно, но не нужно. Я бы сказал, "материться в коде" (от кода команды безусловного перехода 0EBh) нужно в том и только том случае, если без этого крякнуть невозможно. Ну лень мне долго гонять ломаную прогу на предмет наличия таких выкрутасов, если есть способ взломки, заведомо сводящий их на нет. Кстати, про HIEW ходят слухи, что выкрутасы там имеются, но у меня покамест ни разу не вылезли - ломал, по вашим же словам, очень элегантно, и если там есть сабжевые выкрутасы, сработать они просто не могли.
ManHunter
(25.11.2014 в 11:40):
X-Wing Top Ace, соглашусь. Но тут все чистенько, без выкрутасов, так что _в данном конкретном случае_ можно патчить и переходы.
X-Wing Top Ace
(25.11.2014 в 11:34):
Вот этот вариант не лучший - еще под доской приходилось сталкиваться с шароварными прогами, в которых управление передавалось на сброс флагов регистрации откуда-то еще, причем хитровывернутым способом типа "mov bx, NagSetAddr; call far cs:bx" - понимаю, что в примере код кривой, но не в примерах он был корректный и в дизасме так просто уже не ловился.
Второй вариант кряка - подмена инита состояния регистрации - не только более элегантный, но и куда как более надежный. Можно сколько угодно передавать туда управление самыми хитрыми способами, оно передастся на тот код, который изменен в нужную сторону. ;)
ManHunter
(23.11.2014 в 17:27):
Опечатка: 52A494. Видимо в буфер что-то не то попало, когда писал статью.
Поправил, спасибо!
Поправил, спасибо!
Alex
(23.11.2014 в 17:19):
ManHunter подскажите как найти адрес 54E0F8
AyTkACT
(18.11.2014 в 16:39):
ManHunter, я то подумал это автоанализ. :(
ManHunter
(18.11.2014 в 16:35):
Как-то так: http://rghost.ru/59131552/image.png
AyTkACT
(18.11.2014 в 16:25):
Давно хотел спросить: этот код из IDA? Если да, то как сделать чтобы сама IDA представляла
.data:005283AC db 55h ; U
.data:005283AD db 46h ; F
.data:005283AE db 0
.data:005283AF db 0
в виде
.data:005283AC dd 4655h
как у тебя?
.data:005283AC db 55h ; U
.data:005283AD db 46h ; F
.data:005283AE db 0
.data:005283AF db 0
в виде
.data:005283AC dd 4655h
как у тебя?
Добавить комментарий
Заполните форму для добавления комментария
(Все адреса для актуальной на текущий момент версии - 6.6.0.800)
В различных местах есть не только проверки флага зарегистрированности,, но и сравнения dword_54F9CC с константой 5000h, как и при инициализации флага, с последующим условным переходом или вызовом call exit. Imho, лучший вариант - замена километровой функции проверки ключа по адресу 004016E4 последовательностью команд:
mov dword_54F9CC, 5000h
mov dword_53482C, 5600h
mov eax, 1
retn
Останется занопить один переход (004028FF), чтобы наша псевдо-проверка ключа выполнялась даже при отсутствии рег. данных.
А если дальше поискать места, где выставляются эти дворды, увидим ещё аж три! штуки проверок, ббайт в байт идентичных первой километровой процедуре, которые могут испортить нам всю малину, они как раз и вызываются перед возможными "сюрпризами". Дело за малым - вписываем в их начало ret и очередной пациент полностью вылечен.
Патченный файл: _xttp://www.upload.ee/files/5466341/ezb660-800.7z.html
P.S. Первый раз здесь оставляю коммент. Если ссылки не приветствуются, прошу больно не бить. И огромное спасибо автору за передачу бесценных знаний молодому поколению.