Генерирование паролей на Super Castlevania IV и Rock n' Roll Racing
Недавно я написал пост про генерацию паролей на первый и второй Road Rash. В комментариях к статья меня попросили разъяснить, а как устроена система паролей в игре Rock n' Roll Racing. Про это я и хотел бы с вами поговорить. Но начать хотелось бы с игры Super Castlevania IV. Ну что ж, приступим.
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)
Хочу обратить Ваше внимание на то, что два старших бита из одной контрольной суммы переходят в следующую контрольную сумму.
Кодирование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
Эту игру я «взламывал» давно и тогда не пользовался методом битового разбора. Поэтому подход к этой игре будет немного другой.Теория
Пароль состоит из 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 timezone1 июля 2016 в 12:43
0↑
↓
А в Metal Gear на NES, помнится, было посложнее. Жаль в далёкие 90-е не было интернетов, тем не менее, понять, что последний символ является контрольной суммой, удалось даже не зная самого понятия «контрольная сумма» :)