Reputation: 618
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
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
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
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