Author | Message | Time |
---|---|---|
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 |