Генерирование паролей для Super Castlevania IV и Rock n' Roll Racing

    Добрый день, уважаемые пользователи.

    Недавно я написал пост про генерацию паролей на первый и второй Road Rash. В комментариях к статья меня попросили разъяснить, а как устроена система паролей в игре Rock n' Roll Racing. Про это я и хотел бы с вами поговорить. Но начать хотелось бы с игры Super Castlevania IV. Ну что ж, приступим.

    image

    Super Castlevania IV


    Игры для SNES я ещё не разу не «взламывал». Ну, до одного момента. Как-то я увидел своего брата, играющего в эту игру. И он как-бы невзначай сказал, что было бы очень хорошо, если бы можно было генерировать пароли на Super Castlevania IV. Недолго думая, я принялся за дело. После трёх бессонных ночей, я понял что и каким образом сохраняет пароль.

    Теория

    Пароль состоит из 16 ячеек (позиций), каждая ячейка состоит из 2 битов, итого 16*2= 32 бита. Эти биты сохраняют данные игровые параметры:
    • номер уровня (0-14)
    • имя игрока из 8 символов
    • квест (1-4)

    Теперь посмотрим из чего состоит сырой пароль:

    * в скобках будет указан номер бита.
    C4(1),C4(0) D(1), D(0) ?(1), ?(0) C2(1), C2(0)
    C6(1), C6(0) N(15), N(14) U1(1), U1(0) C5(1), C5(0)
    U2(1), U2(0) C1(1), C1(0) ?(1), ?(0) L(1), L(0)
    N(13), N(12) C3(1), C3(0) L(3), L(2) U3(1), U3(0)

    Обозначения

    ? — всегда равен нулю.
    U — неиспользуемые биты.
    D — (квест -1) (1-4) в двоичной системе счисления. ( 00 — нормальная сложность, 01 — повышенная сложность. В Интернете я не находил паролей на 3 и 4 квест. Игра зачем-то записывает эти данные. Сложность расти не будет, но вдруг, если пройти четвёртый квест, откроется секретная концовка? Хотя… скорее всего ничего не измениться.)
    N — значение имени в двоичной системе счисления. Из начального значения вычитается сумма значений имени.

    * в скобках записаны значения символов.
    * [ ] — пробел.
    A (11) B (12) C (13) D (14) E (15) F (16) G (17) H (18) I (19)
    J (20) K (21) L (22) M (23) N (24) O (25) P (26) Q (27) R (28)
    S (29) T (30) U (31) V (32) W (33) X (34) Y (35) Z (36) [ ] (0)
    1 (2) 2 (3) 3 (4) 4 (5) 5 (6) 6 (7) 7 (8) 8 (9) 9 (10)


    L — (номер уровня (0-14) div3) в двоичной системе счисления.

    * уровень B-3 состоит из трёх частей.
    Номер Уровень Начальное значение имени
    0 1-1 2040
    1 2-1 10240
    2 3-1 14340
    3 4-1 34826
    4 5-1 10256
    5 6-1 43026
    6 7-1 51226
    7 8-1 43042
    8 9-1 47142
    9 A-1 55343
    10 B-1 14388
    11 B-3 (1) 63543
    12 B-3 (2) 2104
    13 B-3 (3) 18489
    14 B-4 34874


    Контрольные суммы

    C1 = N(1), N(0) + D(1), D(0)
    C2 = N(3), N(2) + C1(3), C1(2) + U2(1), U2(0)
    C3 = N(5), N(4) + C2(3), C2(2) + U1(1), U1(0)
    C4 = N(7), N(6) + C3(3), C3(2) + U3(1), U3(0)
    C5 = N(9), N(8) + C4(3), C4(2)
    C6 = N(11), N(10) + C5(3), C5(2)

    Хочу обратить Ваше внимание на то, что два старших бита из одной контрольной суммы переходят в следующую контрольную сумму.

    Кодирование

    image

    0 (00) — пусто.
    1 (01) — секира.
    2 (10) — святая вода.
    3 (11) — сердце.

    Пример генерации пароля
    Создадим пароль, который сохраняет данные параметры:
    • имя: «AWL[ ]VITA»
    • квест (4)
    • все неиспользуемые биты равны единице
    • уровень B-3 (2)


    Переводим значения в двоичную систему счисления:

    номер уровня (12div3=4) = 0100
    квест (4) = 4-1=3 = 11

    Вычисляем значение имени:

    AWL[ ]VITA = 11+33+22+0+32+19+30+11 = 158
    2104-158= 1946 = 11110011010
    N(15), N(14) = 00
    N(13), N(12) = 00
    N(11), N(10) = 01
    N(9), N(8) = 11
    N(7), N(6) = 10
    N(5), N(4) = 01
    N(3), N(2) = 10
    N(1), N(0) = 10

    Вычисляем контрольные суммы:

    C1 = 10+11 = 0101
    C2 = 10+01+11 = 0110
    C3 = 01+01+11 = 0101
    C4 = 10+01+11 = 0110
    C5 = 11+01 = 0100
    C6 = 01+01 =10

    Записываем полученные данные в таблицу:

    10 11 00 10
    10 00 11 00
    11 01 00 00
    00 01 01 11

    Осталось перевести цифры в графическое изображение.


    Rock n' Roll Racing


    Эту игру я «взламывал» давно и тогда не пользовался методом битового разбора. Поэтому подход к этой игре будет немного другой.

    image

    Теория

    Пароль состоит из 12 позиций в которых сохраняются данные игровые параметры:
    • сложность (новобранец, ветеран, воин)
    • дивизия (A, B)
    • машины (5 нормальных + 3 глюкнутых)
    • цвет машины (5 нормальных + 1 глюкнутый)
    • планеты (6 нормальных + 2 глюкнутых)
    • персонажи (6 нормальных + 1 секретный + 1 глюкнутый)
    • броня автомобиля (1-4)
    • двигатель автомобиля (1-4)
    • подвеска автомобиля (1-4)
    • шины автомобиля (1-4)
    • шипы/мины (зависит от выбранной машины) (0-7)
    • нитро/прыжок (зависит от выбранной машины) (0-7)
    • ракеты/патроны (зависит от выбранной машины) (0-7)
    • количество денег (0-1599000$) с шагом = 1000.


    Теперь посмотрим, как изменяются значения в позициях в зависимости от выбранных игровых параметров:

    Сложность 1 позиция 4 позиция
    Новобранец +0 XOR5
    Ветеран XOR8 XOR1
    Воин XOR16 XOR13

    Дивизия 1 позиция 7 позиция
    A XOR8 +0
    B +0 +2

    Машина 2 позиция 3 позиция 9 позиция
    Глюк +0 +0 +0
    Глюк +0 XOR16 +4
    Глюк (cамоуничтожающаяся машина) XOR1 +0 +8
    Air Blade XOR1 XOR16 +12
    Marauder XOR2 +0 +16
    Dirt Devil XOR2 XOR16 +20
    Havac XOR3 +0 +24
    Battle Trak XOR3 XOR16 +28

    Цвет машины 2 позиция 8 позиция
    Красный XOR20 +0
    Зелёный XOR16 +1
    Чёрный XOR28 +2
    Синий XOR4 +4
    Глюк (розово-кислотно-зелёный цвет) +0 +5
    Жёлтый XOR12 +6

    Двигатель 1 позиция 10 позиция 11 позиция
    1 +0 +0 +16
    2 XOR4 +0 +0
    3 XOR8 +1 +16
    4 XOR12 +1 +0

    Шины 1 позиция 4 позиция 10 позиция
    1 +0 +0 +6
    2 XOR16 +0 +4
    3 +0 XOR16 +2
    4 XOR16 XOR16 +0

    Броня 3 позиция 9 позиция
    1 XOR4 +1
    2 +0 +0
    3 XOR12 +3
    4 XOR8 +2

    Подвеска 3 позиция 10 позиция
    1 +0 +8
    2 XOR1 +0
    3 XOR2 +24
    4 XOR3 +16

    Нитро/прыжок 1 позиция 2 позиция 11 позиция
    0 +0 +0 +8
    1 +0 XOR16 +10
    2 XOR1 +0 +12
    3 XOR1 XOR16 +14
    4 XOR2 +0 +0
    5 XOR2 XOR16 +2
    6 XOR3 +0 +4
    7 XOR3 XOR16 +6

    Шипы/мины 2 позиция 11 позиция 12 позиция
    0 +0 +1 +0
    1 XOR2 +1 +8
    2 XOR4 +1 +16
    3 XOR6 +1 +24
    4 XOR8 +0 +0
    5 XOR10 +0 +8
    6 XOR12 +0 +16
    7 XOR14 +0 +24

    Ракеты/патроны 2 позиция 3 позиция 12 позиция
    0 +0 +0 +0
    1 +0 XOR8 +1
    2 +0 XOR16 +2
    3 +0 XOR24 +3
    4 XOR1 +0 +4
    5 XOR1 XOR8 +5
    6 XOR1 XOR16 +6
    7 XOR1 XOR24 +7

    Планеты 1 позиция 7 позиция 8 позиция
    Bogmire +0 +1 +0
    New Mojave XOR1 +1 +8
    Chem VI XOR2 +1 +16
    Drakonis XOR3 +1 +24
    Глюк XOR4 +0 +0
    Глюк XOR5 +0 +8
    NHO XOR6 +0 +16
    Inferno XOR7 +0 +24

    Персонажи 1 позиция 3 позиция 4 позиция 7 позиция
    Tarquim +0 XOR1 XOR16 +0
    Jake Badlance XOR16 XOR1 XOR16 +4
    Глюк +0 XOR1 +0 +8
    Olaf (секретный персонаж) XOR16 XOR1 +0 +12
    Cyberhawk +0 +0 XOR16 +16
    Snake Sanders XOR16 +0 XOR16 +20
    Katarina Lions +0 +0 +0 +24
    Ivanzypher XOR16 +0 +0 +28


    Теперь посмотрим как изменяются позиции от количества денег:

    X1з.X2з.X3з.X4з.000$

    Количество денег нужно разделить на 1000 и по остатку определить изменения позиций.

    1 позиция = XOR (x$ div 200)
    2 позиция = XOR (3з.+ 0, если x$ div 100 чётное число, или +16, если нечётное число)
    3 позиция = XOR (4з.* 2)
    4 позиция = XOR (x$ div 400)
    5 позиция =((x$ div 100)mod4) XOR ((x$ div 20) mod5)
                     (             ↓            )
             ( Полученное число преобразуется)
                         в соответствии с
                            0 → 13
                            1 → 5
                            2 → 29
                            3 → 21

    6 позиция = ((x$ div 10)mod2) XOR 4з.
                     (             ↓            )
             ( Полученное число преобразуется)
                         в соответствии с
                             0 → 12
                             1 → 28

    Кодирование

    Символы в позициях принимают значения «BCDFGHJKLMNPQRSTVWXYZ0123456789!», где B=0, C=1… 9=30, !=31.

    Пример генерации пароля
    Создадим пароль, который сохраняет данные параметры:
    • сложность (ветеран)
    • дивизия (A)
    • машина (Dirt Devil)
    • цвет машины (красный)
    • планета (New Mojave)
    • персонаж (Cyberhawk)
    • броня (1)
    • двигатель (3)
    • подвеска (2)
    • шины (4)
    • шипы/мины (5)
    • нитро/прыжок (3)
    • ракеты/патроны (7)
    • деньги (1257000$)

    Вычисляем деньги:
    1257000/1000 = 1257
    1 позиция = 1257 div 200 = 6 = XOR6
    2 позиция = 5+(1257 div 100) = 5+12(так как число чётное, то +0) = 5+0 = XOR5
    3 позиция = 7*2 = 14 = XOR14
    4 позиция = 1257 div 400 = 3 = XOR3
    5 позиция = ((1257 div 100)mod4 = 0 → 13. 13 XOR (1257 div 20)mod5 = 13 XOR 2 = 15
    6 позиция = ((1257 div 10)mod2 = 1 → 28. 28 XOR 7 = 27

    Теперь записываем значения позиций в таблицу:
    * п. — позиция.
    1 п. 2 п. 3 п. 4 п. 5 п. 6 п. 7 п. 8 п. 9 п. 10 п. 11 п. 12 п.
    XOR6 XOR5 XOR14 XOR3 15 27 +1 +8 +20 +1 +16 +8
    XOR8 XOR2 XOR16 XOR1 +0 +0 +16 +0 +1 +0 +14 +7
    XOR8 XOR20 XOR4 XOR16 +0 +0 +0 +0 +0 +0 +0 +0
    XOR8 XOR10 XOR1 XOR16 +0 +0 +0 +0 +0 +0 +0 +0
    XOR16 XOR16 XOR24 +0 +0 +0 +0 +0 +0 +0 +0 +0
    XOR1 XOR1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
    XOR1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0


    Производим необходимые вычисления и получаем:
    30,8,3,2 15,27,17,8 21,1,30,15

    Теперь кодируем данную строку:

    9LFD T6WL 0C9T


    Заключение

    Ну что ж, надеюсь, я не слишком запутал Вас с Rock n' Roll Racing. Удачи, спасибо за прочтение.
    Поделиться публикацией
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 41
      +2
      Всё это безумно здорово, но было бы ещё круче, будь описание того, как были вычислены данные вещи.
        –3
        В тех играх, где есть свободный сейв — меня про одному и собирая пороли чаще всего.
          +6
          меня про одному и собирая пороли

          Интересная история, но не для этого сайта.
            +2
            Беспощадный русский язык
            +2
            меняЯ по одному, и собирая (генерируемые игрой) пАроли.
            0
            Я мог бы и описать, как всё это получено, но тогда бы статья была бы слишком большой. Но если вкратце, я собирал пароли и методом анализа находил насколько и как изменяются позиции при определенных значениях.
              0
              Так может тогда отдельную статью-туториал написать по методам анализа и вычислений?
              Я так понимаю, даже в случае разного способа кодирования, изначальный подход к вычислениям одинаковый?
                0
                Можно и написать, но я не уверен, что будут люди которым это нужно. Я когда эту публикацию писал всё задумывался данным вопросом: «Кому оно надо?»
                  +1
                  Нет если статьи нет — это точно никому не надо, а вот если есть статья — найдётся и тот, кому она нужна. Например, я.
                  +2
                  Есть много разных подходов к анализу, но основных не так много:

                  1. Анализ различий, самый простой метод, работает даже на приставке с бумагой и ручкой. Просто собираются пароли с минимальными различиями по состоянию. Например, в RRR можно выбирать одинаковую сложность, машину, цвет, но разных персонажей и записывать стартовые пароли (благо пароль доступен без прохождения чего-либо). Потом аналогично, только меняем другой параметр, например цвет машины. Тем самым можно понять в каких символах что хранится и заодно сделать предположения где же расположена контрольная сумма. В ряде игр на Sega типовой подход — алфавит не перемешан и обычно 5ти (или 4х битовое кодирование, в зависимости от длины алфавита), потому можно составить табличку в этом предположении что начальный символ алфавита это 00000, а конечный 11111 и выборку паролей сразу разобрать по битам.

                  2. Дизассемблирование ROM'а игры и нахождение кода генерации/проверки пароля. После чего с алгоритмом можно разобраться на уровне кода и сделать альтернативную реализацию (генератор паролей).

                  3. Комбинирование подходов п.1 и п.2 — например позволяет применять методы п.1 в случаях когда например алфавит реально перемешан, обычно перемешанную строку алфавита можно легко найти в ROM'е и составить правильную таблицу преобразования.

                  На деле достаточно много игр с типовой реализацией парольной системы и разбирать подобные однотипные системы не очень интересно. Гораздо интереснее разбирать игры с нестандартной системой, например когда длина пароля переменна как в Power Monger или Syndicate. Там уже подход из п.1 не применим и остаётся только п.2. Кроме того, часто бывает полезно потрогать «неиспользуемые» биты в паролях, иногда это приводит к забавным находкам (например Olaf в RRR или бессмертие в Stargate)
                    0
                    К играм с нестандартной и одной из самых сложных парольных систем, думаю можно еще отнести например X-Perts (Sega Genesis).
                      0
                      Если правильно помню глядя на код генератора паролей, там используется подход «нумерация всех возможных комбинаций», а не явное задание конкретных битов, когда определённые биты сырого пароля хранят какой-либо атрибут. Подобный же подход встречал и описывал в Pocahontas.
                +1
                Заранее извиняюсь, камера у меня весьма посредственная.
                Вот Вы спрашивали, как было это всё вычислено.
                Для примера возьму Super Castlevania IV.
                Для начала я записал пароли на первый уровень с разными именами:
                Нажми на меня
                image

                Потом я нашёл в Интернете пароли на второй квест и в итоге понял как номер квеста записывается в пароле.
                Потом я разобрался с контрольными суммами и неиспользуемыми битами, и записал готовый «генератор»:
                Нажми на меня
                image

                  0
                  Не поймите неправильно, но это очень похоже на уроки «Как нарисовать сову».
                  Нет, я примерно представляю как это делается и сам в детстве увлекался брутфорсом паролей к играм и даже в тетрадку записывал всё.
                  Особенно помню игрушку Goal 5 (наверняка пиратская, так что оригинальное название не знаю).
                  Цель игры — выиграть в чемпионате мира по футболу, изначально на выбор даётся 16 команд (или 32?), и каждый соперник выбирается рандомно. При этом пароля на каждый раунд два: когда противник ещё неизвестен, и когда противник уже выбран.
                  Разумеется, никаких предустановленных паролей не было и я тупым перебором подбирал пароли, выписывал их, смотрел, какой это матч и кто противник, пытался найти различия между паролями, но на тот момент и не думал о том, что всё кодируется в двоичном виде и переводится в символьный. Думал, что кодирование только символьное. А уж о контрольной сумме и не думал вовсе.
                    0
                    Вроде эта игра.
                    очень похоже на уроки «Как нарисовать сову»

                    Эта ещё одна причина из-за которой я не хотел писать статью-туториал.
                      0
                      Не, я про эту.
                      А от создателей Nekketsu я в хоккей рубился.
                        0
                        А игру получилось «взломать»?
                          +1
                          Я не помню, сколько паролей я подобрал — но у меня в несколько столбцов было исписано несколько страниц тетрадки :) И определённая закономерность там прослеживалась, но я не додумался в двоичную систему это переводить, чтобы искать было проще. Где сейчас эта тетрадь — неизвестно.
                          Не все из них брутом получены. Достаточно получить один пароль, где противник ещё не выбран, дождаться конца матча (проиграть) и получить пароль на игру с этим соперником. Потом ввести предыдущий и уже в том же раунде с другим противником сражаться, если рандом того же не подберёт.
                          Помню только, что в качестве стартового пароля выбрал тот, что даётся при проигрыше первого матча, а дальше перебором с последнего символа. Потому что брутить пароль вида AAAAAAAAAA перебором с инкрементом даже тогда выглядело для меня глупым.
                          В общем, в какой-то момент я бросил эту затею. Не хватило мне знаний для решения такой задачки. Да и было это лет 15 назад или больше.
                +5
                Tarquim scores the first place knock-out
                Jake finishes second
                Глюк takes a weak third
                Olaf is in another timezone
                  +1
                  А в Metal Gear на NES, помнится, было посложнее. Жаль в далёкие 90-е не было интернетов, тем не менее, понять, что последний символ является контрольной суммой, удалось даже не зная самого понятия «контрольная сумма» :)
                    +2
                    Интернета не было, но зато были книги кодов в которых были описаны алгоритмы генерации для игр: Road Rash 2, Metal gear, Prince of Persia, Bucky O'Hare, Ferrari Grand Prix Challenge.
                    +2
                    Когда-то в детстве полностью отреверсил сохранения MetalGear, тетрадка была на вес золота, первая игра, которую разобрал. А потом и кучу других игр так разобрал, самое сложно было начать и понять как была построена защита, но в основном чёт только CRC и попадались.
                      +2
                      Есть ли в планах раздербанить генерацию паролей для ru.wikipedia.org/wiki/The_Guardian_Legend?
                        +2
                        Как раз в ней копаюсь. Японские пароли — это сила!
                          0
                          Есть локализованная английская версия, почему бы в ней не покопаться?
                            0
                            Я японский изучаю, так что выбор очевиден.
                              0
                              В любом случае, там есть над чем ломать голову. Я сам пытался выявить закономерности, но быстро бросил, когда при каждом заходе в комнату с паролем мне генерировался новый (просто зашёл, вышел и снова зашёл — ничего не изменилось в характеристиках, очках). После Ваших статей я понимаю — там наверняка усложнённая защита в виде примешивания случайных чисел, похлеще, чем в Принце Персии.
                                0
                                Похоже на рандом. Я с такой штукенцией сталкивался в Castlevania II Simon's Quest и в серии игр от Nekketsu. Очень сильно усложняет выявление закономерности.
                                  0
                                  Время нахождения в игре
                                  0
                                  Из Интернета узнал, что в игре используются 8 бит для операции XOR. Из-за этого, один и тот же пароль можно записать по разному. 2 в 8 степени = 256. Не хило. Большой рандом, ничего тут не скажешь.
                          0

                          Тоже в свое время пытался разобраться, как генерить пароли к RRR. Но не осилил по малолетству.


                          Очень интересная схема паролей в ecco the dolphin на сеге. Если взять сначала нечетные буквы, а потом четные, то часто получается рабочий пароль от другого уровня. Но рабочего генератора паролей, насколько я знаю, нет.

                            0
                            Есть рабочий генератор. Выше roman_pro скинул ссылку на страницу с генераторами.
                            0
                            Очень интересная публикация. Никогда не понимала, как могут «картинки» сохранять информацию. А вы случайно не пробовали генерировать пароли на Castlevania III Dracula's Curse и на Castlevania: Bloodlines? Там тоже схожая система паролей.
                              0
                              Увы и ах. Пытался, но всё безуспешно.
                              P.S. Я очень рад, что Вам понравилась моя статья.
                                +1
                                На Castlevania: Bloodlines для Sega есть рабочий генератор
                                  0
                                  Большое спасибо.)
                                0
                                Небольшая неточность в описании формата пароля для Super Castlevania IV — «эти биты сохраняют данные игровые параметры… имя игрока из 8 символов» — в 16 битах (N и C т.е. совмещенных с контрольной суммой) нельзя сохранить значения 8 символов по 36 вариантов каждого. Тут нужно как минимум 42 бита, если без сжатия. Таким образом получается, что имя вводится в игре отдельно и используется для проверки пароля, но не хранится в нём. Верно?
                                  0
                                  Имя хранится как сумма символов. К примеру, имя из буквы «M» и букв «AB» будут иметь одинаковый пароль, так как суммы символов равны. Если бы игра запоминала каждую букву, тогда бы понадобилась много битов, но в пароль записывается лишь сумма значение. Получается, если я создам имя «Nikname» и потом хоть как буду менять порядок букв в имени, пароль не изменится, так как сумма значений не меняется.
                                  Игра хранит 36*8=288 значений.
                                  P.S. Надеюсь я смог донести до Вас свою мысль.
                                    0
                                    Итого: имя НЕ хранится в пароле, а лишь используется для частичной валидации пароля. О чём и был мой вопрос, на который вы напрямую так и не ответили. Но всё равно спасибо.
                                  0
                                  Спасибо огромное статья отличная.
                                    0
                                    Благодарю. Рад, что не зря делал.

                                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                  Самое читаемое