Исследование защиты программы Deep Green Reversi
Скриншот программы Deep Green Reversi
И снова мои любимые реверси! Сегодня это будут Deep Green Reversi. Дизайн у этой игрушки просто чудовищный, нагруженный свистоперделками и всякими спецэффектами по самое небалуйся. К счастью, практически все их можно отключить в настройках. Сайт разработчика тоже застрял где-то на заре интернета, когда считалось хорошим тоном оформлять странички вырвиглазными анимированными гифками и неоновыми шрифтами. Но все это сразу забывается, когда начинаешь играть. Кроме обычной настройки сложности, в Deep Green Reversi настраивается и стратегия игры компьютера, например, хитрый захват углов или смешанный режим игры. В результате компьютер становится отличным соперником. Если не хватает машинного интеллекта, можете сыграть с кем-нибудь по сети или с товарищем за одним компьютером. Еще в набор минусов следует отнести шароварность игры, но это дело как раз поправимо.
Скачиваем дистрибутив с офсайта, устанавливаем, запускаем, смотрим. Внешними признаками незарегистрированной программы являются характерные надписи в заголовке и в окне "О программе".
Программа не зарегистрирована
Еще на сайте что-то написано про 30 дней триального срока, но это пока оставим. Начнем с поиска строк "Unregistered".
Строка в файле
Количество статей по исследованию защит уже давно перевалило за сотню, надо ли в очередной раз напоминать, что главный исполняемый файл после установки должен находиться на вскрытии в дизассемблере? Ну так вот, нужную строчку в файле мы нашли, поищем в листинге дизассемблера место, где она используется.
Code (Assembler) : Убрать нумерацию
- .text:00401956 mov ecx, [ebx+5A4h]
- .text:0040195C push ecx
- ; Вызвать функцию проверки
- .text:0040195D call sub_40F954
- .text:00401962 pop ecx
- .text:00401963 test eax, eax
- ; Если она вернула EAX!=0, то в заголовок ничего не добавлять
- .text:00401965 jnz loc_401A26
- .text:0040196B mov word ptr [esi+10h], 14h
- .text:00401971 xor eax, eax
- .text:00401973 lea edx, [ebp+var_8]
- .text:00401976 mov [ebp+var_8], eax
- .text:00401979 mov eax, ebx
- .text:0040197B inc dword ptr [esi+1Ch]
- .text:0040197E call @TControl@GetText$qqrv
- .text:00401983 lea edx, [ebp+var_8]
- .text:00401986 push edx
- ; Добавить в заголовок окна строчку "Unregistered"
- .text:00401987 mov edx, offset aUnregistered
- ; " - Unregistered"
- .text:0040198C lea eax, [ebp+var_C]
- .text:0040198F call sub_55FD64
- .text:00401994 inc dword ptr [esi+1Ch]
Code (Assembler) : Убрать нумерацию
- .text:0040F954 push ebp
- .text:0040F955 mov ebp, esp
- .text:0040F957 mov eax, [ebp+arg_0]
- .text:0040F95A cmp dword ptr [eax+80630h], 1
- .text:0040F961 jnz short loc_40F96A
- .text:0040F963 mov eax, 1
- .text:0040F968 pop ebp
- .text:0040F969 retn
- .text:0040F96A ; -------------------------------
- .text:0040F96A loc_40F96A:
- .text:0040F96A xor eax, eax
- .text:0040F96C pop ebp
- .text:0040F96D retn
Функция проверки регистрации после патча
Вот теперь можно сохранять изменения и проверять работоспособность игры. Надписи в заголовке и в окне "О программе" пропали.
Программа успешно "зарегистрирована"
Для чистоты эксперимента переводим часы на пару месяцев вперед и вновь проверяем работоспособность. Ограничения по времени тоже нет. Цель достигнута, можно спокойно наслаждаться игрой.
В комментариях справедливо указали, что патчить совсем не обязательно, а можно подсмотреть правильный серийный номер при проверке введенных регистрационных данных. Начнем с того, как программа отреагирует на заведомо неправильные регистрационные данные:
Сообщение о неправильной регистрации
Строчка легко обнаруживается в файле, но вот прямых ссылок на нее в дизассемблере найти не удалось. Автор позаботился об этом, и, по всей видимости, сделал косвенную адресацию. Но зато рядом с этим строками есть другие, на которые IDA любезно выдает подсказку, что ссылающаяся процедура называется "TRegistrationForm_RegBtnClick".
Code (Assembler) : Убрать нумерацию
- .data:00587638 aXorolc_0 db '[Xorolc]',0
- ; DATA XREF: _TRegistrationForm_RegBtnClick
- .data:00587641 aXorolc@tno_c_1 db 'Xorolc@tNO.com',0
- .data:00587650 aDoYouFeelGuilt db 'Do you feel guilty using this registration?',0
- ...
- .data:0058772B db 0
- .data:0058772C aInvalidRegistr db 'Invalid Registration',0
- .data:00587741 aThankYouForReg db 'Thank you for Registering.',0
Code (Assembler) : Убрать нумерацию
- .text:00412B39 mov eax, off_59375C
- .text:00412B3E mov ecx, [eax]
- .text:00412B40 mov eax, [ecx+5A4h]
- .text:00412B46 push eax ; int
- ; Вызвать функцию проверки
- .text:00412B47 call sub_40F710
- .text:00412B4C add esp, 14h
- ; Если она вернула EAX=1, то установить EDX=1
- .text:00412B4F test eax, eax
- .text:00412B51 setz dl
- .text:00412B54 and edx, 1
- .text:00412B57 lea eax, [ebp+var_2C]
- ; Сохранить значение EDX в стеке
- .text:00412B5A push edx
- .text:00412B5B mov edx, 2
- .text:00412B60 dec dword ptr [esi+1Ch]
- .text:00412B63 call sub_55FEC4
- .text:00412B68 dec dword ptr [esi+1Ch]
- .text:00412B6B lea eax, [ebp+var_28]
- .text:00412B6E mov edx, 2
- .text:00412B73 call sub_55FEC4
- .text:00412B78 dec dword ptr [esi+1Ch]
- .text:00412B7B lea eax, [ebp+var_24]
- .text:00412B7E mov edx, 2
- .text:00412B83 call sub_55FEC4
- .text:00412B88 dec dword ptr [esi+1Ch]
- .text:00412B8B lea eax, [ebp+var_20]
- .text:00412B8E mov edx, 2
- .text:00412B93 call sub_55FEC4
- ; Забрать сохраненное значение из стека
- .text:00412B98 pop ecx
- ; CL=1 ?
- .text:00412B99 test cl, cl
- ; Да, переход
- .text:00412B9B jz short loc_412BE9
- ; Вывести сообщение о неправильной регистрации
- .text:00412B9D mov word ptr [esi+10h], 44h
- ; Вот здесь неявно загружается указатель на строку "Invalid Registration"
- .text:00412BA3 lea edx, [edi+0F4h]
- .text:00412BA9 lea eax, [ebp+var_30]
- .text:00412BAC call sub_55FD64
- .text:00412BB1 inc dword ptr [esi+1Ch]
- .text:00412BB4 mov eax, [eax]
- ; Вывести сообщение
- .text:00412BB6 call @Dialogs@ShowMessage
- .text:00412BBB dec dword ptr [esi+1Ch]
Code (Assembler) : Убрать нумерацию
- .text:0040F725 jmp short loc_40F72E
- .text:0040F727 ; -------------------------------
- .text:0040F727 loc_40F727:
- .text:0040F727 movsx eax, byte ptr [esi]
- .text:0040F72A add ebx, eax
- .text:0040F72C inc edi
- .text:0040F72D inc esi
- .text:0040F72E loc_40F72E:
- .text:0040F72E mov edx, [ebp+s]
- .text:0040F731 push edx ; s
- .text:0040F732 call _strlen
- .text:0040F737 pop ecx
- .text:0040F738 cmp edi, eax
- .text:0040F73A jb short loc_40F727
Code (Assembler) : Убрать нумерацию
- .text:0040F743 jmp short loc_40F74C
- .text:0040F745 ; -------------------------------
- .text:0040F745 loc_40F745:
- .text:0040F745 movsx eax, byte ptr [esi]
- .text:0040F748 add ebx, eax
- .text:0040F74A inc edi
- .text:0040F74B inc esi
- .text:0040F74C loc_40F74C:
- .text:0040F74C mov edx, [ebp+arg_8]
- .text:0040F74F push edx ; s
- .text:0040F750 call _strlen
- .text:0040F755 pop ecx
- .text:0040F756 cmp edi, eax
- .text:0040F758 jb short loc_40F745
Code (Assembler) : Убрать нумерацию
- ; Прибавить к EBX константу 9C5h и занести это все в EDX
- .text:0040F7A7 lea edx, [ebx+9C5h]
- .text:0040F7AD push edx
- : Перевести число в строку
- .text:0040F7AE call unknown_libname_25
- ; BCC v4.x/5.x & BCB v1.0/v7.0 BDS2006 win32 runtime
- .text:0040F7B3 add esp, 0Ch
- .text:0040F7B6 mov edx, [ebp+arg_C]
- ; Побайтно сравнить с первой частью введенного серийника
- .text:0040F7B9 loc_40F7B9:
- .text:0040F7B9 mov cl, [eax]
- .text:0040F7BB cmp cl, [edx]
- .text:0040F7BD jnz loc_40F941
- .text:0040F7C3 test cl, cl
- .text:0040F7C5 jz short loc_40F7DD
- .text:0040F7C7 mov cl, [eax+1]
- .text:0040F7CA cmp cl, [edx+1]
- .text:0040F7CD jnz loc_40F941
- .text:0040F7D3 add eax, 2
- .text:0040F7D6 add edx, 2
- .text:0040F7D9 test cl, cl
- .text:0040F7DB jnz short loc_40F7B9
Code (Assembler) : Убрать нумерацию
- ; Заполнить массив константами
- .text:0040F76C mov [ebp+var_404], 0D87h
- .text:0040F776 mov [ebp+var_400], 2234h
- .text:0040F780 mov [ebp+var_3FC], 2231h
- .text:0040F78A mov [ebp+var_3F8], 128Bh
- .text:0040F794 mov [ebp+var_3F4], 15ADh
- ...
- ...
- ...
- .text:0040F7EC mov eax, ebx
- .text:0040F7EE mov ecx, 5
- .text:0040F7F3 xor edx, edx
- ; Разделить сумму символов на 5
- .text:0040F7F5 div ecx
- ; Остаток - индекс массива с константой
- .text:0040F7F7 mov eax, [ebp+edx*4+var_404]
- .text:0040F7FE push eax
- ; Перевести константу в строку
- .text:0040F7FF call unknown_libname_25
- ; BCC v4.x/5.x & BCB v1.0/v7.0 BDS2006 win32 runtime
- .text:0040F804 add esp, 0Ch
- .text:0040F807 mov edx, [ebp+arg_10]
- ; Побайтно сравнить со второй половиной серийника
- .text:0040F80A loc_40F80A:
- .text:0040F80A mov cl, [eax]
- .text:0040F80C cmp cl, [edx]
- .text:0040F80E jnz loc_40F941
- .text:0040F814 test cl, cl
- .text:0040F816 jz short loc_40F82E
- .text:0040F818 mov cl, [eax+1]
- .text:0040F81B cmp cl, [edx+1]
- .text:0040F81E jnz loc_40F941
- .text:0040F824 add eax, 2
- .text:0040F827 add edx, 2
- .text:0040F82A test cl, cl
- .text:0040F82C jnz short loc_40F80A
- .text:0040F82E loc_40F82E:
- .text:0040F82E jnz loc_40F941
- .text:0040F834 mov eax, [ebp+arg_0]
- ; Установить флаг "Зарегистрировано"
- .text:0040F837 mov dword ptr [eax+80630h], 1
Программа успешно зарегистрирована
Кейген теперь вы можете написать самостоятельно. Кстати, регистрацию это чудо хранит аж в "c:\Program Files\Common Files\Fileid.bin". Ну да, чего ж еще ожидать от программы с такиим наворотами. Вот теперь действительно все.
Просмотров: 3069 | Комментариев: 10
Метки: исследование защиты, игры
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
brute
(16.11.2015 в 21:20):
До самого конца так и нет логического выхода на адрес 0040F954.. В IDR видна процедура обработки регистрации (по названию и форме) - 4128b8, также (методом тыка, по надписи "Invalid Registration" в стеке) находится переход на правильную регистрацию: 00412B99 test cl,cl (что не ведёт к регистрации - только сообщение!). Написано про ф-ю по адресу 00412B47, которая должна вернуть 1, причём принудительное mov dl,1 вместо sete dl не помогает!! Привел разбор ф. 00412B47: " Установить флаг "Зарегистрировано" .text:0040F837 mov dword ptr [eax+80630h], 1". Вот это и непонятно: как узнал, что В ЭТОЙ функции какой-то "левый" байт[eax+80630h] регистрирует программу? (и как нашёл 0040F954?). От 0040F82E jnz loc_40F941 до сообщения о регистрации километр кода!!!
Игорь
(22.10.2015 в 23:16):
Mahnhunter а можете статью написать по снятию защиты с какой-нибудь программы упакованную asprotect 2.1/2.2./2.3SKE?
X-Wing Top Ace
(19.10.2015 в 11:13):
Кряк получился очень элегантный. С таким можно и не подсматривать регистрационный номер.
ManHunter
(19.10.2015 в 10:31):
Ага, я это тоже заметил, когда подбирал серийник. Поэтому пришлось искать, куда оно сохраняет регу, чтобы пройти регистрацию уже в нормальном режиме.
Noobie
(19.10.2015 в 09:45):
Забавно другое: если во время трассировки устанавливать флаг Z во время сравнения произвольного и правильного номера, то программа перепишет файл bin и будет считать себя зарегенной, при любых значениях серийника, то есть его проверка осуществляется только в момент ввода, а дальше рояли не играет. Поэтому сериал 1234-5678 вполне валидный :-)
user
(19.10.2015 в 03:02):
)) Затем, что программы не на одном компьютере работают, и на них регулярно чистки случаются. Или просто распаковать программу и работать с нею, или ещё возиться с "регистрациями". Даже если в виде .reg-файла - всё равно напряжно.
ManHunter
(19.10.2015 в 00:05):
Добавил полный разбор алгоритма регистрации.
Vnv
(18.10.2015 в 18:36):
Зачем? Один раз ввел, подсмотрел свой код и ... Вот мой:
Vnv
com@com.com
3882-8756
user
(18.10.2015 в 18:27):
- а потом постоянно вводить єту абракадабру? - Извините..
Vnv
(18.10.2015 в 11:00):
Сумма всех букв имени и e-mail, какие-то преобразования и сверка регистрационного номера, который можно подсмотреть: 0040F710
Добавить комментарий
Заполните форму для добавления комментария