I'm writing a packet encryption for a friends gameserver. Client is using ws2_32 recv/send but server uses WSARecv/WSASend.
I've managed to encrypt/decrypt send/recv/WSASend, but WSARecv seems impossible. I'm using the same method as on recv, but it doesn't seem to work.
int WINAPI MyWSARecv(SOCKET socket, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags,LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
LPWSABUF buffers = lpBuffers;
int ret = pWSARecv(socket, buffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine);
cryptPacket(buffers->buf, buffers->len);
lpBuffers = buffers;
return ret;
}
Any ideas would be appreciated.
A handful of things to consider.
You are not actually checking the return value from pWASRecv
before calling your cryptPacket
function. You need to start with that fix first before any other assumptions can be made about how the detour hooks work with the socket code. If the call indicates an error, it's probably not well defined what buffers->len
is going to be or what is going to be in those buffers.
Also, you are likely assuming that the socket was initialized to be synchronous. If the socket was initialized for overlapped I/O, then the lpOverlapped
and lpCompletionRoutine
parameters become very relevant. You may need to hook the completion routine or WSAGetOverlappedResult
to actually intercept the socket data.
Finally, may I suggest another approach. Rather than trying to "detour" the socket API calls, run a "proxy socket". That is, when the server socket is created (via a call to "socket"), you change it to listen on a different port. Then you create a separate listen socket that listens on the original port. When an incoming connection comes into your socket, you make a separate "proxy" connection to the actual port the game server is listening on. You can have a dedicated thread that just calls send
and recv
on the client socket that encrypts/decrypts data as needed.