IPB

Добро пожаловать, гость ( Вход | Регистрация )

> Meet The Robinsons [.HOG], Контрольная сумма / хэш
-=CHE@TER=-
Apr 1 2011, 18:50
Сообщение #1


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,355
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



Переношу все междусобойчики из ЛС сюда. У меня уже места для писем нет, запарился себе размер яшика увеличивать, да и неудобно в ЛС.
Товарищ Siberian GRemlin, пожалуйста, в будущем создавай тему, а не пиши мне.
Я всегда смотрю файлы которые кто-либо из нас выкладывает, так что если ты или кто-то другой что-то спросил, а я не ответил, это значит только что я ничего не могу сказать по этому формату. Мне нечего добавить и т.д.
Надеюсь на понимание и что мне никто в будущем не будет писать в ЛС, а создавать отдельную тему...

Но вернёмся к игре. Siberian GRemlin жаждет узнать алгоритм подсчёта контрольной суммы.
Нужно это ему, видимо, для перепаковки архива и создания русификатора.
Далее идёт описание формата (я его немного дополнил, кстати), так что я сразу задам свои вопросы ему:
1) Зачем тебе сдалась эта контрольная сумма? Я поменял её у пары файлов из "Data\say.hog", но игра на это никак не отреагировала. Т.е. никакой ошибки не было.
2) noDVD игры упакован UPX'ом со стёртой сигнатурой, но я его распаковал. Получилось из 8 Мб целых 28. Если кто-нибудь ещё будет смотреть игру - могу выложить его, чтобы не распаковывать. Так вот под отладчиком я нашёл место где читается, к примеру, тот же "Data\say.hog" (он целиком в память засовывается), но проблема в том, что, видимо, из-за криво снятой защиты я не могу поставить бряк на обращение к этой памяти. В частности к ячейке с контрольной суммой. При попытке это сделать Олька говорит что мой бряк инвалид и она поэтому она его убивает. 28 Мб - это не фигушки воробьям показывать и найти там код проверки вручную очень сложно.
Так что вернёмся к вопросу №1: зачем нужна контрольная сумма, если игра её игнорирует? Если не игнорирует, скажи где и что поменять, чтобы игра выбросила сообщение-ошибку. Тогда уже можно будет идти-отлаживать от него вверх и найти место подсчёта контрольной суммы.

Формат .HOG файлов такой:
DWORD - singature/version // сигнатура или версия - игра всегда проверяет, чтобы было равно $20001 (см. код на .5DA88C)
DWORD - TOC offs // смещение до таблицы содержимого (TOC)
DWORD - zero // всегда ноль, вроде бы
DWORD - hash/crc(1) // контрольная сумма для заголовка (???)
DWORD - files count // количество файлов в архиве
DWORD - unknown // неизвестно, какой-то размер похоже, но я не понял что это (???)
DWORD - hash/crc(2) // второе непонятное число (???)

Формат TOC:
DWORD - name // смещение до начала ACSIIZ имени файла - это то, что ты принял за ID
DWORD - offs // смещение до данных файла
DWORD - size // размер файла
DWORD - hash/crc(3) // это самое, что непонятно как считается (???)

Далее идут друг за другом ASCIIZ имена.

С именами, кстати, всё просто - если ты делаешь FileMapping() или прочитал весь файл в память, то не нужно читать по одному байту, пока не 0, можно проще:

PTR_START, FileName: PChar;
...
FileName:=PTR_START; // присваиваем указатель на начало архива
Inc(FileName, TOC[I].name); // сдвигаем его до имени файла
WriteLn(FileName); // получили имя текущего, I-того, файла

Ссылки на игру:
_ttp://ifolder.ru/22688282
_ttp://ifolder.ru/22687944
_ttp://ifolder.ru/22688054
_ttp://ifolder.ru/22687760
_ttp://ifolder.ru/22688384


Код распаковщика за авторством Siberian GRemlin'а:
показать
CODE
Program unpk;
{$APPTYPE CONSOLE}
Uses Windows, SysUtils, Classes;
{
[!] SecuROM Detected - Version 07.31.0011
[CompilerDetect] -> Visual C++ 7.1 (Visual Studio 2003)
}
type
  Tmass = record
    ID, CRC,
    FileOffset,
    FileSize: dword;
    FileName: String;
  end;

Procedure Extract(name:string);
var
  Mstr,OutStr: TFileStream;
  i, Offset{, Unknown}: Integer;
  FilesMass: array of TMass;
//  path,p: string;
  b:byte;
begin
  if FileExists(name) then begin
    Mstr:=TFileStream.Create(name, fmOpenRead);
    Mstr.Position:=$4;
    Mstr.ReadBuffer(Offset, 4); //начало таблицы или размер заголовка
    Mstr.Position:=$10;
    Mstr.ReadBuffer(i, 4); //кол-во файлов
    SetLength(FilesMass,i);

    Mstr.Position:=Offset;

    for i:=0 to Length(FilesMass)-1 do begin
      Mstr.ReadBuffer(FilesMass[i].ID, 4);
      Mstr.ReadBuffer(FilesMass[i].FileOffset, 4);
      Mstr.ReadBuffer(FilesMass[i].FileSize, 4);
      Mstr.ReadBuffer(FilesMass[i].CRC, 4);
    end;
    for i:=0 to Length(FilesMass)-1 do begin
      FilesMass[i].FileName:='';
      Repeat
        Mstr.ReadBuffer(B,1);
        if B<>0 then FilesMass[i].FileName:=FilesMass[i].FileName+chr(B);
      Until B=0;
      WriteLn(FilesMass[i].FileName,' : CRC = ',IntToHex(FilesMass[i].CRC,8));
    end;
    for i:=0 to Length(FilesMass)-1 do begin
      Mstr.Position:= FilesMass[i].FileOffset;
      OutStr:=TFileStream.Create(FilesMass[i].FileName, fmCreate);
      OutStr.CopyFrom(Mstr,FilesMass[i].FileSize);
      OutStr.Free;
    end;
    Mstr.Free;
  end;
  writeln('Completed!');
end;

Begin
  If ParamCount = 1 Then Extract(ParamStr(1));
End.


Спасибо сказали:
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
 
Reply to this topicStart new topic
Ответов

Сообщения в этой теме


Reply to this topicStart new topic
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0 -

 



Упрощённая версия Сейчас: 27th April 2024 - 07:16