Надо хукнуть функцию sendto из ws2_32.dll для получения передаваемого буфера в сеть. Решил реализовать через перехват сервисов. Мой ZwMonitor показал что sendto юзает селдующие сервисы в следующем порядке: Код (Text): ZwCreateFile (00000064h, c0100000h, "\Device\Afd\Endpoint", 0012fe4ch, 00000000h, 00000000h, 00000003h, 00000003h, 00000000h, 0012fe90h, 00000043h) ZwDeviceIoControlFile (00000064h, 0000004ch, 00000000h, 00000000h, 0012fdd0h, 0001207bh, 0012fdc0h, 00000010h, 0012fdc0h, 00000010h) ZwDeviceIoControlFile (00000064h, 0000004ch, 00000000h, 00000000h, 0012fdd0h, 0001207bh, 0012fdc0h, 00000010h, 0012fdc0h, 00000010h) ZwDeviceIoControlFile (00000064h, 0000004ch, 00000000h, 00000000h, 0012fcd8h, 00012047h, 0012fcf0h, 000000f8h, 0012fd70h, 00000010h) ;начало работы sendto ZwDeviceIoControlFile (00000064h, 0000004ch, 00000000h, 00000000h, 0012fdc0h, 00012003h, 0012fddch, 0000001ah, 0012fddch, 0000001ah) ZwDeviceIoControlFile (00000064h, 0000004ch, 00000000h, 00000000h, 0012fd5ch, 00012037h, 0012fd6ch, 00000004h, 0012fd64h, 00000008h) ZwDeviceIoControlFile (00000064h, 0000004ch, 00000000h, 00000000h, 0012fc6ch, 00012047h, 0012fc84h, 000000f8h, 00000000h, 00000000h) ZwDeviceIoControlFile (00000064h, 0000004ch, 00000000h, 00000000h, 0012fc54h, 0001202fh, 00000000h, 00000000h, 0012fc74h, 0000001ah) ZwOpenFile (0000006ch, 00100001h, "\Device\KsecDD", 0012ef0ch, 00000007h, 00000010h) ZwDeviceIoControlFile (0000006ch, 00000000h, 00000000h, 00000000h, 0012eea0h, 00390008h, 77e46318h, 00000100h, 0012ef5ch, 00000100h) ZwClose (00000070h) ZwClose (00000074h) ZwQueryVirtualMemory (ffffffffh, 77e7a2b0h, 0[MemoryBasicInformation], 0012f454h, 0000001ch, 0012f47ch) ZwDeviceIoControlFile (00000064h, 0000004ch, 00000000h, 00000000h, 0012fe9ch, 00012023h, 0012fe48h, 00000038h, 00000000h, 00000000h) Код (Text): ZwDeviceIoControlFile( IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength ); Создал тестовой пример, где перез sendto передавал слово "privet". Поиск данного слова в 7-ом параметре ZwDeviceIoControlFile ничего не дало.. Не подскажите в какую сторону копать? p.s. могет подскажите откуда стянуть исходный код ws2_32 или исходник именно функции sendto. Спасибо.
Походу один из IoControlCode = IOCTL_AFD_SEND_DATAGRAM, только как узнать какой ? msdn молчит как рыба, а гугль дал вот это: Код (Text): #define FILE_DEVICE_NETWORK 0x00000012 #define FSCTL_AFD_BASE FILE_DEVICE_NETWORK #define _AFD_CONTROL_CODE(Operation,Method) ((FSCTL_AFD_BASE)<<12 | (Operation<<2) | Method) #define IOCTL_AFD_SEND_DATAGRAM _AFD_CONTROL_CODE(AFD_SEND_DATAGRAM, METHOD_NEITHER) Как из этого вычислить IoControlCode я не знаю.
Надыбал исходник WSPSendTo и есть подазрение что sendto обращается именно к нему. Правда api в библиотеке начинаются на WSA а не WSP Код (Text): int WSPAPI WSPSendTo( SOCKET Handle, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD iFlags, const struct sockaddr *SocketAddress, int SocketAddressLength, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno) { PIO_STATUS_BLOCK IOSB; IO_STATUS_BLOCK DummyIOSB; AFD_SEND_INFO_UDP SendInfo; NTSTATUS Status; PVOID APCContext; PVOID APCFunction; HANDLE Event; PTRANSPORT_ADDRESS RemoteAddress; UCHAR TdiBuffer[0x16]; PSOCKADDR BindAddress; INT BindAddressLength; HANDLE SockEvent; PSOCKET_INFORMATION Socket; /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, NULL, 1, FALSE ); if( !NT_SUCCESS(Status) ) return -1; /* Bind us First */ if (Socket->SharedData.State == SocketOpen) { /* Get the Wildcard Address */ BindAddressLength = Socket->HelperData->MaxWSAddressLength; BindAddress = HeapAlloc(GlobalHeap, 0, BindAddressLength); Socket->HelperData->WSHGetWildcardSockaddr (Socket->HelperContext, BindAddress, &BindAddressLength); /* Bind it */ WSPBind(Handle, BindAddress, BindAddressLength, NULL); } /* Set up Address in TDI Format */ RemoteAddress = (PTRANSPORT_ADDRESS)TdiBuffer; RemoteAddress->TAAddressCount = 1; RemoteAddress->Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family); RtlCopyMemory(&RemoteAddress->Address[0].AddressType, SocketAddress, SocketAddressLength); /* Set up Structure */ SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers; SendInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0; SendInfo.BufferCount = dwBufferCount; SendInfo.RemoteAddress = RemoteAddress; SendInfo.SizeOfRemoteAddress = Socket->HelperData->MaxTDIAddressLength; /* Verifiy if we should use APC */ if (lpOverlapped == NULL) { /* Not using Overlapped structure, so use normal blocking on event */ APCContext = NULL; APCFunction = NULL; Event = SockEvent; IOSB = &DummyIOSB; } else { if (lpCompletionRoutine == NULL) { /* Using Overlapped Structure, but no Completition Routine, so no need for APC */ APCContext = lpOverlapped; APCFunction = NULL; Event = lpOverlapped->hEvent; } else { /* Using Overlapped Structure and a Completition Routine, so use an APC */ APCFunction = NULL; // should be a private io completition function inside us APCContext = lpCompletionRoutine; SendInfo.AfdFlags = AFD_SKIP_FIO; } IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; SendInfo.AfdFlags |= AFD_OVERLAPPED; } /* Send IOCTL */ Status = NtDeviceIoControlFile((HANDLE)Handle, SockEvent, APCFunction, APCContext, IOSB, IOCTL_AFD_SEND_DATAGRAM, &SendInfo, sizeof(SendInfo), NULL, 0); /* Wait for completition of not overlapped */ if (Status == STATUS_PENDING && lpOverlapped == NULL) { WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infintely for send... Status = IOSB->Status; } NtClose( SockEvent ); if (Status == STATUS_PENDING) { return WSA_IO_PENDING; } /* Re-enable Async Event */ SockReenableAsyncSelectEvent(Socket, FD_WRITE); return MsafdReturnWithErrno ( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent ); } Отсюда Код (Text): SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers; моно сделать вывод что в SendInfo.BufferArray указатель на строку, а не сама строка, поэтому когда я чекал InputBuffer всех 6-и запросов ZwDeviceIoControlFile, не нашел своей строки, да ? Правильный вывод ?
Как оказалось IOCTL_AFD_SEND_DATAGRAM = 00012023h Это значит нам интересен запрос: Код (Text): ZwDeviceIoControlFile (00000064h, 0000004ch, 00000000h, 00000000h, 0012fe9ch, 00012023h, 0012fe48h, 00000038h, 00000000h, 00000000h) Код (Text): typedef struct _AFD_WSABUF { UINT len PCHAR buf } AFD_WSABUF, *PAFD_WSABUF typedef struct _AFD_SEND_INFO_UDP { PAFD_WSABUF BufferArray ULONG BufferCount ULONG AfdFlags ULONG Padding[9] ULONG SizeOfRemoteAddress PVOID RemoteAddress } AFD_SEND_INFO_UDP, *PAFD_SEND_INFO_UDP Хукаю ZwDeviceIoControlFile и добираюсь до передаваемых данных вот так: Код (Text): mov eax,InputBuffer mov eax,AFD_SEND_INFO_UDP.BufferArray[eax] mov eax,AFD_WSABUF.buf[eax] Надеюсь не кто не против что я тут нафлудил чуток.. Всётаки это замечательно когда есть где выговориватся.. Пока пишешь пост а хелпе, появляется решение задачи в голове