IPB

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

> Aurora Watching: Gorky Zero [.ZAP]
-=CHE@TER=-
Aug 11 2010, 13:32
Сообщение #1


Walter Sullivan
***

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



На форуме 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).

Кто-нибудь желает помочь?
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
 
Reply to this topicStart new topic
Ответов
-=CHE@TER=-
Mar 13 2012, 17:13
Сообщение #2


Walter Sullivan
***

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



Распаковал программу при помощи .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.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post

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


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

 



Упрощённая версия Сейчас: 30th May 2024 - 04:11