Шифрование (GTA 4) — различия между версиями

Материал из GTAModding.ru
Перейти к: навигация, поиск
(Новая: ==Алгоритмы шифрования== === AES === Алгоритм шифрования, использованный для RPF, IMG и SCO файлов, имеет ...)

Версия 14:59, 4 марта 2009

Содержание

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

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)


Ссылки