перехват sendto на уровне сервисов

Тема в разделе "WASM.WIN32", создана пользователем Flasher, 13 окт 2008.

  1. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    Надо хукнуть функцию sendto из ws2_32.dll для получения передаваемого буфера в сеть.
    Решил реализовать через перехват сервисов. Мой ZwMonitor показал что sendto юзает селдующие сервисы в следующем порядке:

    Код (Text):
    1. ZwCreateFile                 (00000064h, c0100000h, "\Device\Afd\Endpoint", 0012fe4ch, 00000000h, 00000000h, 00000003h, 00000003h, 00000000h, 0012fe90h, 00000043h)
    2. ZwDeviceIoControlFile        (00000064h, 0000004ch, 00000000h, 00000000h, 0012fdd0h, 0001207bh, 0012fdc0h, 00000010h, 0012fdc0h, 00000010h)
    3. ZwDeviceIoControlFile        (00000064h, 0000004ch, 00000000h, 00000000h, 0012fdd0h, 0001207bh, 0012fdc0h, 00000010h, 0012fdc0h, 00000010h)
    4. ZwDeviceIoControlFile        (00000064h, 0000004ch, 00000000h, 00000000h, 0012fcd8h, 00012047h, 0012fcf0h, 000000f8h, 0012fd70h, 00000010h)
    5.  
    6. ;начало работы sendto
    7. ZwDeviceIoControlFile        (00000064h, 0000004ch, 00000000h, 00000000h, 0012fdc0h, 00012003h, 0012fddch, 0000001ah, 0012fddch, 0000001ah)
    8. ZwDeviceIoControlFile        (00000064h, 0000004ch, 00000000h, 00000000h, 0012fd5ch, 00012037h, 0012fd6ch, 00000004h, 0012fd64h, 00000008h)
    9. ZwDeviceIoControlFile        (00000064h, 0000004ch, 00000000h, 00000000h, 0012fc6ch, 00012047h, 0012fc84h, 000000f8h, 00000000h, 00000000h)
    10. ZwDeviceIoControlFile        (00000064h, 0000004ch, 00000000h, 00000000h, 0012fc54h, 0001202fh, 00000000h, 00000000h, 0012fc74h, 0000001ah)
    11. ZwOpenFile                   (0000006ch, 00100001h, "\Device\KsecDD", 0012ef0ch, 00000007h, 00000010h)
    12. ZwDeviceIoControlFile        (0000006ch, 00000000h, 00000000h, 00000000h, 0012eea0h, 00390008h, 77e46318h, 00000100h, 0012ef5ch, 00000100h)
    13. ZwClose                      (00000070h)
    14. ZwClose                      (00000074h)
    15. ZwQueryVirtualMemory         (ffffffffh, 77e7a2b0h, 0[MemoryBasicInformation], 0012f454h, 0000001ch, 0012f47ch)
    16. ZwDeviceIoControlFile        (00000064h, 0000004ch, 00000000h, 00000000h, 0012fe9ch, 00012023h, 0012fe48h, 00000038h, 00000000h, 00000000h)
    Код (Text):
    1. ZwDeviceIoControlFile(
    2.   IN HANDLE               FileHandle,
    3.   IN HANDLE               Event OPTIONAL,
    4.   IN PIO_APC_ROUTINE      ApcRoutine OPTIONAL,
    5.   IN PVOID                ApcContext OPTIONAL,
    6.   OUT PIO_STATUS_BLOCK    IoStatusBlock,
    7.   IN ULONG                IoControlCode,
    8.   IN PVOID                InputBuffer OPTIONAL,
    9.   IN ULONG                InputBufferLength,
    10.   OUT PVOID               OutputBuffer OPTIONAL,
    11.   IN ULONG                OutputBufferLength );
    Создал тестовой пример, где перез sendto передавал слово "privet".
    Поиск данного слова в 7-ом параметре ZwDeviceIoControlFile ничего не дало..

    Не подскажите в какую сторону копать?

    p.s. могет подскажите откуда стянуть исходный код ws2_32 или исходник именно функции sendto.

    Спасибо.
     
  2. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    Я так понял надо копать в сторону TDI ? Или TDI только для tcpip ?
     
  3. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    Походу один из IoControlCode = IOCTL_AFD_SEND_DATAGRAM, только как узнать какой ? msdn молчит как рыба, а гугль дал вот это:

    Код (Text):
    1. #define FILE_DEVICE_NETWORK             0x00000012
    2. #define FSCTL_AFD_BASE                  FILE_DEVICE_NETWORK
    3. #define _AFD_CONTROL_CODE(Operation,Method) ((FSCTL_AFD_BASE)<<12 | (Operation<<2) | Method)
    4. #define IOCTL_AFD_SEND_DATAGRAM        _AFD_CONTROL_CODE(AFD_SEND_DATAGRAM, METHOD_NEITHER)
    Как из этого вычислить IoControlCode я не знаю.
     
  4. shizo

    shizo New Member

    Публикаций:
    0
    Регистрация:
    8 окт 2008
    Сообщения:
    6
    глянь, хотя не уверен что это то :)
    ---
    файл не прикрепился, можешь кинуть мыло в пм, вечером отошлю
     
  5. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    Надыбал исходник WSPSendTo и есть подазрение что sendto обращается именно к нему.
    Правда api в библиотеке начинаются на WSA а не WSP :)

    Код (Text):
    1. int
    2. WSPAPI
    3. WSPSendTo(
    4.     SOCKET Handle,
    5.     LPWSABUF lpBuffers,
    6.     DWORD dwBufferCount,
    7.     LPDWORD lpNumberOfBytesSent,
    8.     DWORD iFlags,
    9.     const struct sockaddr *SocketAddress,
    10.     int SocketAddressLength,
    11.     LPWSAOVERLAPPED lpOverlapped,
    12.     LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
    13.     LPWSATHREADID lpThreadId,
    14.     LPINT lpErrno)
    15. {
    16.     PIO_STATUS_BLOCK            IOSB;
    17.     IO_STATUS_BLOCK             DummyIOSB;
    18.     AFD_SEND_INFO_UDP           SendInfo;
    19.     NTSTATUS                    Status;
    20.     PVOID                       APCContext;
    21.     PVOID                       APCFunction;
    22.     HANDLE                      Event;
    23.     PTRANSPORT_ADDRESS          RemoteAddress;
    24.     UCHAR                       TdiBuffer[0x16];
    25.     PSOCKADDR                   BindAddress;
    26.     INT                         BindAddressLength;
    27.     HANDLE                                  SockEvent;
    28.     PSOCKET_INFORMATION         Socket;
    29.    
    30.  
    31.     /* Get the Socket Structure associate to this Socket*/
    32.     Socket = GetSocketStructure(Handle);
    33.  
    34.     Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
    35.                 NULL, 1, FALSE );
    36.  
    37.     if( !NT_SUCCESS(Status) ) return -1;
    38.  
    39.     /* Bind us First */
    40.     if (Socket->SharedData.State == SocketOpen) {
    41.        
    42.         /* Get the Wildcard Address */
    43.         BindAddressLength = Socket->HelperData->MaxWSAddressLength;
    44.         BindAddress = HeapAlloc(GlobalHeap, 0, BindAddressLength);
    45.         Socket->HelperData->WSHGetWildcardSockaddr (Socket->HelperContext,
    46.                                                     BindAddress,
    47.                                                     &BindAddressLength);
    48.  
    49.         /* Bind it */
    50.         WSPBind(Handle, BindAddress, BindAddressLength, NULL);
    51.     }
    52.  
    53.     /* Set up Address in TDI Format */
    54.     RemoteAddress = (PTRANSPORT_ADDRESS)TdiBuffer;
    55.     RemoteAddress->TAAddressCount = 1;
    56.     RemoteAddress->Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family);
    57.     RtlCopyMemory(&RemoteAddress->Address[0].AddressType, SocketAddress, SocketAddressLength);
    58.  
    59.     /* Set up Structure */
    60.     SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
    61.     SendInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0;
    62.     SendInfo.BufferCount = dwBufferCount;
    63.     SendInfo.RemoteAddress = RemoteAddress;
    64.     SendInfo.SizeOfRemoteAddress = Socket->HelperData->MaxTDIAddressLength;
    65.  
    66.     /* Verifiy if we should use APC */
    67.     if (lpOverlapped == NULL) {
    68.  
    69.         /* Not using Overlapped structure, so use normal blocking on event */
    70.         APCContext = NULL;
    71.         APCFunction = NULL;
    72.         Event = SockEvent;
    73.         IOSB = &DummyIOSB;
    74.  
    75.     } else {
    76.  
    77.         if (lpCompletionRoutine == NULL) {
    78.  
    79.             /* Using Overlapped Structure, but no Completition Routine, so no need for APC */
    80.             APCContext = lpOverlapped;
    81.             APCFunction = NULL;
    82.             Event = lpOverlapped->hEvent;
    83.        
    84.         } else {
    85.  
    86.             /* Using Overlapped Structure and a Completition Routine, so use an APC */
    87.             APCFunction = NULL; // should be a private io completition function inside us
    88.             APCContext = lpCompletionRoutine;
    89.             SendInfo.AfdFlags = AFD_SKIP_FIO;
    90.         }
    91.  
    92.         IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
    93.         SendInfo.AfdFlags |= AFD_OVERLAPPED;
    94.     }
    95.  
    96.     /* Send IOCTL */
    97.     Status = NtDeviceIoControlFile((HANDLE)Handle,
    98.                     SockEvent,
    99.                     APCFunction,
    100.                     APCContext,
    101.                     IOSB,
    102.                     IOCTL_AFD_SEND_DATAGRAM,
    103.                     &SendInfo,
    104.                     sizeof(SendInfo),
    105.                     NULL,
    106.                     0);
    107.  
    108.     /* Wait for completition of not overlapped */
    109.     if (Status == STATUS_PENDING && lpOverlapped == NULL) {
    110.         WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infintely for send...
    111.         Status = IOSB->Status;
    112.     }
    113.  
    114.     NtClose( SockEvent );
    115.  
    116.     if (Status == STATUS_PENDING) {
    117.         return WSA_IO_PENDING;
    118.     }
    119.  
    120.     /* Re-enable Async Event */
    121.     SockReenableAsyncSelectEvent(Socket, FD_WRITE);
    122.  
    123.     return MsafdReturnWithErrno
    124.     ( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent );
    125. }
    Отсюда
    Код (Text):
    1. SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
    моно сделать вывод что в SendInfo.BufferArray указатель на строку, а не сама строка, поэтому когда я чекал InputBuffer всех 6-и запросов ZwDeviceIoControlFile, не нашел своей строки, да ? Правильный вывод ?
     
  6. slow

    slow New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2004
    Сообщения:
    615
    http://ifolder.ru/4949724
     
  7. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    slow, thanks, кстати там какраз тот код что я выше привел..
     
  8. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    Как оказалось IOCTL_AFD_SEND_DATAGRAM = 00012023h

    Это значит нам интересен запрос:
    Код (Text):
    1. ZwDeviceIoControlFile        (00000064h, 0000004ch, 00000000h, 00000000h, 0012fe9ch, 00012023h, 0012fe48h, 00000038h, 00000000h, 00000000h)
    Код (Text):
    1. typedef struct _AFD_WSABUF {
    2.      UINT  len
    3.      PCHAR buf
    4. } AFD_WSABUF, *PAFD_WSABUF
    5.  
    6. typedef struct _AFD_SEND_INFO_UDP {
    7.      PAFD_WSABUF                         BufferArray
    8.      ULONG                               BufferCount
    9.      ULONG                               AfdFlags
    10.      ULONG                               Padding[9]
    11.      ULONG                               SizeOfRemoteAddress
    12.      PVOID                               RemoteAddress
    13. } AFD_SEND_INFO_UDP, *PAFD_SEND_INFO_UDP
    Хукаю ZwDeviceIoControlFile и добираюсь до передаваемых данных вот так:

    Код (Text):
    1.         mov eax,InputBuffer
    2.         mov eax,AFD_SEND_INFO_UDP.BufferArray[eax]
    3.         mov eax,AFD_WSABUF.buf[eax]
    Надеюсь не кто не против что я тут нафлудил чуток..
    Всётаки это замечательно когда есть где выговориватся..
    Пока пишешь пост а хелпе, появляется решение задачи в голове :)