Всем здрасте. Подскажите пожалуйста АПИ-функции для Content-Encoding: GZIP и DEFLATE. Написал простенькую программку, ставящую хук на WSARecv для iexplore.exe(64-разрядный), с дальнейшим выводом содержимого в EDIT-BOX. Только там ещё нужно распаковывать текст, чтобы его было видно. Вот код функций. Код (Text): x_WSARecv proc <7> uses rbx s:QWORD,lpBuffers:QWORD,qwBufferCount:QWORD,lpNumberOfBytesRecvd:QWORD,\ pFlags:QWORD,lpOverlapped:QWORD,lpCompletionROUTINE:QWORD LOCAL AxResult:QWORD LOCAL DxResult:QWORD LOCAL CallerHeader:QWORD LOCAL CallerName[128]:BYTE LOCAL CallerToRecvOut[256]:BYTE ;IndexOfName=52 WSARecv TEXTEQU <[FuncAddrs][8*70]> mov s,rcx mov lpBuffers,rdx mov qwBufferCount,r8 mov lpNumberOfBytesRecvd,r9 ;actions before ;--------------------------------------------------------------- ;call to original function invoke WSARecv,s,lpBuffers,qwBufferCount,lpNumberOfBytesRecvd,\ ;вызов настоящего WSARecv`a pFlags,lpOverlapped,lpCompletionROUTINE mov AxResult,rax mov DxResult,rdx ;actions after .if AxResult==NULL && hRecv CONSTANT CallerPatt db 13,10,'Вызов из модуля %s',13,10,\ 'с аддрессом возврата %I64x',13,10,0 invoke RtlPcToFileHeader,[rbp+8],addr CallerHeader ;получение по аддрессу хэндла модуля invoke GetModuleFileName,CallerHeader,addr CallerName,sizeof CallerName invoke sprintf,addr CallerToRecvOut,addr CallerPatt,addr CallerName,[rbp+8] invoke RecvOut,addr CallerToRecvOut mov ebx,dword ptr qwBufferCount .repeat mov rdx,lpBuffers lea rdx,[rdx][8*rbx-8] lea rdx,[rdx][8*rbx-8] .if [rdx][WSABUF.u_long] invoke RecvOut,[rdx][WSABUF.buf] ;это вывод в edit-box .endif dec rbx .until ZERO? .endif ;results returning mov rax,AxResult mov rdx,DxResult ret x_WSARecv endp Например для http://www.ya.ru/ после первого заголовка видны одни крякозябры Код (Text): Вызов из модуля C:\XP64\system32\wsock32.dll с адрессом возврата 7ff770f3518 HTTP/1.1 200 OK Server: nginx Date: Mon, 15 Mar 2010 09:26:16 GMT Content-Type: text/html; charset=utf-8 Last-Modified: Tue, 12 Jan 2010 15:29:04 GMT Transfer-Encoding: chunked Connection: keep-alive Content-Encoding: gzip 96a ‹®’Td6Ö½ØPLb¬é†ž?%*ôZl›=d5@™¨µß*Ùe›…¤‚~]CjFeo†´¸ã4}”cODäÃÓfó-f$¼?£na•/BOë©¢R!Ì$öÈ´FyA–„üº=c÷¼ [C1¶à-DsºØˆ›<ˆõs Û•gQÛE@DZð ) ±Mà,øZÖ<²HŸå"sÓ ‘‹Uó3~Á‹QwÁSˆÃx$ú¾pÏÉÓ·«}Í©èi pt~äµ5”’Zéñ²öÉF«µ¶qÚxæÒÒ¾Ž#—?¤R½ï4[å„)ˆ˜á£ÜÇ©£ÈW<1äãP®ú„Ÿ CëÃ;˜22ó fõ;Ÿ¾¼Ç‚¨ôƒÌ„S†1I…§b3ŒS¬ë;v§ßUÊ#3Ñ™ô;ýzݘ¼kÿJi]{H>WrÒ?ïµ4œç¥ûyã™x¢½™8ðBATØ»>òt¥¡H?a±+aæhTB5èrçš5>(BàÌ´÷»½™ÿ
это там элементарно делается unc_buff=new CHAR[len*100];\\5 or 10 or 1000 мы не знаем степень сжатия show_error("Expanding..."); zstrm.zalloc = Z_NULL; zstrm.zfree = Z_NULL; zstrm.opaque = Z_NULL; zstrm.avail_in = len; zstrm.next_in = Z_NULL; inflateInit(&zstrm); zstrm.next_in=(Bytef *)buff; zstrm.avail_out = len*100; zstrm.next_out = (Bytef *)unc_buff; ret=inflate(&zstrm,Z_NO_FLUSH);
и кстате если данные в гзипе то и распаковываемый размер можно узнать в злибе есть функции специально для работы с гзипом
Ээээ, не все так просто и быстро, там еще заголовок gzip'a есть, и если просто так подсунуть данные в zlib - то ничего не выйдет. Плюс ко всему, необходимо заводить автомат состояния для zlib'a т.к. необходимо последовательно обрабатывать блок за блоком (Transfer-Encoding: chunked). Как этот автомат состояния выглядит можно посмотреть в библиотеке whireShark. Когда то давно я писал http парсер подсматривая некоторые моменты в whireshark'e . Вот, собственно код для распаковки самих данных... Там правда дебаговая версия для т.ч. ловить утечку памяти внутри zlib, а она там может быть если неправильно автомат состояний построишь...
какой конечный автомат ? Я когда-то дописывал в злиб ф-цию для сжатия и распаковки данных прямо из памяти, вообще странно что там такой ф-ции нет по умолчанию) Зато есть ф-ции gzwrite/gzread для файлов, я оттуда вызовы повытаскивал и вставил в свою ф-цию, там ничего сложного. Правда после этого у меня размер проекта увеличился килобайт на 15-20 от этого злиба... В винде в урлмоне есть класс для работы с гзипом,тока его в очень старых версиях неть, гуглите вобщем
который может распаковывать поток данных (поток по определению может быть бесконечным). Вот в zlib'e включили такую возможность для распаковки потоков, т.е. данные в zlib запихиваются порциями. И как тут обойтись без конечного автомата ? А функция inflate библиотеки как раз этим и занимается, подсовываешь ей блок данных и она выдает распакованные данные и код ошибки который как раз характеризует внутренний автомат состояния zlib'a. Читайте документацию и смотрите примеры, там все прекрасно расписано. http://www.zlib.net/zlib_how.html http://www.zlib.net/manual.html
Парни , как правильно распаковать raw data ? Имеем буфер запакованный . Размер буфера может быть любым. Заголовка буфер не имеет . При распаковке максимум правильно распакованных байт 4096 начала . Дальнейшие байты нули. У кого есть код функции для распаковки raw data ? Спасибо.
советую не мучаться, а тупо затереть в Content-Encoding: пробелами всё, если там написано gzip или deflate тогда данные пойдут не сжатыми, ну и HTTP 1.0 добавить иначе все будет валиться чанками, браузер иногда не может такое схавать.