|
|
Регистрация | << Правила форума >> | 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, без проверок по алфавиту и иных усложнений. В начале строки скорее всего в каком-то виде закодирован "номер" строки (грубо говоря, где она используется в самой программе) и её длина. jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось 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. |