![]() |
Добро пожаловать, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
-=CHE@TER=- |
![]()
Сообщение
#1
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Переношу все междусобойчики из ЛС сюда. У меня уже места для писем нет, запарился себе размер яшика увеличивать, да и неудобно в ЛС.
Товарищ 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'а: показать Спасибо сказали:
|
Siberian GRemlin |
![]()
Сообщение
#2
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 537 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
При несовпадении контрольной суммы игра не выдаёт сообщений, а просто игнорирует этот файл, т.е. при перепаковке архива со звуками игра становится немой.
Спасибо сказали:
|
-=CHE@TER=- |
![]()
Сообщение
#3
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Я подозревал, что что-то такое примерно и происходит.
Хм, как же тогда к вычислению суммы-то подобраться... |
Siberian GRemlin |
![]()
Сообщение
#4
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 537 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
Один человек поделился алгоритмом
CODE Byte stream divided into blocks (3 dwords == 12 bytes): [ x x x x x x x x x x x x ] ... [ x x x x x 0 0 0 0 0 0 0 ] \ / \ / \ / | | 1 2 3 | | full block last block filled with trailing zeros #define f_r(a, b, c, n) (a)-=(b)+(c); (a)^=(b)>>(n) #define f_l(a, b, c, n) (a)-=(b)+(c); (a)^=(b)<<(n) #define f_x(a, b, c, n1, n2, n3) f_r(a,b,c,n1); \ f_l(c,a,b,n2); \ f_r(b,c,a,n3) Инициализация { a=b=0x9E3779B9; c=0; } Каждый полный блок { a+=p[0]; b+=p[1]; c+=p[2]; f_x(a, c, b, 13, 8, 13); f_x(a, c, b, 12, 16, 5); f_x(a, c, b, 3, 10, 15); } Последний блок [0..11] { memcpy(t, p, n); // rep movsd / rep movsb a+=t[0]; b+=t[1]; c+=(t[2]<<8) + k; f_x(a, c, b, 13, 8, 13); f_x(a, c, b, 12, 16, 5); f_x(a, c, b, 3, 10, 15); // ! c - our karma ! } DWORD a, b, c; // just variables DWORD n; // amount of bytes in the last block DWORD k; // total amount of bytes in our stream DWORD *p; // pointer to a block of 3 dwords DWORD t[3] = {0,0,0}; // temporary array on stack Спасибо сказали:
|
![]() ![]() |
Упрощённая версия | Сейчас: 8th September 2024 - 11:32 |