![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Всем привет! Нужно поправить в игре некоторый текст. Файл локализации чем то закодирован, если есть люди разбирающиеся в криптографии, помогите пожалуйста расшифровать.
Игра: Рандеву с незнакомкой 4, год выхода: 2002, написана на Delphi. Пример закодированной строки: 040,/ ,<15. Ооибгт-ДЯааиувЮдЯь,э рнлэ* Ятъ-коиппжяслыиусоемлииснл. Она же, раскодированная: Привет. Давай угадаю, я сплю, а ты - мой приятный утренний сон. Также прикреплю весь файл локализации. Интересно что слову привет соответствует Ооибгт, что за цифры до этого, не удалось выяснить. |
|
#2
|
|||
|
|||
|
Сегодня ковырял экзешник в DelphiDecompiler, он использует ComObj и OleServer, при этом в папках игры нет ни одного вордовского документа, возможно эта информация поможет, известно что разработчики данной игры любят для защиты поменять пару байт, например видео у них защищено заменой первого байта на произвольный.
|
|
#3
|
||||
|
||||
|
Ну многие программы не используют документы офиса. В этом нет ничего плохого.
|
|
#4
|
|||
|
|||
|
Это я понимаю, я имел ввиду что может этот как то через OLE загружается, так как в папке кроме этого файла только графика и аудио. Разработчики те еще "шифраторы", я уже сообщил как мощно они зашифровали видео, а этот файл локализации у них вообще в формате bmp, это я на txt сам поменял. Известно что длина строки одинаковая и зашифрованная и расшифрованная. Тут может быть вообще нет шифрования, может кодировка другая, или файл не текстовый а на подобии ворда что то. Третий день уже ковыряюсь, чем только не пытался открыть
|
|
#5
|
|||
|
|||
|
1. ComObj и OleServer совершенно не обязательно связаны с офисом. Они просто относяться к технологии COM. Через нее,в т.ч. используется DirectX. И проигрывание видео тоже через COM можно играть (кодеки).
2. Расширение файла никак не завязано на его содержимое, так что хоть горшком назови. 3. Если длинна строки до шифрования и после одинаковая, то, скорее всего, используется какое-то достаточно простое симетричное шифрование. Что можно попробовать. Если известна какая-то строка в шифрованном и расшифрованном виде, то можно попробовать проверить на простой XOR. Т.е. если поXORить строку с ее же зашифрованной версией, то, по идее, ты получишь пароль. Соответсвенно, этот пароль можно попробовать применить к другой строке и посмотреть, получается ли расшифровка. Однако, т.к. мы не знаем где начало зашифрованного блока, то, возможно, надо будет этот пароль "подвигать" по строке что бы найти правильное положение. |
| Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
Shaft (11.07.2017)
| ||
|
#6
|
|||
|
|||
|
Это вариант, завтра буду пробовать. Первая строка известна и шифрованная и расшифрованная, я пока не уверен но по моему результат шифрования зависит от длины строки. Известно что в первой строке слово Ооибгт это Привет, поиграл я сегодня в эту игру, там целая куча приветов а в шифрованном файле слово Ооибгт встречается только 2 раза, и в обоих случаях длина строки равна 63. Еще известно что если в шифрованном файле длину строки уменьшить или увеличить хотя бы на 1 символ, то игра зависает, а если менять буквы с сохранением длины строки, то неправильно расшифровывает, но не всю строку а только измененные буквы.
|
|
#7
|
|||
|
|||
|
Расшифровать так и не удалось.
Что удалось выяснить: -Результат шифрования зависит от длины строки. -В левой части те цифры которые я ранее писал что неизвестны, судя по всему содержат какую то системную информацию, при их замене игра не зависает но и строку не расшифровывает, в интерфейсе игры на месте строки будет пустое место, даже если их скопировать от другой строки. В общем левая часть подходит только к определенной правой. -Интересно что если в шифрованной строке все символы заменить на 0 то в игре будет выглядеть так "1201201201201201201201201201201201201201201201201 20120120120120" причем любая стока, можно весь файл заменить и все строки в игре будут такие. При этом не важно какой длины строка, вот это совсем не понятно как так. |
|
#8
|
||||
|
||||
|
Цитата:
Цитата:
о плюс 2 по алфавиту равно "р" и плюс 0 по алфавиту равно "и" б плюс 1 по алфавиту равно "в" г плюс 2 по алфавиту равно "е" т плюс 0 по алфавиту равно "т" То есть к первой букве строки прибавляется 1, ко второй - два, к третьей - 0 и далее по кругу. Не буквенные символы (пробелы, знаки препинания) - не знаю, может тоже так "шифруются". На границе алфавита большая "Я" превращается в "а", значит скорее всего там просто str[i] + x, без проверок по алфавиту и иных усложнений. В начале строки скорее всего в каком-то виде закодирован "номер" строки (грубо говоря, где она используется в самой программе) и её длина. Последний раз редактировалось Bargest, 09.07.2017 в 20:19. |
| Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
Shaft (11.07.2017)
| ||
|
#9
|
||||
|
||||
|
Вот релиз G-кодом по предложенному алгоритму, в Мемо1 загружен исходный текстовый файл, в Мемо2 расшифровка
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
i,j,b: integer;
s, s1: string;
begin
Memo2.Clear;
for i := 0 to Memo1.Lines.Count do
begin
s1:= '';
s:= Memo1.Lines[i];
b:= 1;
if (Length(s) > 0) then
begin
if (s[1] = ')') or (s[4] = ',') then
for j := 1 to Length(s) do
begin
s1:= s1 + chr(byte(s[j])+b);
inc(b);
if b > 2 then b:= 0;
end;
case s[4] of
'+':
for j := 3 to Length(s) do
begin
s1:= s1 + chr(byte(s[j])+b);
inc(b);
if b > 3 then b:= 1;
end;
'*':
begin
b:= 2;
for j := 3 to Length(s) do
begin
s1:= s1 + chr(byte(s[j])+b);
inc(b);
if b > 4 then b:= 2;
end;
end;
end;{case}
end;
Memo2.Lines.Add(s1);
end;
end; |
| Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
Shaft (11.07.2017)
| ||
|
#10
|
|||
|
|||
|
Алгоритм разгадан верно, большое спасибо.
Вот что удалось выяснить: -Оказывается используется еще 2 ключа кроме "120", они были подобраны по представленному примеру, так же известно что данный алгоритм используется еще в 3х частях этой игры(и возможно во всех остальных), была написана процедура поиска ключа(нужно знать хотя бы одно слово в шифрованном и расшифрованном виде). -Была написана процедура расшифровки. -Выяснено за что отвечает левая системная часть строки. Пример строки расшифрованной вместе с левой частью: 160-3 ->160 Кто ты? Что с тобой случилось? Может расскажешь, что все это значит? где 160-3 Номер сцены-номер диалога, ->160 к какой сцене ведет диалог(если числа одинаковые значит выбор варианта не верный и игрок не продвигается дальше). -Некоторые строки разбиты на 2 части, каждая вторая часть начинается на * то есть если во время чтения и расшифровки файла обнаруживается что строка начинается на * то значит ее надо склеить с предыдущей. Код расшифровки: Код:
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;Код поиска ключа: Код:
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;Еще как я уже говорил видео зашифровано заменой первого байта, оно мне в принципе было не нужно но ради интереса сделал, пусть оно тут полежит, а то как выяснилось в поисковиках относительно этой серии игр, расшифровка видео самый популярный запрос. Код расшифровки видео: Код:
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, проверен, работает, расшифровывает весь файл целиком, но назад зашифровать не удается, в некоторых строках системная часть не вся, без системной части игра отказывается показывать диалог, не зависает, просто на его месте пусто. Последний раз редактировалось Shaft, 11.07.2017 в 14:24. |
|
#11
|
|||
|
|||
|
Мой код допиленый по примеру Alegun, расшифровывает весь файл целиком вместе с системной частью.
Код:
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:='';
if Length(s)<4 then Exit;
if (s[1] = ')') or (s[4] = ',') then Result:=Encrypt_(s,Key1);
if s[4]='+' then Result:=Encrypt_(s,Key2);
if s[4]='*' then Result:=Encrypt_(s,Key3);
end;
procedure StartDecode;
var
sl:TStringList;
I:Integer;
begin
sl:=TStringList.Create;
sl.LoadFromFile('icon6@.bmp');
for I:=0 to sl.Count-1 do
mmo1.Lines.Add(Encrypt(sl[i]));
sl.Free;
end;P.S. Пробовал Рандеву с незнакомкой 9, тоже работает, судя по всему во всех частях один и тот же ключ и алгоритм. Последний раз редактировалось Shaft, 11.07.2017 в 15:01. |