Здравствуйте, задача следующая- есть процесс, в котором установлено tcp соединение. А нужно "передать" это соединение другому процессу, который должен служить промежуточным звеном(по сути прокси-сервером). Возможно ли это сделать не залезая в ядро?
Да, но этого мало. Нужно перехватить ещё и connect, в котором установить соединение с моим процессом, а он уже выполнит соединение, которое запрашивал целевой. Вопрос- можно ли что-то сделать, если connect уже выполнен? Нужно иметь возможность подсовывать собственные пакеты. Насколько я понимаю LSP это не подвластно.
А можно чуть конкретнее? А то совсем не понятно что вы имеете ввиду. Отсюда следует, что возможности LSP ограничиваются обработкой вызовов API.
А не у кого не завалялся диск от книги "Network programming for Microsoft Windows"(Программирование в сетях Microsoft Windows)? Хотелось бы посмотреть на реализацию LSP на том диске.
Euler с LSP потеряете времени немало на "разборки" - перехватите connect(), send(), recv() = перенаправляем все на проксик локальный или передаём инфу в другой поцесс....
Это уже реализовано, сейчас мне бы хотелось именно познакомится с этой технологией. В принципе пример есть на сайте microsoft, но там он довольно объёмный, хотелось бы что-нибудь поменьше.
Я вообще правильно понимаю принцип работы SPI? В системе есть БД поставщиков услуг. В этой БД хранятся записи трёх типов- "базовые", "многоуровневые" и "цепочки". Когда приложение создаёт сокет, оно просматривает эту БД и выбирает первую попавшуюся запись базового поставщика или цепочку. Т.е. для перехвата трафика нужно создать многоуровневый поставщик услуг и прописать его во все цепочки(а базовые протоколы "превратить" в цепочки). При этом ничто не мешает приложению создать новую цепочку, в которой не будет нежелательных поставщиков. Всё верно?
Ну тогда уж не забудь и структуры выложить для всех этих запросов. А также не забудь упомянуть, что этого недостаточно, ибо там, как минимум, ещё создание сокетных объектов, ну и корректное завершение соединения тоже не помешало бы. И, разумеется, было бы просто непростительно не сказать о том, что слать эти запросы надобно к \Device\Afd и \Device\Afd\EndPoint с помощью сервиса NtDeviceIoControlFile().
x64 Я дал направление человеку куда копать. Найти можно тут же на форуме. Единственно решение с ЛСП было бы лучше, но видимо оно нужно ему для другого.
x64(с) "Формат входных и выходных структур для управляющих запросов AFD меняется от версии к версии системы, так что написание собственных нативных сокетов на IOCTL-запросах представляется нетривиальной задачей, требующей анализа исходного кода операционной системы, а также реверсинга некоторых её частей (например, драйвера afd.sys)" .)
а так вот: Код (Text): typedef struct _AFD_WSABUF { UINT len; PCHAR buf; } AFD_WSABUF, *PAFD_WSABUF; typedef struct _TDI_ADDRESS_IP { USHORT sin_port; ULONG in_addr; UCHAR sin_zero[8]; } TDI_ADDRESS_IP, *PTDI_ADDRESS_IP; typedef struct _TA_ADDRESS_IP { LONG TAAddressCount; struct _AddrIp { USHORT AddressLength; USHORT AddressType; TDI_ADDRESS_IP Address[1]; } Address [1]; } TA_IP_ADDRESS, *PTA_IP_ADDRESS; typedef struct _TA_ADDRESS { USHORT AddressLength; USHORT AddressType; UCHAR Address[1]; } TA_ADDRESS, *PTA_ADDRESS; typedef struct _TRANSPORT_ADDRESS { LONG TAAddressCount; TA_ADDRESS Address[1]; } TRANSPORT_ADDRESS, *PTRANSPORT_ADDRESS; typedef struct _AFD_SEND_INFO { PAFD_WSABUF BufferArray; ULONG BufferCount; ULONG AfdFlags; ULONG TdiFlags; } AFD_SEND_INFO , *PAFD_SEND_INFO ; typedef struct _AFD_CONNECT_INFO { BOOLEAN UseSAN; ULONG Root; ULONG Unknown; //#if 1 /* bruening: based on win7 observation: i#376 */ // SOCKADDR Address; //#else TRANSPORT_ADDRESS Address; //#endif } AFD_CONNECT_INFO , *PAFD_CONNECT_INFO ; typedef struct _AFD_BIND_DATA { ULONG ShareType; #if 1 /* bruening: based on win7 observation: i#376 */ SOCKADDR Address; #else TRANSPORT_ADDRESS Address; #endif } AFD_BIND_DATA, *PAFD_BIND_DATA; ................................ void PrintAddress( PTA_ADDRESS address ) { char buffer[256]; if(address->AddressType == TDI_ADDRESS_TYPE_IP) { TDI_ADDRESS_IP* ip_address = (TDI_ADDRESS_IP*)address->Address; char *p; p = (char *)&ip_address->in_addr; in_addr ia; memcpy(&ia,&ip_address->in_addr,sizeof(in_addr)); sprintf(buffer,"%d.%d.%d.%d:%u", (UCHAR)p[0], (UCHAR)p[1], (UCHAR)p[2], (UCHAR)p[3], ntohs(ip_address->sin_port)); DPRINT2("Address = %s -- %s\n", buffer,inet_ntoa(ia)); } } .................... case IOCTL_AFD_CONNECT: OutputDebugStringA("IOCTL_AFD_CONNECT"); PAFD_CONNECT_INFO pAFDCI; pAFDCI = (PAFD_CONNECT_INFO)InputBuffer; TA_ADDRESS ta; ta = pAFDCI->Address.Address[0]; PrintAddress(&ta); кому надо тот разберется, это выдержка из проекта моего одного (черновик естественно)