Шифрование (GTA 4)
Материал из GTAModding.ru
Версия от 14:59, 4 марта 2009; Dageron (обсуждение | вклад)
Содержание |
Алгоритмы шифрования
AES
Алгоритм шифрования, использованный для RPF, IMG и SCO файлов, имеет название Advanced Encryption Standard (AES) и следующую характеристику:
- Размер блока: 128 бит (16 байт)
- Размер ключа: 256 бит (32 байта)
- Режим: electronic code book (ECB)
- Повторяется: 16 раз
Это значит что вся зашифрованная информация может быть разбита на блоки по 16 байт и расшифрована отдельно. Расшифровка происходит с использованием 128 битного ключа 16 раз на каждом блоке данных. Если последний блок меньше 16 байт, он остается не зашифрованным.
Ключ
256 - битный ключ, обязательный для шифрования может быть получен из .exe
файла со следующих оффсетов:
Game Version | Offset |
---|---|
1.0 US | 0xA94204 |
1.0.1 US | 0xB607C4 |
1.0.2 US | 0xB56BC4 |
1.0.0.1 RUS | 0xB5B65C |
1.0.1.1 RUS | 0xB569F4 |
Xbox360 | 0xA80F40 |
Ключ одинаков для всех игровых версий включая Xbox360 (для этого следует извлечь gtaiv_360.exe
из default.xex
). Вы можете использовать SHA1 хеш для проверки правильности ключа:
DE A3 75 EF 1E 6E F2 22 3A 12 21 C2 C5 75 C4 7B F1 7E FA 5E
Примечание: Это не ключ шифрования!
Игра может читать как шифрованные, так и не шифрованные архивы. Рекомендуется оставлять измененные игровые архивы не шифрованными.
Примеры
Программы для расшифровки данных GTA IV могут выглядеть так:
С++:
AES_set_decrypt_key(key, 256, context); for (int i = 0; i < (int) (data_size/16); i++) { void *p = (void *) (data_offset + i*16); // the pointer to the current block for (int j = 1; j <= 16; j++) // 16 (pointless) repetitions AES_decrypt_block(p, p, context); }
Delphi (дополнительно нужен AesLib.pas):
unit RockstarCrypt; interface const CKeyLength = 32; type PAesKey = ^TAesKey; TAesKey = array[0..CKeyLength-1] of byte; procedure RockstarDecrypt(Data: Pointer; Size: cardinal); implementation uses AesLib; procedure RockstarDecrypt(Data: Pointer; Size: cardinal); const CAesRounds = 16; // because it's 16x more secure!!1! CAesKey: array[0..CKeyLength-1] of byte = ( $1A, $B5, ... // put the full key here or load it from the exe ); var AesCtx: TAesContext; i, j: Cardinal; p: Pointer; begin aes_set_decrypt_key(@CAesKey[0], CKeyLength, AesCtx); for i := 0 to Size div 16 - 1 do begin Cardinal(p) := Cardinal(Data) + i*16; for j := 1 to CAesRounds do aes_decrypt_block(p^, p^, AesCtx); end; end; end.
См.так же: Расшифровка в SparkIV (C#, GPL)
Ссылки
- AES Encryption на Википедии.