![]() |
Добро пожаловать, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
Siberian GRemlin |
![]() ![]()
Сообщение
#1
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 537 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
Заголовок для архива (.~h). Тупоконечная запись значений.
По следующим смещениям хранятся. $0C - смещение на таблицу. (dword) $14 - смещение на имена файлов. (dword) Таблица содержит. dword - длина названия (архива?). string - название, включая ноль. переменное выравнивание нулями, чтобы следующее значение начиналось со смещения кратного четырём. dword - кол-во файлов в архиве. dword - неизвестно. dword - неизвестно. Затем идёт массив с записями по 16 байт на каждый файл. Собственно загвоздка здесь, где предположительно хранятся размеры файла в сжатом и несжатом виде и смещение. Значения какие-то оторванные от действительности. Дальше идут имена файлов. Сами файлы хранятся в архиве (.~p). Данные либо в чистом виде, либо сжаты Zlib. Идут с выравниванием кратным $800. Грубым образом я конечно смог извлечь данные, но хотелось бы полностью разобрать формат. Скачать образец файлов. (<1) Скачать игру. (~500) |
-=CHE@TER=- |
![]()
Сообщение
#2
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Смотрел только маленький архив.
Смещение $20 - судя по всему количество файлов в архиве ($DF). Заголовок таблицы: DWORD - SLEN длинна имени структуры CHAR[SLEN] - строчка с именем (BLOB) - выравнивается до ближайшей кратной 4 границы DWORD - неизвестно (?) DWORD - точно не количество файлов, потому что файлов $DF, а тут $BD DWORD - неизвестно (не используется, походу filler $CC) Далее идёт таблица. На глаз структура таблицы примерно следующая: DWORD - USIZE - (USIZE >> 9) = размер распакованного файла DWORD - PSIZE - (PSIZE >> 1) = размер упакованного файла DWORD - FOFFS - (FOFFS >> 3) - смещение файла в архиве DWORD - NOFFS - (NOFFS >> 11) = смещение до начала имени файла, относительно начала секции строк: 0, 30, 58, ... >> - битовый сдвиг вправо (shr) Т.е. читаем, к примеру, поле USIZE, затем, чтобы получить размер распакованного файла, сдвигаем это поле вправо на 9 бит. Если USIZE = PSIZE (!!!без сдвигов - как было в файле!!!) - файл не упакован и любое из этих полей сдвинутое вправо на 9 даст размер файла. Поля имеют какие-то байты FOFFS (всегда 1), NOFFS (2 или 4), которые при сдвиге отбрасываются, но за что они отвечают - я не знаю. Точно не за сжатие. Спасибо сказали:
|
Siberian GRemlin |
![]()
Сообщение
#3
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 537 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
Спасибо большое! Оказалось, этот же формат используется в Brutal Legend. BMS - работает далеко не на всех архивах, однако даёт пищу к размышлению.
Потестировал на разных архивах распаковщик и выяснил. 1. Количество имён зачастую меньше количества файлов в архиве. ![]() 2. У PSIZE иногда придётся отнимать $400000. Т.о. скорее всего, переменные нужно читать вообще побитово, и их гораздо больше чем четыре. Методом научного тыка вряд ли получится определить кол-во и назначение всех переменных. ![]() |
Siberian GRemlin |
![]()
Сообщение
#4
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 537 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
Если кому-то интересно, то вот структура таблицы для «Costume Quest» — читать по битам, их кол-во указано. На компе Zlib, на «Xbox 360» — LZX, и ещё возможно LZMA, вероятно, на «PlayStation 3». И разумеется, без сжатия.
CODE uint64 _unused1 : 1; uint64 deflatedSize :22; uint64 metadataSize :18; uint64 dataSize :23; uint32 assetCategory : 3; uint32 dataOffset :29; uint32 _unused2 : 1; uint32 compressionType: 3; uint32 descIndex : 7; uint32 assetNameIndex :21; Спасибо сказали:
|
![]() ![]() |
Упрощённая версия | Сейчас: 8th September 2024 - 02:03 |