Valhalla Legends Forums Archive | Advanced Programming | "Hooking" War3's WSARecv

AuthorMessageTime
UserLoser.
Hi, I'm attempting to write a semi-useful hack for Warcraft III, so ofcourse I'll need to be hooking it's WSARecv and WSASend calls to get everything started (the fun stuff).  I'm quite new to overlapped I/O (or using WSARecv for that matter) so I've come to some troubles.  Currently where War3.exe would call WSARecv I have replaced it with my function:

[code]
int __stdcall WSARecvStub(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd,
  LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped,  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
return WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine);
}
[/code]

This code works fine.  Setting lpCompletionRoutine to anything else (which I thought would do the trick) causes it to return SOCKET_ERROR (-1) which isn't good and causes War3 to think something went wrong (well something did, but that's not wanted).  How could I go about receiving data and reading what the data is?  I'm assuming modifying/using my own WSAOVERLAPPED structure would be correct, but where do I start?
December 31, 2004, 12:16 PM
Kp
First, you need to determine how war3 does its network input.  It could be using a blocking recv, a non-blocking recv, an overlapped read with completion routine, or an overlapped read with I/O completion ports.  Identify and post which it is and I can guide you further.
December 31, 2004, 5:27 PM
UserLoser.
[quote author=Kp link=topic=10066.msg93956#msg93956 date=1104514056]
First, you need to determine how war3 does its network input.  It could be using a blocking recv, a non-blocking recv, an overlapped read with completion routine, or an overlapped read with I/O completion ports.  Identify and post which it is and I can guide you further.
[/quote]

Well, so far I've figured: there's no completion routine because I can set it it to NULL and it'll be ok (won't return SOCKET_ERROR).  It does something with WSAIoctl with control code 0x9800000C, while the lpOverlapped and lpCompletionRoutine parameters are null (msdn says if these are NULL then it's non-overlapped socket, so i think overlapped read with I/O completion is out of the scene).

Looks like blocking recv?  Don't see any other WSAIoctl calls to set the socket to be nonblocking
December 31, 2004, 6:43 PM
Kp
That's what I expected.  Blizzard seems to prefer blocking netloops, which isn't actually that surprising since they Win9x kernels tend to do bizarre things with overlapped operations.

To address your original question:

[code]int __stdcall WSARecvStub(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped,  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) {
int r = WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine);
/* read received data here, but only if r > 0 */
return r;
}[/code]

However, beware that this falls prey to the same thing that plagues newbie bot developers: it presupposes that each receive constitutes a whole number of BNCS messages, which isn't always true.  A better solution would be to hook into the netloop code after it has already extracted a single message from the stream.
December 31, 2004, 8:17 PM

Search