Алгоритм разгадан верно, большое спасибо.
Вот что удалось выяснить:
-Оказывается используется еще 2 ключа кроме "120", они были подобраны по представленному примеру, так же известно что данный алгоритм используется еще в 3х частях этой игры(и возможно во всех остальных), была написана процедура поиска ключа(нужно знать хотя бы одно слово в шифрованном и расшифрованном виде).
-Была написана процедура расшифровки.
-Выяснено за что отвечает левая системная часть строки. Пример строки расшифрованной вместе с левой частью: 160-3 ->160 Кто ты? Что с тобой случилось? Может расскажешь, что все это значит?
где 160-3 Номер сцены-номер диалога, ->160 к какой сцене ведет диалог(если числа одинаковые значит выбор варианта не верный и игрок не продвигается дальше).
-Некоторые строки разбиты на 2 части, каждая вторая часть начинается на * то есть если во время чтения и расшифровки файла обнаруживается что строка начинается на * то значит ее надо склеить с предыдущей.
Код расшифровки:
Код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | function Encrypt_(s: string ; EncodeTable: array of Integer ): string ;
var
i,KeyL: Integer ;
begin
Result:= '' ;
KeyL:= 0 ;
for i:= 1 to Length(s) do
begin
if KeyL> 2 then KeyL:= 0 ;
Result:=Result+ Char (Ord(s[i])+EncodeTable[KeyL]);
Inc(KeyL);
end ;
end ;
function Encrypt(s: string ): string ;
const Key1: array [ 0..2 ] of Integer =( 1 , 2 , 0 );
Key2: array [ 0..2 ] of Integer =( 2 , 3 , 1 );
Key3: array [ 0..2 ] of Integer =( 3 , 4 , 2 );
begin
Result:=Encrypt_(s,Key1);
end ;
|
Расшифровывается полностью вся строка включая знаки препинания, пробелы, и заглавные буквы.
Код поиска ключа:
Код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | procedure FindKey;
var
i: Integer ;
Key: array of Integer ;
EncS,DecS,Check: string ;
begin
EncS:= 'кдираЮ' ;
DecS:= 'никуда' ;
SetLength(Key, 3 );
Key[ 0 ]:= 0 ;
Key[ 1 ]:= 0 ;
Key[ 2 ]:= 0 ;
for i:= 1 to 1000 do
begin
if (Key[ 0 ]>= 9 ) and (Key[ 1 ]>= 9 ) and (Key[ 2 ]>= 9 ) then Break;
if Key[ 2 ]< 9 then Inc(Key[ 2 ]) else
begin
Key[ 2 ]:= 0 ;
if Key[ 1 ]< 9 then Inc(Key[ 1 ]) else
begin
Key[ 1 ]:= 0 ;
if Key[ 0 ]< 9 then Inc(Key[ 0 ]);
end ;
end ;
Check:=Encrypt_(EncS,Key);
if Check=DecS then
WriteLn ( 'Key Found - ' +IntToStr(Key[ 0 ])+IntToStr(Key[ 1 ])+IntToStr(Key[ 2 ]));
end ;
end ;
|
Еще как я уже говорил видео зашифровано заменой первого байта, оно мне в принципе было не нужно но ради интереса сделал, пусть оно тут полежит, а то как выяснилось в поисковиках относительно этой серии игр, расшифровка видео самый популярный запрос.
Код расшифровки видео:
Код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | procedure EncodeVideo;
var
ms:TMemoryStream;
B: Byte ;
begin
ms:=TMemoryStream . Create;
ms . LoadFromFile( 'Video.cmk' );
ms . Position:= 1 ;
ms . ReadBuffer(B,SizeOf(B));
if B= $7C then
begin
B:= $49 ;
ms . Position:= 1 ;
ms . WriteBuffer(B,SizeOf(B));
ms . SaveToFile( 'Video.avi' );
end ;
ms . Free;
end ;
|
Осталось неразгаданным почему игра зависала при изменении длины шифрованной строки, игра просто валится и все, никаких ошибок не выдает, если запускать в OllyDbg то олька выдает '' is not a valid integer value. Но это в принципе уже не важно, то что мне нужно было изменить я изменил, и все нормально работает. Еще раз всем большое спасибо за помощь!
P.S. Код представленный Alegun, проверен, работает, расшифровывает весь файл целиком, но назад зашифровать не удается, в некоторых строках системная часть не вся, без системной части игра отказывается показывать диалог, не зависает, просто на его месте пусто.