![]() |
Добро пожаловать, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
-=CHE@TER=- |
![]()
Сообщение
#1
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
На форуме Extractor.ru товарищ Axsis утверждал, что файлы там не запакованы, однако, судя по тому, что в Интернете нигде нет распаковщика и народ жалуется, что никто не может достать оттуда музыку - следовательно не всё так просто.
Скачал демку: _ttp://www.ag.ru/games/soldier-elite-zero-hour/demos/14368 Увы, отдебажить игру не могу, т.к. она падает до того места, где расшифровываются файлы - при инициализации графики (чего-то у меня в видеокарте нехватает, поэтому получаю ошибку чтения памяти по адресу 0x0000000c). Что успел отдебажить, так это открытие файлов. Кстати, кто тоже будет ковырять демку - там после первого запуска появится файл в каталоге /bin/, где можно поменять настройки и запустить игру в окне, чтобы отлаживаться не мешала. Так вот, всё что я смог узнать: 1) При открытии файла игра считывает 20 последних байт с конца: DWORD sign; // 0x20031031 DWORD vers; // 0x00000004 DWORD off1; DWORD off2; DWORD unkn; а) Первые два поля игра проверяет именно на эти значения - первое это сигнатура, второе - версия. б) offs1 < offs2, в файле textures.zap разница между ними 32 байта и оба смещения указывают примерно на конец файла (они оба проверяются, правда не понял с каким значением - с размером файла?). в) unkn - неизвестное поле, но небольшое. В том же textures.zap оно было равно 0xDB (но это точно не количество файлов - файлов там меньше было - штук 10). 2) Дальше игра, убедившись что файл верный, делает FileMapping() + MapView() всего файла, отчего ставить бряки на ReadFile() становится бессмысленным. (*улыбается*) 3) Интересен алгоритм определения архива свой/чужой - там также проверяется, а не .ZIP ли это архив. И, если .ZIP, то обрабатывается другим куском кода уже как .ZIP. В целом структура .ZAP похожа на .ZIP из чего делаю вывод, что: ZAP = ZIP Aurora Package Напомню, структура .ZIP выглядит примерно так: PK-заголовок|Файл-1|PK-заголовок|Файл-2|PK-заголовок|Файл-3|...|PK-заголовок|Файл-N А далее снова идут PK-заголовоки, но уже без файлов ("Файл-#" - это тело сжатого файла). Так вот, такое ощущение, что в .ZAP оставили именно этот хвост в конце с заголовками, а начало архива зашифровано. Причём ключ либо записан в самом архиве, либо игра генерит его как-то по другому (по имени, например), потому что все .ZAP архивы начинаются по разному. Какое шифрование - стандартное для .ZIP или своё - не знаю. Затрудняет это всё к тому же то, что файлы, видимо, сжаты, а уже потом зашифрованы. В упомянутом файле textures.zap в начале должен был идти .TGA файл - так вот, количество одинаковых полей по три байта (24 BPP видимо) в начале впечатляет. Однако, я перепробовал все XOR от 0 до 255, также rol и даже инверсию битов в байте слева на право - ничего хорошего так и не вышло. Кстати, в одном файле там вообще есть поле байт, эдак, под 200, если не больше, просто одинакового байта. Возможно, шифрование как-то меняет ключ или от чего-нибудь зависит (кстати, шифровать на предыдущий байт, как было в Runaway 2, я тоже пробовал). В файле с музыкой я нашёл две OggS сигнатуры незашированные. Но это два жалких фрейма, а не целые .OGG файлы. 4) Для тех, кто заинтересуется по адресу .692DE0 идёт чтение архива описанное в 1). Кто-нибудь желает помочь? |
Siberian GRemlin |
![]()
Сообщение
#2
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 537 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
Думаю, полная версия с последним обновлением вываливаться не должна.
|
Axsis |
![]()
Сообщение
#3
|
Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 121 Регистрация: 6-February 08 Пользователь №: 374 Спасибо сказали: 149 раз(а) ![]() |
Ох, давно это было, почти 5 лет прошло...
Я уже и не помню что видел эту игру. Игра, как я понимаю, в качестве ресурсов поддерживает и zip, правильно? Тогда, возможно, пираты после "локализации" не заморачивались с родным форматом и запихали всё в zip. И ко мне в тот раз попала такая вот пиратка. Это так, лишь предположения... Как бы там ни было в прошлый раз, сейчас глянул демку с ag.ru Трудно искать чёрную кошку в тёмной комнате, особенно, если её там нет... ![]() Это я про шифрование. Его там нет. Обычный deflate, просто без 2-х байт заголовка, STUNS справляется на ура. ДОБАВЛЕНО: Таблица файлов довольно мудрёная, но структуру уже почти полностью разобрал. Если кто-то соберётся писать распаковщик могу подсказать по формату. ДОБАВЛЕНО2: Гугл по запросу "zap unpacker" выдаёт гору ссылок на распаковщик для Infernal, в котором, как оказалось, тот же самый zap. (по крайней мере из демки Aurora Watching всё распаковал). Вроде как страничка автора, ложка дёгтя - он требует горячо любимый .net framework ![]() Спасибо сказали:
|
-=CHE@TER=- |
![]()
Сообщение
#4
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Думаю, полная версия с последним обновлением вываливаться не должна. А с демо можно как-нибудь обойтись?.. А то качать полную версию... уф.Игра, как я понимаю, в качестве ресурсов поддерживает и zip, правильно? Тогда, возможно, пираты после "локализации" не заморачивались с родным форматом и запихали всё в zip. И ко мне в тот раз попала такая вот пиратка. Это так, лишь предположения... Кстати, да, мысль.Как бы там ни было в прошлый раз, сейчас глянул демку с ag.ru А я там демки не нашёл - поэтому ссылку и привёл... добавили уже что-ли?..Трудно искать чёрную кошку в тёмной комнате, особенно, если её там нет... У меня разрыв шаблона, честно говоря. Просто на форуме Extractor.ru есть ссылка на MegaUpload, в которой выложен какой-то .OGG файл. Так вот я на него STUNS натравливал и ничего не получилось извлечь. Кстати, я так понял, что тот .OGG файл это извлечённый при помощи Watto'вского MultiExtractor или как он там - т.е., по идее, файл должен был бы быть нормальный...![]() Это я про шифрование. Его там нет. Обычный deflate, просто без 2-х байт заголовка, STUNS справляется на ура. Поэтому я вариант со STUNS даже не проверял... Спасибо, я тогда ещё раз проверю, может всё гораздо проще. Так стоп. У меня двойной разрыв шаблона - только что проверил STUNS на том файле и он РАСПАКОВАЛ! Походу в конце 2005 года я ещё с распаковкой zlib не так активно работал, поэтому STUNS видимо даже не пробовал. Ох, ну и дела... ДОБАВЛЕНО: Таблица файлов довольно мудрёная, но структуру уже почти полностью разобрал. Если кто-то соберётся писать распаковщик могу подсказать по формату. Давай! Был бы признателен - меньше времени бы потратил. В больший файлах она, зрительно, как-то делится на несколько. Зачем так сделали я не понял.ДОБАВЛЕНО2: Гугл по запросу "zap unpacker" выдаёт гору ссылок на распаковщик для Infernal, в котором, как оказалось, тот же самый zap. (по крайней мере из демки Aurora Watching всё распаковал). Это не наш метод. © (*улыбается*)Вроде как страничка автора, ложка дёгтя - он требует горячо любимый .net framework ![]() Кстати, что-то я протупил - я именно по названию игры искал и ничего поэтому не нашёл путного. |
Siberian GRemlin |
![]()
Сообщение
#5
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 537 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
Возможно, не к месту, но я тут вспомнил про архивы MDK2. Там тоже обычный ZIP и файлы пожаты были тоже deflate. Но к тому времени когда я их пытался распаковать, ни один архиватор с ним не справился, кроме фирменного от PKWare.
Спасибо сказали:
|
-=CHE@TER=- |
![]()
Сообщение
#6
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Распаковал программу при помощи .NET Reflector 7.5.2.1
CODE private void button1_Click(object sender, EventArgs e) { if (this.OpenZAP()) { byte[] buffer = new byte[4]; this.m_zap.Position = this.m_zap.Length - 8L; this.m_zap.Read(buffer, 0, 4); int treeOffset = BitConverter.ToInt32(buffer, 0); this.m_zap.Position = this.m_zap.Length - 12L; this.m_zap.Read(buffer, 0, 4); this.sizeOfPackedStream = BitConverter.ToInt32(buffer, 0); this.treeView1.Nodes.Add(this.m_zap.Name); this.getDirFiles(treeOffset, this.treeView1.Nodes[this.treeView1.Nodes.Count - 1].Nodes); } } private void getDirFiles(int treeOffset, TreeNodeCollection currentNode) { byte[] buffer = new byte[4]; this.m_zap.Position = treeOffset; this.m_zap.Read(buffer, 0, 2); short num = BitConverter.ToInt16(buffer, 0); this.m_zap.Read(buffer, 0, 2); short num2 = BitConverter.ToInt16(buffer, 0); this.m_zap.Read(buffer, 0, 4); int num3 = BitConverter.ToInt32(buffer, 0); for (int i = 0; i < num2; i++) { this.m_zap.Position = num3 + (i * 4); this.m_zap.Read(buffer, 0, 4); int num5 = BitConverter.ToInt32(buffer, 0); this.m_zap.Position = num5 + num3; FAS fas = new FAS(); buffer[0] = 0; buffer[1] = 0; buffer[2] = 0; buffer[3] = 0; this.m_zap.Read(buffer, 0, 1); fas.nameLenght = BitConverter.ToInt32(buffer, 0); byte[] buffer2 = new byte[0x100]; this.m_zap.Read(buffer2, 0, fas.nameLenght); fas.filename = Encoding.ASCII.GetString(buffer2, 0, fas.nameLenght); this.m_zap.Read(buffer, 0, 4); fas.offsetInZap = BitConverter.ToInt32(buffer, 0); this.m_zap.Read(buffer, 0, 4); fas.unpackedSize = BitConverter.ToInt32(buffer, 0); this.m_zap.Read(buffer, 0, 4); fas.packedSize = BitConverter.ToInt32(buffer, 0); this.m_zap.Read(buffer, 0, 4); fas.unk1 = BitConverter.ToInt32(buffer, 0); this.m_zap.Read(buffer, 0, 4); fas.unk2 = BitConverter.ToInt32(buffer, 0); this.m_zap.Read(buffer, 0, 4); fas.unk3 = BitConverter.ToInt32(buffer, 0); TreeNode node = new TreeNode(fas.filename) { ImageIndex = 1, SelectedImageIndex = 1 }; currentNode.Add(node); fas.NodePath = node.FullPath.Substring(this.m_zap.Name.Length + 1); this.fasArray.Add(fas); } int num6 = treeOffset + 8; for (int j = 0; j < num; j++) { this.m_zap.Position = num6 + (j * 4); this.m_zap.Read(buffer, 0, 4); int num8 = BitConverter.ToInt32(buffer, 0); this.m_zap.Position = num8 + num6; DAS das = new DAS(); buffer = new byte[4]; this.m_zap.Read(buffer, 0, 1); das.dirNameLen = BitConverter.ToInt32(buffer, 0); byte[] buffer3 = new byte[0x100]; this.m_zap.Read(buffer3, 0, das.dirNameLen); das.dirName = Encoding.ASCII.GetString(buffer3, 0, das.dirNameLen); this.m_zap.Read(buffer, 0, 4); das.offsetToTree = BitConverter.ToInt32(buffer, 0); TreeNode node2 = new TreeNode(das.dirName) { ImageIndex = 0, SelectedImageIndex = 0, Name = das.dirName, Text = das.dirName }; currentNode.Add(node2); this.getDirFiles(das.offsetToTree, node2.Nodes); } } zlib распаковывается, если packedSize != UnpackedSize. |
-=CHE@TER=- |
![]()
Сообщение
#7
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Разобрал формат с нуля и написал распаковщик, при следующем обновлении добавлю на сайт.
Увы, в .ZIP сконвертировать не получится, потому что там формат сильно отличается (один способ хранения имён файлов и каталогов чего стоит - наркомания сплошная). А в остальном, действительно, deflate без заморочек. |
![]() ![]() |
Упрощённая версия | Сейчас: 10th September 2024 - 03:42 |