ZLIB распаковка
Я написал небольшое приложение, которое должно распаковывать данные, закодированные в формате gzip/deflate.
Для этого я использую библиотеку ZLIB, используя функцию распаковки.
Проблема в том, что функция не работает! Другими словами, данные не являются несжатыми!
Я выкладываю здесь код:
int (*decompress)(PBYTE,PULONG,PBYTE,ULONG);
void DecodeData(PBYTE data,ULONG dataSize){
LoadLibrary("C:\\zlib1.dll");
decompress=(int(*)(PBYTE,PULONG,PBYTE,ULONG))GetProcAddress(
GetModuleHandle("zlib1.dll"),"uncompress");
// Yeah I know the size is hardcoded and it's not right, but it's just a test,
// so nevermind
PBYTE decompressedData=(PBYTE)VirtualAlloc(NULL,300,MEM_COMMIT|MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
ULONG maxSize=250;
decompress(decompressedData,&maxSize,data,dataSize);
MessageBox(0,(char*)decompressedData,0,MB_OK);//MessageBox shows no data, it's blank!
}
GetProcAddress успешно получает указатель на функцию, проблема в том, что функция возвращает NULL(и даже не ошибки, перечисленные в документации zlib)
Заранее спасибо =)
2 ответа
uncompress()
Функция не будет распаковывать данные gzip, и в зависимости от того, что вы подразумеваете под "deflate", она также не может распаковывать это.
Существует три возможных формата, к которым вы обращаетесь, это фактические сжатые данные, возможно, с некоторыми короткими заголовками и трейлерами для идентификации потока и предоставления некоторых проверочных данных в конце. Есть необработанные данные о дефляте, как описано в RFC 1951. Существуют данные с дефлированием в zlib, определенные в RFC 1950. Есть сжатые gzip данные deflate, определенные RFC 1952.
uncompress()
будет распаковывать только zlib-упакованные данные deflate. Он не будет распаковывать данные в формате gzip или необработанные данные.
Вы не предоставили контекст для того, что вы пытаетесь сделать. Однако, когда вы говорите "gzip/deflate", я могу предположить, что по этой комбинации вы ссылаетесь на имена опций кодирования содержимого HTTP. В этом случае из-за неудачного выбора имени кодировка содержимого "deflate" относится к дефлированным данным, заключенным в zlib, а не к необработанным данным. uncompress()
будет распаковывать правильно доставленные HTTP-дефлятированные данные в кодированном виде.
Я говорю "правильно доставлено", потому что это не может быть. Опять же, из-за неудачного выбора имени и неспособности программистов Microsoft фактически прочитать спецификацию HTTP, серверы IIS некорректно доставляли необработанные данные с дефляцией вместо данных, упакованных в zlib, когда клиент принимал кодирование контента с дефляцией. Это привело к тому, что клиенты должны либо попытаться декодировать кодирование дефлятированного содержимого в обоих направлениях и посмотреть, работает ли один из них, либо лучший подход, который заключается в том, чтобы просто не принимать кодирование дефлирования в первую очередь. Если клиент принимает только кодировку содержимого gzip, проблем нет.
Ты можешь использовать inflateInit2()
, inflate()
, а также inflateEnd()
функции zlib для декодирования любого из упомянутых форматов, т.е. gzip-wrapped, zlib-wrapped и raw. Пожалуйста, прочитайте документацию в zlib.h
чтобы увидеть как.
Кстати, uncompress()
Функция возвращает целое число, а не указатель. Поэтому, когда вы говорите, что функция вернулась NULL
вместо того, что предполагалось, я могу только предположить, что интерфейс к этой функции zlib не был определен должным образом.
Почему в вашем GetProcAddress используется 'uncompress', но вы пытаетесь распаковать? Вы получаете адрес процедуры 'uncompress'!!!