привет. необходимо реализовать сплайсинг сокетов. работаю через detours. по ходу дела я немного анализирую пакеты и блокирую/редактирую некоторые из них. модуль работает для браузеров. нужно ИЕ и ФФ. ИЕ работает через recv/send. перехватил их нормально. с буфером нормально отработал. также нужно поступить и с WSARecv/WSASend. в документации написано, что WSARecv является надстройкой над стандартным recv. и сенд аналогично. по ходу дела получилось так, что с помощью перехвата send перехватились пакеты из WSASend, а с WSARecv/recv так не вышло (ничего не приходит). можно ли обрабатывать все пакеты, перехватывая лишь recv/send? если нет, то как работать с буффером WSARecv? он хранит массив буферов. сколько их, как их писать. может, есть у кого опыт в этом деле. поделитесь соображениями, плз. как в такой ситуации поступали? заранее всем спасибо
saxon Для таких дел стоит клацнуть "сообщить модератору" и попросить перенести в другой форум. Не надо плодить тыщу копий
их там много. есть ли у них ограничение по объему? или можно просто сначала все буферы соединять в один, обрабатывать, а потом опят разделять на несколько буферов? и почему не получается обрабатывать запрос по WSA через обычные сокеты? ведь это надстройка? или нет?
int WSARecv( __in SOCKET s, __in_out LPWSABUF lpBuffers, __in DWORD dwBufferCount, __out LPDWORD lpNumberOfBytesRecvd, __in_out LPDWORD lpFlags, __in LPWSAOVERLAPPED lpOverlapped, __in LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ); нету не каких ограничений, просто можно указывать несколько буферов, можно это рассматривать как dwBufferCount раз вызовов к recv/send. for(DWORD i = 0; i < dwBufferCount; i++) { lpBuffers; //Содержимое текущего буфера. lpNumberOfBytesRecvd; //Размер текущего буфера. } >или можно просто сначала все буферы соединять в один, обрабатывать, а потом опят разделять на несколько буферов? не в коем случаи. >и почему не получается обрабатывать запрос по WSA через обычные сокеты? ведь это надстройка? или нет? вероятно recv,send, WSA* это насдтройки над внутреней функцией. кажется в исходниках win2k3 был код ws2_32.dll
>нету не каких ограничений, просто можно указывать несколько буферов, можно это рассматривать как dwBufferCount раз вызовов к recv/send. Мне необходимо перед выдачей контента юзеру сначала загрузить все, проанализировать, изменить и вернуть ему. в случае с recv я при первом пакете вызываю до отказа recv, анализирую, отдаю. как тогда анализировать несколько буферов? почему их нельзя соединить, а в конце порезать по размерам буферов? в МСДН по этому поводу ничего не нашел.
в ИЕ6 как-то интересно все сделано. на отправку там send, на получение WSARecv. зачем они такое сделали.. но, не в этом дело. я хотел бы сохранять в файл просто содердимое буфера из WSARecv. в коде пишу просто сохранение в файл и возвращаю сразу результат выполнения оригинальной функции. но, ИЕ выдает ошибку (невозморжно загрузить...).если работу с дескрипторами (файлом) убрать, то все ок. почему так происходит и как с этим бороться? в теории, когда у ИЕ таймаут, он сразу начинает проверять сеть - отсылает по УДП байтик. здесь такое делает, но, это не помогает. подскажите, что еще нужно перехватить, чтобы можно было залогировать пакеты?
>как тогда анализировать несколько буферов? почему их нельзя соединить, а в конце порезать по размерам буферов? я все расписал, как это сделать. "можно это рассматривать как dwBufferCount раз вызовов к recv/send." при чем тут ие вообще? смотри ошибку в коде какая нить функция не парвильно вызывается или еше че, лучше код показать
> но, ИЕ выдает ошибку (невозморжно загрузить...).если работу с дескрипторами (файлом) убрать, то все ок. попробуй после вызова сохранить код ошибки GetLastError, а когда сделаешь все свои дела, перед возвратом, установи обратно эту ошибку
Вчера/позавчера был подобный топик, наверно его удалили. Вобщем можно сграбить не привлекая механизм исключений. Перехват статический. Механизм следующий: o Загружаем mswsock.dll o Трассируем(ldasm) функцию(экспортируется) WSPStartup(), находим код: Код (Text): mov esi,offset _SockProcTable rep movsd и извлекаем ссылку на таблицу _SockProcTable: Код (Text): $ _WSPAccept@24 $+4 _WSPAddressToString@24 $+8 _WSPAsyncSelect@20 $+C _WSPBind@16 $+10 _WSPCancelBlockingCall@4 $+14 _WSPCleanup@4 $+18 _WSPCloseSocket@8 $+1C _WSPConnect@32 $+20 _WSPDuplicateSocket@16 $+24 _WSPEnumNetworkEvents@16 $+28 _WSPEventSelect@16 $+2C _WSPGetOverlappedResult@24 $+30 _WSPGetPeerName@16 $+34 _WSPGetSockName@16 $+38 _WSPGetSockOpt@24 $+3C _WSPGetQOSByName@16 $+40 _WSPIoctl@44 $+44 _WSPJoinLeaf@36 $+48 _WSPListen@12 $+4C _WSPRecv@36 $+50 _WSPRecvDisconnect@12 $+54 _WSPRecvFrom@44 $+58 _WSPSelect@24 $+5C _WSPSend@36 $+60 _WSPSendDisconnect@12 $+64 _WSPSendTo@44 $+68 _WSPSetSockOpt@24 $+6C _WSPShutdown@12 $+70 _WSPSocket@28 $+74 _WSPStringToAddress@24 Это целевые стабы, по сути являются заглушками для высокоуровневых функций. Для целевой WSASend() стаб это _WSPSend(). o Выполняем обмен значения для необходимого индекса в массиве, тоесть по адресу [_SockProcTable + 23*4] загружаем ссылку на хэндлер _WSPSend(), предварительно сохранив текущий. Эта манипуляция абсолютно безопасна, таблица в секции данных. o Таблица будет передана далее из WSPStartup() и все запросы пройдут через её стабы. Хэндлер может выполнить низкоуровневую обработку(текущий уровень апи), трассировать до NtDeviceIoControlFile, либо выполнить бактрейс с захватом адреса возврата, вернуть управление и обработать высокоуровневый вызов(в стековых фреймах параметры). - Так только на XP, как в остальных версиях не знаю, также не юзал это.
juggler Разниц нет, это обёртка вокруг калбэков. В win2k сурцах кстате всё есть полностью, так что это опенсурс. Единственный нюанс это енум описателей с их захватом проблемный. Тоесть код что выше он статический, юзается есчо до инициализации, тогда копия таблицы калбэков будет разослана. Проблема в захвате уже инициализированных описателей(хотя не проблема, нужно найти sm_context_table, она юзается WahReferenceContextByHandle(), енумить описатели и модифицировать таблицы).