#define UNICODE
#define _UNICODE
#include <afxwin.h>
#include <ws2spi.h>
#include <io.h>
#include <sporder.h>
#include <TCHAR.H>
//
// 全局变量,用来保存系统服务提供者30个服务函数指针
//
WSPPROC_TABLE NextProcTable ;
//
// 全局变量,用来临时保存全部服务提供者的信息
//
LPWSAPROTOCOL_INFOW ProtocolInfo = NULL;
DWORD ProtocolInfoSize = 0;
INT TotalProtocols = 0;
// UDP SOCKET总代理
//
//
SOCKET g_UdpProxy = INVALID_SOCKET;
int nErrorNo;
char szLog[512];
// 日志
void WriteLog(char *fmt,...)
{
FILE *fp;
va_list args;
char szTime[256];
SYSTEMTIME sys;
GetLocalTime( &sys );
sprintf(szTime,"[%02d:%02d:%02d.%03d]",sys.wHour,sys.wMinute, sys.wSecond,sys.wMilliseconds);
if((fp =fopen("C://XClientHookApi.log", "a")) !=NULL)
{
va_start(args,fmt);
fprintf(fp,"%s ",szTime);
vfprintf(fp,fmt, args);
fprintf(fp,"/n");
fclose(fp);
va_end(args);
}
}
BOOL GetProviders()
{
INT ErrorCode;
ProtocolInfo = NULL;
ProtocolInfoSize = 0;
TotalProtocols = 0;
if (WSCEnumProtocols(NULL, ProtocolInfo, &ProtocolInfoSize,&ErrorCode) == SOCKET_ERROR && ErrorCode != WSAENOBUFS)
{
printf("First WSCEnumProtocols failed %d/n", ErrorCode);
return(FALSE);
}
if ((ProtocolInfo = (LPWSAPROTOCOL_INFOW)
GlobalAlloc(GPTR, ProtocolInfoSize)) == NULL)
{
printf("Cannot enumerate Protocols %d/n", GetLastError());
return(FALSE);
}
if ((TotalProtocols = WSCEnumProtocols(NULL
, ProtocolInfo, &ProtocolInfoSize, &ErrorCode)) == SOCKET_ERROR)
{
printf("Second WSCEnumProtocols failed %d/n", ErrorCode);
return(FALSE);
}
printf("Found %d protocols/n",TotalProtocols);
return(TRUE);
}
void FreeProviders(void)
{
GlobalFree(ProtocolInfo);
}
BOOL GetHookProvider(IN WSAPROTOCOL_INFOW *pProtocolInfo, OUT TCHAR* sPathName,OUT WSAPROTOCOL_INFOW *pNextProtocolInfo)
{
if(pProtocolInfo->ProtocolChain.ChainLen <= 1)
return FALSE;
GetProviders();
__try
{
for(int i = pProtocolInfo->ProtocolChain.ChainLen - 1; i > 0; i--)
{
for(int j = 0; j < TotalProtocols; j++)
{
if(pProtocolInfo->ProtocolChain.ChainEntries[i] == ProtocolInfo[j].dwCatalogEntryId)
{
INT iErrno, iProviderPathLen = MAX_PATH;
if(WSCGetProviderPath(&ProtocolInfo[j].ProviderId, sPathName, &iProviderPathLen, &iErrno) == SOCKET_ERROR)
return FALSE;
if (!ExpandEnvironmentStrings(sPathName, sPathName, MAX_PATH))
return FALSE;
memcpy(pNextProtocolInfo, pProtocolInfo, sizeof(WSAPROTOCOL_INFOW));
return TRUE;
}
}
}
}
__finally
{
FreeProviders();
}
return FALSE;
}
SOCKET WSPAPI WSPSocket(
int af,
int type,
int protocol,
LPWSAPROTOCOL_INFOW lpProtocolInfo,
GROUP g,
DWORD dwFlags,
LPINT lpErrno
)
{
OutputDebugString(_T("WSPSocket/n"));
return NextProcTable.lpWSPSocket(
af, type, protocol, lpProtocolInfo, g, dwFlags, lpErrno);
}
int WSPAPI WSPBind(
SOCKET s,
const struct sockaddr FAR * name,
int namelen,
LPINT lpErrno
)
{
OutputDebugString(_T("WSPBind/n"));
return NextProcTable.lpWSPBind(s,name,namelen,lpErrno);
}
int WSPAPI WSPCleanup(LPINT lpErrno)
{
OutputDebugString(_T("WSPCleanup/n"));
return NextProcTable.lpWSPCleanup(lpErrno);
}
int WSPAPI WSPClosesocket(SOCKET s,LPINT lpErrno)
{
OutputDebugString(_T("WSPClosesocket/n"));
return NextProcTable.lpWSPCloseSocket(s,lpErrno);
}
int WSPAPI WSPConnect(
SOCKET s,
const struct sockaddr FAR * name,
int namelen,
LPWSABUF lpCallerData,
LPWSABUF lpCalleeData,
LPQOS lpSQOS,
LPQOS lpGQOS,
LPINT lpErrno
)
{
OutputDebugString(_T("WSPConnect/n"));
return NextProcTable.lpWSPConnect(s,name,namelen,lpCallerData,lpCalleeData,lpSQOS,lpGQOS,lpErrno);
}
int WSPAPI WSPGetPeerName(
SOCKET s,
struct sockaddr FAR * name,
LPINT namelen,
LPINT lpErrno
)
{
OutputDebugString(_T("WSPGetPeerName/n"));
return NextProcTable.lpWSPGetPeerName(s,name,namelen,lpErrno);
}
int WSPAPI WSPGetSockName(
SOCKET s,
struct sockaddr FAR * name,
LPINT namelen,
LPINT lpErrno
)
{
OutputDebugString(_T("WSPGetSockName/n"));
return NextProcTable.lpWSPGetSockName(s,name,namelen,lpErrno);
}
int WSPAPI WSPListen(
SOCKET s,
int backlog,
LPINT lpErrno
)
{
OutputDebugString(_T("WSPListen/n"));
return NextProcTable.lpWSPListen(s,backlog,lpErrno);
}
int WSPAPI WSPRecv(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno
)
{
OutputDebugString(_T("WSPRecv/n"));
return NextProcTable.lpWSPRecv(s,lpBuffers,dwBufferCount,lpNumberOfBytesRecvd,lpFlags,lpOverlapped,
lpCompletionRoutine,lpThreadId,lpErrno);
}
int WSPAPI WSPRecvFrom(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags,
struct sockaddr FAR * lpFrom,
LPINT lpFromlen,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno
)
{
int ret = NextProcTable.lpWSPRecvFrom(s,lpBuffers,dwBufferCount,lpNumberOfBytesRecvd,lpFlags,lpFrom,
lpFromlen,lpOverlapped,lpCompletionRoutine,lpThreadId,lpErrno);
struct sockaddr_in* pAddr = (struct sockaddr_in*)lpFrom;
char szTemp[256];
sprintf(szTemp,"WSPRecvFrom %s:%d/n",inet_ntoa(pAddr->sin_addr),ntohs(pAddr->sin_port));
WriteLog(szTemp);
OutputDebugString(_T("WSPRecvFrom/n"));
return ret;
}
int WSPAPI WSPSend(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno
)
{
OutputDebugString(_T("WSPSend/n"));
return NextProcTable.lpWSPSend(s,lpBuffers,dwBufferCount,lpNumberOfBytesSent,dwFlags,
lpOverlapped,lpCompletionRoutine,lpThreadId,lpErrno);
}
int WSPAPI WSPSendTo(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
const struct sockaddr FAR * lpTo,
int iTolen,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno
)
{
struct sockaddr_in* pAddr = (struct sockaddr_in*)lpTo;
char szTemp[256];
sprintf(szTemp,"WSPSendTo %s:%d/n",inet_ntoa(pAddr->sin_addr),ntohs(pAddr->sin_port));
WriteLog(szTemp);
OutputDebugString(_T("WSPSendTo/n"));
return NextProcTable.lpWSPSendTo(s,lpBuffers,dwBufferCount,lpNumberOfBytesSent,dwFlags,
lpTo,iTolen,lpOverlapped,lpCompletionRoutine,lpThreadId,lpErrno);
}
int WSPAPI WSPSetSockOpt(
SOCKET s,
int level,
int optname,
const char FAR * optval,
int optlen,
LPINT lpErrno
)
{
OutputDebugString(_T("WSPSetSockOpt/n"));
return NextProcTable.lpWSPSetSockOpt(s,level,optname,optval,optlen,lpErrno);
}
int WSPAPI WSPShutdown(
SOCKET s,
int how,
LPINT lpErrno
)
{
OutputDebugString(_T("WSPShutdown/n"));
return NextProcTable.lpWSPShutdown(s,how,lpErrno);
}
int WSPAPI WSPStartup(
WORD wVersionRequested,
LPWSPDATA lpWSPData,
LPWSAPROTOCOL_INFOW lpProtocolInfo,
WSPUPCALLTABLE upcallTable,
LPWSPPROC_TABLE lpProcTable
)
{
OutputDebugString(_T("WSPStartup/n"));
TCHAR sLibraryPath[MAX_PATH];
LPWSPSTARTUP WSPStartupFunc = NULL;
HMODULE hLibraryHandle = NULL;
INT ErrorCode = 0;
WSAPROTOCOL_INFOW NextProtocolInfo;
if (!GetHookProvider(lpProtocolInfo, sLibraryPath, &NextProtocolInfo)|| (hLibraryHandle = LoadLibrary(sLibraryPath)) == NULL
|| (WSPStartupFunc = (LPWSPSTARTUP)GetProcAddress(hLibraryHandle, "WSPStartup")) == NULL
)
return WSAEPROVIDERFAILEDINIT;
if ((ErrorCode = WSPStartupFunc(wVersionRequested, lpWSPData,
&NextProtocolInfo, upcallTable, lpProcTable)) != ERROR_SUCCESS)
return ErrorCode;
NextProcTable = *lpProcTable;
lpProcTable->lpWSPSocket = WSPSocket;
lpProcTable->lpWSPSocket = WSPSocket;
// lpProcTable->lpWSPBind = WSPBind;
// lpProcTable->lpWSPSetSockOpt = WSPSetSockOpt;
// lpProcTable->lpWSPListen = WSPListen;
// lpProcTable->lpWSPConnect = WSPConnect;
lpProcTable->lpWSPRecv = WSPRecv;
lpProcTable->lpWSPRecvFrom = WSPRecvFrom;
lpProcTable->lpWSPSend = WSPSend;
lpProcTable->lpWSPSendTo = WSPSendTo;
// lpProcTable->lpWSPGetPeerName = WSPGetPeerName;
// lpProcTable->lpWSPGetSockName = WSPGetSockName;
lpProcTable->lpWSPShutdown = WSPShutdown;
lpProcTable->lpWSPCleanup = WSPCleanup;
lpProcTable->lpWSPCloseSocket = WSPClosesocket;
//
// 创建总代理SOCKET
//
if (g_UdpProxy == INVALID_SOCKET)
{
g_UdpProxy = lpProcTable->lpWSPSocket(AF_INET,SOCK_DGRAM,IPPROTO_UDP,lpProtocolInfo,0,WSA_FLAG_OVERLAPPED,&nErrorNo);
if (g_UdpProxy == INVALID_SOCKET)
{
sprintf(szLog,"Create UDP Proxy failed! %d",WSAGetLastError());
WriteLog(szLog);
}
else
{
WriteLog("Create UDP Proxy success!");
}
}
return 0;
}