【详细过程】
在魔兽的联机过程中,主机负责转发其他玩家的操作,其他玩家只与主机联系。这样主机就可以干很多事情,所以延迟外挂就只能在主机上使用。
延迟外挂的初步思路是HOOK主机魔兽的网络通信函数,然后再sleep一定的MS数,来达到人为制造延迟的目的。
HOOK操作可以用微软研究院的Detours开发包方便地实现。
经过试验,发现魔兽使用send来发送,WSARecv来接受。
DLL的核心代码如下:
然后在DllMain中进行初始化:
写完DLL就可以将它注入war3进程,注入完后别人就开始延迟了。
在魔兽的联机过程中,主机负责转发其他玩家的操作,其他玩家只与主机联系。这样主机就可以干很多事情,所以延迟外挂就只能在主机上使用。
延迟外挂的初步思路是HOOK主机魔兽的网络通信函数,然后再sleep一定的MS数,来达到人为制造延迟的目的。
HOOK操作可以用微软研究院的Detours开发包方便地实现。
经过试验,发现魔兽使用send来发送,WSARecv来接受。
DLL的核心代码如下:
代码:
//申明要HOOK的函数 int (WINAPI *pSend)(SOCKET s, const char* buf, int len, int flags) = send; int WINAPI MySend(SOCKET s, const char* buf, int len, int flags); int (WINAPI *pWSARecv)(SOCKET s,LPWSABUF lpBuffers,DWORD dwBufferCount,LPDWORD lpNumberOfBytesRecvd,LPDWORD lpFlags,LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) = WSARecv; int WINAPI MyWSARecv(SOCKET s,LPWSABUF lpBuffers,DWORD dwBufferCount,LPDWORD lpNumberOfBytesRecvd,LPDWORD lpFlags,LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); int WINAPI MySend(SOCKET s, const char* buf, int len, int flags) { return pSend(s, buf, len, flags); } int WINAPI MyWSARecv(SOCKET s,LPWSABUF lpBuffers,DWORD dwBufferCount,LPDWORD lpNumberOfBytesRecvd,LPDWORD lpFlags,LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) { Sleep(1000); //在send中也可以sleep,不过那样就会导致大家魔兽一起卡 return pWSARecv( s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine); }
然后在DllMain中进行初始化:
代码:
DisableThreadLibraryCalls(hModule); DetourTransactionBegin(); //detours初始化 DetourUpdateThread(GetCurrentThread()); //更新detours线程 DetourAttach(&(PVOID&)pSend, MySend); //要Hook的函数 if(DetourTransactionCommit()!=NO_ERROR) //生效的操作 MessageBox(NULL,(LPCWSTR)L"failed",(LPCWSTR)L"blocked",MB_OK); DetourTransactionBegin(); //detours初始化 DetourUpdateThread(GetCurrentThread()); //更新detours线程 DetourAttach(&(PVOID&)pWSARecv, MyWSARecv); //要Hook的函数 if(DetourTransactionCommit()!=NO_ERROR) //生效的操作 MessageBox(NULL,(LPCWSTR)L"failed",(LPCWSTR)L"blocked",MB_OK);