Генерирование паролей на 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. Удачи, спасибо за прочтение.

Комментарии (8)

  • 1 июля 2016 в 11:43

    0

    Всё это безумно здорово, но было бы ещё круче, будь описание того, как были вычислены данные вещи.
    • 1 июля 2016 в 12:07

      0

      В тех играх, где есть свободный сейв — меня про одному и собирая пороли чаще всего.
      • 1 июля 2016 в 12:47

        0

        меня про одному и собирая пороли

        Интересная история, но не для этого сайта.
    • 1 июля 2016 в 13:16

      0

      Я мог бы и описать, как всё это получено, но тогда бы статья была бы слишком большой. Но если вкратце, я собирал пароли и методом анализа находил насколько и как изменяются позиции при определенных значениях.
      • 1 июля 2016 в 13:32

        0

        Так может тогда отдельную статью-туториал написать по методам анализа и вычислений?
        Я так понимаю, даже в случае разного способа кодирования, изначальный подход к вычислениям одинаковый?
        • 1 июля 2016 в 13:47

          0

          Можно и написать, но я не уверен, что будут люди которым это нужно. Я когда эту публикацию писал всё задумывался данным вопросом: «Кому оно надо?»
  • 1 июля 2016 в 12:16

    +2

    Tarquim scores the first place knock-out
    Jake finishes second
    Глюк takes a weak third
    Olaf is in another timezone
  • 1 июля 2016 в 12:43

    0

    А в Metal Gear на NES, помнится, было посложнее. Жаль в далёкие 90-е не было интернетов, тем не менее, понять, что последний символ является контрольной суммой, удалось даже не зная самого понятия «контрольная сумма» :)

© Habrahabr.ru