У меня есть файл pcap с трафиком World of Warcraft, и мне нужно его распаковать. Я знаю, что это сжато Zlib:
http://wiki.xentax.com/index.php/List_Of_Compressed_Games
Поэтому, чтобы найти начало сжатого блока, я написал фрагмент кода, который перебирает необработанные данные, пытается распаковать данные и проверяет, доступны ли какие-либо выходные данные.
Я вызываю функцию inflateInit2 для инициализации zlib с параметрами windowBits 15 (формат zlib) и 30 (формат gzip). Я пытался использовать inflate () с параметрами Z_SYNC_FLUSH и Z_FULL_FLUSH.
Но это не дает мне выхода.
Каждый пакет заканчивается на 00 00 00 ff ff. Но руководство zlib говорит, что оно должно быть 00 00 ff ff.
Так как же извлечь данные из потока WoW?
Мой код:
void tryZlib(unsigned __int8 *StPt, __int64 size, Deflate *zlib)
{
z_stream_s * stream = new z_stream_s;
SecureZeroMemory(stream, sizeof(z_stream_s));
bool isInit = false;
while (size > 0)
{
BYTE *out_buf;
bool isPacketLost = false;
unsigned __int32 total_out = 0;
Zlib::ZlibData ddata(StPt, size, *stream, isInit, isPacketLost);
auto IsOk = zlib->Decoder(ddata, out_buf, total_out);
zlib->Reset(*stream, isInit);
--size;
++StPt;
}
}
Надуть обертку функции:
bool Zlib::Decoder(const DeflateData & ddata, BYTE *& out_data, unsigned __int32 & size)
{
if (IsDllLoaded == false || ddata.PDU == nullptr || ddata.PDU_size == 0)
return false;
z_stream_s & strm = ddata.stream;
if (!ddata.isInitialized)
Init(ddata);
strm.total_out = 0;
strm.avail_in = ddata.PDU_size;
strm.next_in = ddata.PDU;
strm.avail_out = OUT_BUFFER_SIZE;
strm.next_out = out_buffer;
__int32 ret = 0;
bool isWasSync = false;
ret = ZDecompressor(&strm, Z_SYNC_FLUSH);
size = strm.total_out;
if ((ret = 0) || (size > 10))
printf("Found!!");
out_data = out_buffer;
return true;
}
Вам нужно windowBits
параметр, который будет -15
(отрицательный), чтобы запросить сырой дефлят.
Сохраненный блок, на который вы ссылаетесь, равен трем нулям биты, с последующим заполнением оставшейся части этого байта достаточным количеством нулевых битов, чтобы добраться до границы байта, за которой следуют четыре байта 00 00 ff ff
, Таким образом, в зависимости от предыдущих битов в потоке, байт перед 00 00 ff ff
может не быть 00
,
Других решений пока нет …