OVH Cloud OVH Cloud

decompresser avec zlib en memoire

3 réponses
Avatar
Laurent.Debarre
Bonjour,

J'ai besoin de decompresser en memoire des donnees renvoyées par un serveur
http
compressées avec gzip.
Je me bats depuis 3 jours avec zlib sans succès.
- La commande de haut niveau "uncompress" ne marche pas.
- La séquence inflateInit / inflate en un bloc ne marche pas0
- La séquence inflateInit / inflate en un plusieurs blocs ne marche pas0
- remplacer inflateInit par inflateInit2 avec une valeur négative à cause de
l'absence de header ne marche pas non plus
--> dans tout les cas, j'ai l'erreur -3 (Z_DATA_ERROR)
- J'ai meme regardé le source de FireFox, mais c'est assez difficile
d'isoler la partie qui m'interesse.
La technique d'ajouter un "dummy header" de 2 octets n'a pas marchée non
plus.

Donc, si quelqu'un a les 20 ou 30 lignes de codes qui marche sous Windows
avec une decompression zlib en memoire sans header de type http, je suis
PRENEUR !!

Merci de votre aide.

3 réponses

Avatar
dark poulpo
http://www.vbfrance.com/code.aspx?id$208

--
-----
http://dark.freezee.org/
http://www.dark-team.cjb.net/
Avatar
Laurent.Debarre
Merci, mais je cherche une solution "tout en mémoire", sans passer par un
fichier temporaire.

Laurent
Avatar
Gilles Vollant
quelle version de la zLib ?
pour être à jour:
http://www.zlib.net/

http://www.winimage.com/zLibDll


j'ai trouvé cela dans mes archives (vieux code parfois, mais vivant)

ce code lit une resource Windows, et si c'est un fichier .gz qui a été mis
en ressource, il est décompressé en mémoire


DWORD ComputeBufferCRC(DWORD dwCRC, LPCVOID pvBuffer, DWORD cbBuffer)

{

return crc32(dwCRC ^(0xffffffff),(Bytef*)pvBuffer,cbBuffer)^(0xffffffff);

}




BOOL UncompressGZMem(const BYTE* lpRes,DWORD dwSizeRes,LPSTR & lpBuf,DWORD &
dwSizeExe)
{
BOOL fRetúLSE;
lpBuf = NULL;
dwSizeExe=0;

DWORD dwCrcRes = ComputeBufferCRC(0xFFFFFFFFL,(void*)lpRes,dwSizeRes ) ^
0xFFFFFFFFL;


if (!(((*lpRes)=='x1f') && (*(lpRes+1)==((BYTE)'x8b')) &&
(*(lpRes+2)=='x08')))
{ // No GZ header
lpBuf = (LPSTR)GlobalAllocPtr(GHND,dwSizeRes+0x10);
fRet = (lpBuf != NULL);
if (fRet)
{
dwSizeExe = dwSizeRes;
memcpy(lpBuf,lpRes,dwSizeExe);
}
}
else
{ // here GZ file
BYTE flag = *(lpRes+3);
const BYTE* lpBegin = lpRes + 0x0a;
DWORD dwCrcComputed;
DWORD dwUncompressedSize= ((*(lpRes+dwSizeRes-4))) |
((*(lpRes+dwSizeRes-3)) * 0x100) |
((*(lpRes+dwSizeRes-2)) * 0x10000) |
((*(lpRes+dwSizeRes-1)) * 0x1000000);

DWORD dwCRC32= ((*(lpRes+dwSizeRes-8))) |
((*(lpRes+dwSizeRes-7)) * 0x100) |
((*(lpRes+dwSizeRes-6)) * 0x10000) |
((*(lpRes+dwSizeRes-5)) * 0x1000000);

if ((flag & 0x04) != 0) // FEXTRA
{
WORD wxLen = (*lpBegin) + (0x100 * ((*(lpBegin+1)))) ;
lpBegin += wxLen +2;
}
if ((flag & 0x8) != 0) // ORIG NAME
{
while ((*lpBegin) != '')
lpBegin++;
lpBegin++;
}
if ((flag & 0x10) != 0)
{
while ((*lpBegin) != '')
lpBegin++;
lpBegin++;
}
if ((flag & 0x2) != 0)
{
lpBegin+=2;
}

lpBuf = (LPSTR)GlobalAllocPtr(GHND,dwUncompressedSize+0x20);
dwSizeExe = dwUncompressedSize ;


{
/* We have the GZip file in resource, we uncompress it*/
z_stream c_stream; /* compression stream */
int err;
DWORD dwRestIn = (uInt)((lpRes+dwSizeRes)-lpBegin)-8 ;
_fmemset(&c_stream,0,sizeof(c_stream));
c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
err=inflateInit2(&c_stream,-MAX_WBITS);

c_stream.next_in = (LPBYTE)lpBegin;
c_stream.avail_in = (uInt)dwRestIn + 4;


c_stream.next_out = (LPBYTE)lpBuf;
c_stream.avail_out = (uInt)dwUncompressedSize + 0x10;

err=inflate(&c_stream, Z_FINISH);

err=inflateEnd(&c_stream);
}
dwCrcComputed =
ComputeBufferCRC(0xFFFFFFFFL,lpBuf,dwUncompressedSize) ^ 0xFFFFFFFFL;

fRet = dwCrcComputed == dwCRC32;
}

return fRet;
}

// --------------------------------------------------------------------------

BOOL UncompressGZRes(HMODULE hModule, LPCTSTR lpName, LPCTSTR lpType, LPSTR
& lpBuf,DWORD & dwSizeExe)
{
HRSRC hrSrc=NULL;
HGLOBAL hGlob=NULL;
BOOL fResUncompr = FALSE;
LPSTR lpRes = NULL;

hrSrc=FindResource(hModule, lpName, lpType);
if (hrSrc!=NULL)
hGlob=LoadResource(NULL,hrSrc);
lpRes=(LPSTR)LockResource(hGlob);

if (lpRes != NULL)
fResUncompr=UncompressGZMem((LPBYTE)lpRes,SizeofResource(hModule,hrSrc),lpBuf,dwSizeExe);

UnlockResource(hGlob);
FreeResource(hGlob);
return fResUncompr;
}

// --------------------------------------------------------------------------

BOOL FreeGzDecompressedMem(LPSTR lpBuf)
{
GlobalFreePtr(lpBuf);
return TRUE;
}


Gilles Vollant
MVP Visual C++