Исследование защиты игры Kyodai Mahjongg
Скриншот игры Kyodai Mahjongg
Kyodai Mahjongg - сборник красивых китайских трехмерных головоломок. Хорошая графика, множество настроек, различные варианты игр, многоязычный интерфейс, поддержка сетевой игры. Я люблю коротать время за разбором маджонгов, но выкладывать за игры деньги - это уже за пределами моего понимания.
Забираем с сайта дистрибутив, устанавливаем, запускаем. Сразу появляется сообщение, что надо бы прогуляться до ближайшей кассы, расстаться с некоторой суммой для поддержания штанов автора, ну и все такое.
Триальное окно
Но это еще не так плохо, как сообщения, которые периодически появляются во время игры. При этом даже сам автор согласен, что эти сообщения мерзкие.
Триальное окно
Главный исполняемый файл упакован обычным UPX, который без проблем снимается им же самим upx -d kmj.exe, после чего распакованный файл отправляем в дизассемблер. Параллельно посмотрим, как ведет себя игра в случае ввода неправильных данных:
Сообщение о неправильной регистрации
Поскольку интерфейс многоязычный, надо искать соответствие в языковых файлах. В файле русского языка обнаружится вот такая запись:
Строка сообщения в языковом файле
То есть строка сообщения на английском является индексом для локализованной строки. Вернемся к дизассемблеру и поищем, где эта строка используется и при каких условиях появляется. Обнаружится следующий код:
Code (Assembler) : Убрать нумерацию
- CODE:004B7D66 call sub_4049F4
- CODE:004B7D6B mov eax, ebx
- CODE:004B7D6D call sub_4CF8FC
- CODE:004B7D72 mov eax, ebx
- ; Вызвать функцию проверки
- CODE:004B7D74 call sub_4B9AF0
- ; Если она вернула AL=0, то введенный серийник неправильный
- CODE:004B7D79 test al, al
- CODE:004B7D7B jz short loc_4B7DED
- ; Сохранить регистрационные данные в реестре
- CODE:004B7D7D mov ecx, offset aSoftwareNamida
- ; "Software\\Namida"
- CODE:004B7D82 mov dl, 1
- CODE:004B7D84 mov eax, off_4332FC
- CODE:004B7D89 call sub_4343D8
- CODE:004B7D8E mov esi, eax
- CODE:004B7D90 mov eax, [ebx+0A2B98h]
- CODE:004B7D96 push eax
- CODE:004B7D97 mov ecx, offset aReguser ; "RegUser"
- CODE:004B7D9C mov edx, offset aKyodai_1 ; "Kyodai"
- CODE:004B7DA1 mov eax, esi
- CODE:004B7DA3 mov edi, [eax]
- CODE:004B7DA5 call dword ptr [edi+4]
- CODE:004B7DA8 mov eax, [ebx+0A2B9Ch]
- CODE:004B7DAE push eax
- CODE:004B7DAF mov ecx, offset aRegpass ; "RegPass"
- CODE:004B7DB4 mov edx, offset aKyodai_1 ; "Kyodai"
- CODE:004B7DB9 mov eax, esi
- CODE:004B7DBB mov edi, [eax]
- CODE:004B7DBD call dword ptr [edi+4]
- CODE:004B7DC0 mov eax, esi
- CODE:004B7DC2 call sub_403BAC
- CODE:004B7DC7 lea ecx, [ebp+var_C]
- CODE:004B7DCA mov edx, offset aThanksAgainYou
- ; "Thanks again ! You're now registered."
- CODE:004B7DCF mov eax, [ebx+444h]
- CODE:004B7DD5 call sub_47D9D8
- CODE:004B7DDA mov eax, [ebp+var_C]
- CODE:004B7DDD mov cx, word_4B7F00
- CODE:004B7DE4 mov dl, 2
- CODE:004B7DE6 call sub_4B3148
- CODE:004B7DEB jmp short loc_4B7E50
- CODE:004B7DED ; --------------------------------------
- CODE:004B7DED loc_4B7DED:
- CODE:004B7DED mov eax, [ebx+0A2B98h]
- CODE:004B7DF3 call sub_404C60
- CODE:004B7DF8 cmp eax, 8
- CODE:004B7DFB jge short loc_4B7E23
- CODE:004B7DFD lea ecx, [ebp+var_10]
- CODE:004B7E00 mov edx, offset aTheUserNameMus
- ; "The user name must be at least 8 charac"...
- CODE:004B7E05 mov eax, [ebx+444h]
- CODE:004B7E0B call sub_47D9D8
- CODE:004B7E10 mov eax, [ebp+var_10]
- CODE:004B7E13 mov cx, word_4B7F00
- CODE:004B7E1A mov dl, 2
- CODE:004B7E1C call sub_4B3148
- CODE:004B7E21 jmp short loc_4B7E50
- CODE:004B7E23 ; --------------------------------------
- CODE:004B7E23 loc_4B7E23:
- CODE:004B7E23 lea ecx, [ebp+var_14]
- CODE:004B7E26 mov edx, offset aSorryWrongPass
- ; "Sorry, wrong password. Please check out"...
- CODE:004B7E2B mov eax, [ebx+444h]
- CODE:004B7E31 call sub_47D9D8
- CODE:004B7E36 mov eax, [ebp+var_14]
- CODE:004B7E39 mov cx, word_4B7F00
- CODE:004B7E40 mov dl, 2
- CODE:004B7E42 call sub_4B3148
Code (Assembler) : Убрать нумерацию
- CODE:004B9B21 sub eax, 2
- CODE:004B9B24 jl short loc_4B9B48
- CODE:004B9B26 inc eax
- CODE:004B9B27 mov edx, 2
- CODE:004B9B2C loc_4B9B2C:
- CODE:004B9B2C mov ecx, [ebx+0A2B98h]
- CODE:004B9B32 mov cl, [ecx+edx-1]
- CODE:004B9B36 mov esi, [ebx+0A2B98h]
- CODE:004B9B3C cmp cl, [esi]
- CODE:004B9B3E jz short loc_4B9B44
- CODE:004B9B40 mov [ebp+var_1], 0
- CODE:004B9B44 loc_4B9B44:
- CODE:004B9B44 inc edx
- CODE:004B9B45 dec eax
- CODE:004B9B46 jnz short loc_4B9B2C
Code (Assembler) : Убрать нумерацию
- CODE:004B9BB7 lea ecx, [ebp+var_10]
- CODE:004B9BBA mov edx, offset aUnregistered_0
- ; "UNREGISTERED"
- CODE:004B9BBF mov eax, [ebx+444h]
- CODE:004B9BC5 call sub_47D9D8
- CODE:004B9BCA mov edx, [ebp+var_10]
- CODE:004B9BCD mov eax, [ebx+0A2B9Ch]
- CODE:004B9BD3 call sub_404DAC
- CODE:004B9BD8 jz loc_4BCAE1
- CODE:004B9BDE mov eax, [ebx+0A2B98h]
- CODE:004B9BE4 mov edx, offset aJohnnyXC398
- ; "Johnny+X/C3'98!"
- CODE:004B9BE9 call sub_404DAC
- CODE:004B9BEE jz loc_4BCA94
- CODE:004B9BF4 lea edx, [ebp+var_14]
- CODE:004B9BF7 mov eax, [ebx+0A2B98h]
- CODE:004B9BFD call sub_4089F0
- CODE:004B9C02 mov eax, [ebp+var_14]
- CODE:004B9C05 mov edx, offset aCosmoCramer
- ; "cosmo cramer"
- CODE:004B9C0A call sub_404DAC
- CODE:004B9C0F jz loc_4BCA94
- CODE:004B9C15 mov eax, [ebx+0A2B98h]
- CODE:004B9C1B mov edx, offset aRevealsSerialN
- ; "Reveals Serial Numbers"
- CODE:004B9C20 call sub_404DAC
- CODE:004B9C25 jz loc_4BCA94
- CODE:004B9C2B mov eax, [ebx+0A2B98h]
- CODE:004B9C31 mov edx, offset aCobra1997
- ; "Cobra 1997"
- ...
- ...
- ...
Список заблокированных имен
Такое впечатление, что упорная работа автора, о которой он так настойчиво твердит, заключается в отслеживании и блокировке серийников к своему поделию. Едем дальше. Между этими двумя проверками есть следующий код. Если его пройти в отладчике, то все сразу встанет на свои места.
Code (Assembler) : Убрать нумерацию
- CODE:004B9B6D push eax
- CODE:004B9B6E xor ecx, ecx
- CODE:004B9B70 mov edx, [ebx+0A2B98h]
- CODE:004B9B76 mov eax, ebx
- CODE:004B9B78 call sub_4B5FD4
- CODE:004B9B7D mov eax, [ebp+var_8]
- CODE:004B9B80 mov edx, [ebx+0A2B9Ch]
- CODE:004B9B86 call sub_404DAC
- CODE:004B9B8B jz short loc_4B9BB7
- CODE:004B9B8D lea eax, [ebp+var_C]
- CODE:004B9B90 push eax
- CODE:004B9B91 mov ecx, 2
- CODE:004B9B96 mov edx, [ebx+0A2B98h]
- CODE:004B9B9C mov eax, ebx
- ; Сгенерировать правильный серийный номер для введенного имени
- CODE:004B9B9E call sub_4B5FD4
- CODE:004B9BA3 mov eax, [ebp+var_C]
- CODE:004B9BA6 mov edx, [ebx+0A2B9Ch]
- ; Сравнить введенный серийник с правильным
- CODE:004B9BAC call sub_404DAC
- CODE:004B9BB1 jnz loc_4BCAE1
Серийные номера
Таким образом, регистрационному имени "ManHunter / PCL" соответствует серийный номер "347297675699273". Закрываем отладчик, запускаем игру в обычном режиме, повторяем регистрацию, но уже с найденным серийным номером:
Программа успешно зарегистрирована
Игра еще раз благодарит, после чего переходит в полноценный режим работы. Никакие триальные окна больше не появляются, все работает как надо. Цель достигнута. Теперь автору придется добавить к списку блокировки еще одно имя. Но мы его напрягать лишний раз не будем, а посмотрим на алгоритм генерации правильного серийного номера. Лучше это делать под отладчиком. Загружаем исполняемый файл в отладчик, ставим точку останова по адресу 004B5FD4, запускаем и пытаемся зарегистрировать. Когда точка останова сработает, в пошаговом режиме пройдем функцию генерации серийника.
Code (Assembler) : Убрать нумерацию
- CODE:004B6039 mov edx, [ebp+var_8]
- CODE:004B603C movzx eax, byte ptr [edx+eax-1]
- CODE:004B6041 mov edx, [ebp+var_8]
- CODE:004B6044 movzx edx, byte ptr [edx]
- CODE:004B6047 add eax, edx
- CODE:004B6049 mov ecx, 0Ah
- CODE:004B604E xor edx, edx
- CODE:004B6050 div ecx
- CODE:004B6052 add edx, 30h
Code (Assembler) : Убрать нумерацию
- CODE:004B606C mov ebx, 2
- CODE:004B6071 loc_4B6071:
- CODE:004B6071 mov eax, [ebp+var_8]
- CODE:004B6074 movzx eax, byte ptr [eax+ebx-2]
- CODE:004B6079 mov edx, [ebp+var_8]
- CODE:004B607C movzx edx, byte ptr [edx+ebx-1]
- CODE:004B6081 add eax, edx
- CODE:004B6083 mov ecx, 0Ah
- CODE:004B6088 xor edx, edx
- CODE:004B608A div ecx
- CODE:004B608C add edx, 30h
- CODE:004B608F lea eax, [ebp+var_1C]
- CODE:004B6092 call sub_404B88
- CODE:004B6097 mov edx, [ebp+var_1C]
- CODE:004B609A mov eax, edi
- CODE:004B609C call sub_404C68
- CODE:004B60A1 inc ebx
- CODE:004B60A2 dec esi
- CODE:004B60A3 jnz short loc_4B6071
Code (Assembler) : Убрать нумерацию
- ; Keygen для Kyodai Mahjongg
- mov edi,serial
- mov esi,name
- mov ecx,[name_len]
- mov ebx,10
- xor eax,eax
- loc_loop:
- or eax,eax
- lodsb
- jnz @1
- add al,byte[esi+ecx-2]
- dec esi
- jmp @2
- @1:
- add al,byte[esi]
- @2:
- cdq
- div ebx
- xchg eax,edx
- add al,'0'
- stosb
- loop loc_loop
- xor eax,eax
- stosb
Просмотров: 1750 | Комментариев: 6
Метки: исследование защиты, игры
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Sonia
(11.01.2023 в 08:54):
Серийник из статьи подошел) спасибо за ваш труд, еле нашла рабочий
ManHunter
(13.04.2021 в 18:10):
Если речь про классический маджонг, то там фишки должны быть не только одинаковые, но при этом еще и свободные, то есть как минимум с одной из боковых сторон не должно лежать другой фишки.
brute
(13.04.2021 в 17:39):
"выиграл" за 40 минут. Там не просто одинаковые фишки надо нажимать, но и в определённой последовательности?
Sergii
(13.04.2021 в 08:45):
Прекрасная подача материала! Спасибо. Учусь
voffka
(07.04.2021 в 20:16):
Вот это антиквариат. Один из первых моих кейгенов.
Добавить комментарий
Заполните форму для добавления комментария
спасибо за серийник.