splattru
splattru

Reputation: 618

WSARecv hook: prevent packet from being recieved by the executable

I am working on dll which hooks winsock2 functions, using C++ and detours. My goal is to modify TCP traffic that goes from and to the original executable. At some point, I need to stop certain packet delivery (so that original executable has no idea about that packet at all, but still keeps the connection).

With WSASend hook, it's clear (you just don't call original WSASend and return 0). But I have no idea how to make it in WSARecv hook using WSAOVERLAPPED structure.

I hope this code below demonstrates what do I want:

__declspec(dllexport) int WINAPI WSARecv_hook(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
    // Recieve real data
    int ret = WSARecv_real(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine);

    // Loop over lpBuffers and analyze it
    for(int i=0; i < dwBufferCount; i++)
    {
        // analyze it
        if(packet_should_be_blocked(lpBuffers[i].buf, lpBuffers[i].len))
        {
            // Do or return what?
        } else {
            // Otherwise, just process as usual
        }
    }
    return ret;
}

How do I pretend that nothing happened and no packet was recieved (like fake WSA_IO_PENDING)? Any ideas/thoughts?

P.S. From what I know, executable is not using completion routine (lpCompletionRoutine is always NULL), only overlapped structure.

Upvotes: 0

Views: 1320

Answers (2)

Ben Voigt
Ben Voigt

Reputation: 283634

A much easier way to modify TCP traffic is to hook only the connect family of functions, and make the application connect to a transparent proxy under your control that performs the actual stream modification.

Although it is possible for the application to write its own port number in the stream for the remote end to compare to the packet source address, this isn't a problem in practice because

  1. This would also break NAT-PAT gateways which are very common on residential internet connections
  2. You can rewrite the content and send the proxy's address, so the check passes

In fact, FTP proxies have to do this command rewriting because they spawn slave connections for file transfers. But most modern applications are written to be PAT compatible.

Upvotes: -1

Remy Lebeau
Remy Lebeau

Reputation: 596256

The main hurdle is that overlapped operations are meant to be performed in the background after the calling function has exited with a pending status. If the caller asks WSARecv() to perform an overlapped read, it is expecting the data to arrive in the background, and you won't be able to validate the data inside of your hook directly because it has not been received yet. You will have to use your own private WSAOVERLAPPED to perform your own overlapped read, using a thread or completion callback to detect when that read finishes so that you can then analyze the data. If the data is acceptable, copy it into the caller's buffer and signal the caller's WSAOVERLAPPED. Otherwise, post another read and wait for that data to arrive, repeating as needed until you finally receive some data that you want to give to the caller.

Upvotes: 3

Related Questions