Шифрование (GTA 4)

Материал из GTAModding.ru
Перейти к: навигация, поиск

Содержание

Алгоритмы шифрования

AES

Алгоритм шифрования, использованный для RPF, IMG и SCO файлов, имеет название Advanced Encryption Standard (AES) и следующую характеристику:

  • Размер блока: 128 бит (16 байт)
  • Размер ключа: 256 бит (32 байта)
  • Режим: electronic code book (ECB)
  • Повторяется: 16 раз

Это значит что вся зашифрованная информация может быть разбита на блоки по 16 байт и расшифрована отдельно. Расшифровка происходит с использованием 128 битного ключа 16 раз на каждом блоке данных. Если последний блок меньше 16 байт, он остается не зашифрованным.

Ключ

256 - битный ключ, обязательный для шифрования может быть получен из .exe файла со следующих оффсетов:

Версия игры Оффсет
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); 
    for (int j = 1; j <= 16; j++)            // Повторяется 16 раз
        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; // 16 секций.
  CAesKey: array[0..CKeyLength-1] of byte = (
    $1A, $B5, ... // Поместите сюда полный ключ или загрузите из  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)


Ссылки