截获WINSOCKET <br>福州大学自动化研究所 <br>林毅 <br> TCP/IP协议是目前各网络操作系统主要的通讯协议,也是 INTERNET的通讯协议,WIN95/NT平台提供了TCP/IP协议的实现函数库WINSOCKET(WSOCKET.DLL)动态库,因而可以利用WINSOCKET 编写基于TCP/IP协议的应用系统。(UNIX平台提供BSD-SOCKET) <br><br> 在实际应用开发中,我们总希望在调用正常的WINSOCKET接口函数时,先进行各自的特殊处理,如对于开发基于WIN95/NT平台的VPN客户端软件时,我们希望应用信息在发送前即在调用SEND函数时,先对信息进行加密后再发送。又如有的应用系统调用CONNECT 函数进行连接请求,我们需要截获此调用,插入我们自己的身份认证。模块,只有合法的身份,才可以调用正常的CONNECT函数,而非法的身份则不进行CONNECT调用。因而需要开发一种截获WINSOCKET函数调用的方法(INTERCEPT WINSOCKET),使在进行WINSOCK正常函数调用之前,使其先调用我们的身份认证模块,加解密模块。由于在WIN95/NT平台 WINSOCKET是以动态连接库(DLL)形式提供的,应而使各种应用系统在进行TCP/IP协议通讯时,无须任何修改,就先调用我们的应用模块,实现应用的透明性。 <br><br> 一般要截获动态库(DLL)的调用,可以用HOOK(钩子技术),或外包DLL 技术,即将原来的DLL库改名(如将WINSOCK库WSOCK32.DLL改为A.DLL),新建一个DLL库,WSOCKET32.DLL,在新的DLL库中调用旧的DLL库。 <br><br> 以下给出了利用VISUAL C++实现的截获WINSOCK的应用程序的源代码。 <br><br><br>WSOCK32.CPP <br><br>#include <windows.h> <br>#include <stdio.h> <br>void abc(char *p){FILE *fp=fopen("c://z.txt","a+");fprintf(fp,"%s/n",p);fclose(fp);} <br>//日志文件 <br>//必须输出与原WSOCK32.DLL库同样的函数。 <br><br>HMODULE i;char aa[1000];FARPROC a;DWORD d; <br><br>int (__stdcall *getsockopt1)(SOCKET ,int ,int ,char * , int * ); <br>u_short (__stdcall *ntohs1)(u_short ); <br>struct hostent * (__stdcall *gethostbyname1)(const char FAR * ); <br>int (__stdcall *getsockname1)(SOCKET ,struct sockaddr *,int * ); <br>int (__stdcall *bind1)(SOCKET ,const struct sockaddr *,int ); <br>u_long (__stdcall *htonl1)(u_long); <br>char * (__stdcall *inet_ntoa1)(struct in_addr); <br>int (__stdcall *WsControl1)(int ,int ,int ,int ,int ,int ); <br>unsigned long (__stdcall *inet_addr1)(const char FAR * ); <br>int (__stdcall *__WSAFDIsSet1)(SOCKET,fd_set FAR *); <br>int (__stdcall *WSAGetLastError1)(); <br>int (__stdcall *recv1)(SOCKET ,char FAR * ,int ,int ); <br>int (__stdcall *send1)(SOCKET ,const char * ,int ,int); <br>int (__stdcall *connect1)(SOCKET,const struct sockaddr *,int); <br>int (__stdcall *closesockinfo1)(int ); <br>int (__stdcall *NPLoadNameSpaces1)(int ,int ,int ); <br>int (__stdcall *closesocket1)(SOCKET ); <br>int (__stdcall *select1)(int ,fd_set FAR *,fd_set FAR *,fd_set FAR *,const struct timeval FAR * ); <br>HANDLE (__stdcall *WSAAsyncGetHostByName1)(HWND ,u_int ,const char FAR * , char FAR * ,int ); <br>int (__stdcall *ioctlsocket1)(SOCKET ,long ,u_long FAR *); <br>int (__stdcall *setsockopt1)(SOCKET ,int ,int ,const char * ,int ); <br>int (__stdcall *WSAAsyncSelect1)(SOCKET,HWND ,u_int,long); <br>SOCKET (__stdcall *socket1)(int ,int,int); <br>u_short (__stdcall *htons1)(u_short); <br>int (__stdcall *WSAStartup1)(WORD,LPWSADATA); <br>int (__stdcall *WSACleanup1)(); <br><br>int PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData) <br>{ <br>abc("WSAStartup"); <br>//记日志,当然也可以是您的模块 <br>i=LoadLibrary("c://windows//system//wsock32.aaa"); <br>//装载原动态库 <br>a=GetProcAddress(i,"WSAStartup"); <br>WSAStartup1=(int (_stdcall *)(WORD,LPWSADATA))a; <br>return WSAStartup1(wVersionRequired,lpWSAData); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL FAR WSACleanup(void) <br>{ <br>abc("WSACleanup"); <br>//记日志 <br>a=GetProcAddress(i,"WSACleanup"); <br>//取得原同名函数地址 <br>WSACleanup1=(int (_stdcall *)())a; <br>return WSACleanup1(); <br>//执行真正的处理 <br>} <br>u_short PASCAL FAR htons (u_short hostshort) <br>{ <br>abc("htons"); <br>a=GetProcAddress(i,"htons"); <br>htons1=(u_short (_stdcall *)(u_short))a; <br>return htons1(hostshort); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>SOCKET PASCAL FAR socket (int af, int type, int protocol) <br>{ <br>abc("socket"); <br>a=GetProcAddress(i,"socket"); <br>socket1=(SOCKET (_stdcall *)(int ,int,int))a; <br>return socket1(af,type,protocol); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL FAR WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg,long lEvent) <br>{ <br>abc("WSAAsyncSelect"); <br>a=GetProcAddress(i,"WSAAsyncSelect"); <br>WSAAsyncSelect1=(int (_stdcall *)(SOCKET,HWND ,u_int,long ))a; <br>return WSAAsyncSelect1(s,hWnd,wMsg,lEvent); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL FAR setsockopt(SOCKET s,int level,int optname,const char * optval,int optlen) <br>{ <br>abc("setsockopt"); <br>a=GetProcAddress(i,"setsockopt"); <br>setsockopt1=(int (_stdcall *)(SOCKET ,int ,int ,const char * ,int ))a; <br>return setsockopt1(s,level,optname,optval,optlen); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL FAR ioctlsocket(SOCKET s, long cmd, u_long FAR *argp) <br>{ <br>abc("ioctlsocket"); <br>a=GetProcAddress(i,"ioctlsocket"); <br>ioctlsocket1=(int (_stdcall *)(SOCKET ,long ,u_long FAR *))a; <br>return ioctlsocket1(s,cmd,argp); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>HANDLE PASCAL FAR WSAAsyncGetHostByName(HWND hWnd, u_int wMsg,const char FAR * name, char FAR * buf,int buflen) <br>{ <br>abc("WSAAsyncGetHostByName"); <br>a=GetProcAddress(i,"WSAAsyncGetHostByName"); <br>WSAAsyncGetHostByName1=(HANDLE (_stdcall *)(HWND ,u_int ,const char FAR * , char FAR * ,int ))a; <br>return WSAAsyncGetHostByName1(hWnd,wMsg,name,buf,buflen); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL FAR select(int nfds, fd_set FAR *readfds, fd_set FAR *writefds,fd_set FAR *exceptfds, const struct timeval FAR *timeout) <br>{ <br>abc("select"); <br>a=GetProcAddress(i,"select"); <br>select1=(int (_stdcall *)(int ,fd_set FAR *,fd_set FAR *,fd_set FAR *,const struct timeval FAR *))a; <br>return select1(nfds,readfds,writefds,exceptfds,timeout); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL FAR closesocket(SOCKET s) <br>{ <br>abc("closesocket"); <br>a=GetProcAddress(i,"closesocket"); <br>closesocket1=(int (_stdcall *)(SOCKET ))a; <br>return closesocket1(s); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL FAR NPLoadNameSpaces(int p,int q,int r) <br>{ <br>abc("NPLoadNameSpaces"); <br>a=GetProcAddress(i,"NPLoadNameSpaces"); <br>NPLoadNameSpaces1=(int (_stdcall *)(int ,int ,int ))a; <br>return NPLoadNameSpaces1(p,q,r); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL FAR closesockinfo(int p) <br>{ <br>abc("closesockinfo"); <br>a=GetProcAddress(i,"closesockinfo"); <br>closesockinfo1=(int (_stdcall *)(int))a; <br>return closesockinfo1(p); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL FAR connect(SOCKET s,const struct sockaddr *name, int namelen) <br>{ <br>abc("connect"); <br>a=GetProcAddress(i,"connect"); <br>connect1=(int (_stdcall *)(SOCKET ,const struct sockaddr *,int ))a; <br>return connect1(s,name,namelen); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL FAR WSAGetLastError(void) <br>{ <br>a=GetProcAddress(i,"WSAGetLastError"); <br>WSAGetLastError1=(int (_stdcall *)())a; <br>d=WSAGetLastError1(); <br>sprintf(aa,"WSAGetLastError %d",d); <br>abc(aa); <br>return d; <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL FAR send(SOCKET s,const char * buf,int len,int flags) <br>{ <br>abc("send"); <br>a=GetProcAddress(i,"send"); <br>send1=(int (_stdcall *)(SOCKET ,const char * ,int ,int ))a; <br>return send1(s,buf,len,flags); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL FAR recv(SOCKET s, char FAR * buf, int len, int flags) <br>{ <br>abc("recv"); <br>a=GetProcAddress(i,"recv"); <br>recv1=(int (_stdcall *)(SOCKET ,char FAR * ,int ,int ))a; <br>return recv1(s, buf, len, flags); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL FAR __WSAFDIsSet(SOCKET p,fd_set FAR *q) <br>{ <br>abc("__WSAFDIsSet"); <br>a=GetProcAddress(i,"__WSAFDIsSet"); <br>__WSAFDIsSet1=(int (_stdcall *)(SOCKET,fd_set FAR *))a; <br>return __WSAFDIsSet1(p,q); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>unsigned long PASCAL inet_addr(const char FAR * cp) <br>{ <br>abc("inet_addr"); <br>a=GetProcAddress(i,"inet_addr"); <br>inet_addr1=(unsigned long (_stdcall *)(const char FAR * ))a; <br>return inet_addr1(cp); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL WsControl(int p,int q,int r,int s,int t,int u) <br>{ <br>abc("WsControl"); <br>a=GetProcAddress(i,"WsControl"); <br>WsControl1=(int (_stdcall *)(int ,int ,int ,int ,int ,int ))a; <br>return WsControl1(p,q,r,s,t,u); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>char * PASCAL inet_ntoa (struct in_addr in) <br>{ <br>abc("inet_ntoa"); <br>a=GetProcAddress(i,"inet_ntoa"); <br>inet_ntoa1=(char * (_stdcall *)(struct in_addr))a; <br>return inet_ntoa1(in); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>u_long PASCAL FAR htonl(u_long hostlong) <br>{ <br>abc("htonl"); <br>a=GetProcAddress(i,"htonl"); <br>htonl1=(u_long (_stdcall *)(u_long))a; <br>return htonl1(hostlong); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL bind(SOCKET s, const struct sockaddr FAR *addr, int namelen) <br>{ <br>abc("bind"); <br>a=GetProcAddress(i,"bind"); <br>bind1=(int (_stdcall *)(SOCKET ,const struct sockaddr *,int ))a; <br>return bind1(s,addr,namelen); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL getsockname(SOCKET s, struct sockaddr *name,int * namelen) <br>{ <br>abc("getsockname"); <br>a=GetProcAddress(i,"getsockname"); <br>getsockname1=(int (_stdcall *)(SOCKET ,struct sockaddr *,int * ))a; <br>return getsockname1(s,name,namelen); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>struct hostent * PASCAL FAR gethostbyname(const char FAR * name) <br>{ <br>abc("gethostbyname"); <br>a=GetProcAddress(i,"gethostbyname"); <br>gethostbyname1=(struct hostent * (_stdcall *)(const char FAR * ))a; <br>return gethostbyname1(name); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>u_short PASCAL ntohs(u_short netshort) <br>{ <br>abc("ntohs"); <br>a=GetProcAddress(i,"ntohs"); <br>ntohs1=(u_short (_stdcall *)(u_short))a; <br>return ntohs1(netshort); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br>int PASCAL getsockopt(SOCKET s,int level,int optname,char * optval, int *optlen) <br>{ <br>abc("getsockopt"); <br>a=GetProcAddress(i,"getsockopt"); <br>getsockopt1=(int (_stdcall *)(SOCKET ,int ,int ,char * , int *))a; <br>return getsockopt1(s,level,optname,optval,optlen); <br>//取得原同名函数地址 <br>//执行真正的处理 <br><br>} <br><br><br><br>SOCKET PASCAL FAR accept (SOCKET s, struct sockaddr FAR *addr,int FAR *addrlen){abc("1");return 0;} <br>int PASCAL FAR getpeername (SOCKET s, struct sockaddr FAR *name,int FAR * namelen){abc("5");return 0;} <br>int PASCAL FAR listen (SOCKET s, int backlog){abc("13");return 0;} <br>u_long PASCAL FAR ntohl (u_long netlong){abc("14");return 0;} <br>int PASCAL FAR recvfrom (SOCKET s, char FAR * buf, int len, int flags,struct sockaddr FAR *from, int FAR * fromlen){abc("17");return 0;} <br>int PASCAL FAR sendto (SOCKET s, const char FAR * buf, int len, int flags,const struct sockaddr FAR *to, int tolen){abc("20");return 0;} <br>int PASCAL FAR shutdown (SOCKET s, int how){abc("22");return 0;} <br>struct hostent FAR * PASCAL FAR gethostbyaddr(const char FAR * addr,int len, int type){abc("24");return 0;} <br>struct protoent FAR * PASCAL FAR getprotobynumber(int proto){abc("26");return 0;} <br>struct protoent FAR * PASCAL FAR getprotobyname(const char FAR * name){abc("27");return 0;} <br>struct servent FAR * PASCAL FAR getservbyport(int port, const char FAR * proto){abc("28");return 0;} <br>struct servent FAR * PASCAL FAR getservbyname(const char FAR * name,const char FAR * proto){abc("29");return 0;} <br>int PASCAL FAR gethostname (char FAR * name, int namelen){abc("30");return 0;} <br>HANDLE PASCAL FAR WSAAsyncGetServByName(HWND hWnd, u_int wMsg,const char FAR * name,const char FAR * proto,char FAR * buf, int buflen){abc("32");return 0;} <br>HANDLE PASCAL FAR WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, int port,const char FAR * proto, char FAR * buf,int buflen){abc("33");return 0;} <br>HANDLE PASCAL FAR WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg,const char FAR * name, char FAR * buf,int buflen){abc("34");return 0;} <br>HANDLE PASCAL FAR WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg,int number, char FAR * buf,int buflen){abc("35");return 0;} <br>HANDLE PASCAL FAR WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg,const char FAR * addr, int len, int type,char FAR * buf, int buflen){abc("37");return 0;} <br>int PASCAL FAR WSACancelAsyncRequest(HANDLE hAsyncTaskHandle){abc("38");return 0;} <br>FARPROC PASCAL FAR WSASetBlockingHook(FARPROC lpBlockFunc){abc("39");return 0;} <br>int PASCAL FAR WSAUnhookBlockingHook(void){abc("40");return 0;} <br>void PASCAL FAR WSASetLastError(int iError){abc("41");} <br>int PASCAL FAR WSACancelBlockingCall(void){abc("43");return 0;} <br>BOOL PASCAL FAR WSAIsBlocking(void){abc("44");return 0;} <br>int PASCAL FAR WSARecvEx (SOCKET s, char FAR * buf, int len, int FAR *flags){abc("47");return 0;} <br>BOOL PASCAL FAR TransmitFile (IN SOCKET hSocket,IN HANDLE hFile,IN DWORD nNumberOfBytesToWrite,IN DWORD nNumberOfBytesPerSend,IN LPOVERLAPPED lpOverlapped,IN void *lpTransmitBuffers,IN DWORD dwReserved){abc("48");return 0;} <br><br>int PASCAL FAR Arecv (){abc("a3");return 0;} <br>int PASCAL FAR Asend (){abc("a4");return 0;} <br>int PASCAL FAR WSHEnumProtocols(){abc("a5");return 0;} <br>int PASCAL FAR inet_network (){abc("a6");return 0;} <br>int PASCAL FAR getnetbyname (){abc("a7");return 0;} <br>int PASCAL FAR rcmd (){abc("a8");return 0;} <br>int PASCAL FAR rexec (){abc("a9");return 0;} <br>int PASCAL FAR rresvport (){abc("a10");return 0;} <br>int PASCAL FAR sethostname (){abc("a11");return 0;} <br>int PASCAL FAR dn_expand (){abc("a12");return 0;} <br>int PASCAL FAR s_perror (){abc("a13");return 0;} <br>int PASCAL FAR GetAddressByNameA (){abc("a14");return 0;} <br>int PASCAL FAR GetAddressByNameW (){abc("a15");return 0;} <br>int PASCAL FAR EnumProtocolsA (){abc("a16");return 0;} <br>int PASCAL FAR EnumProtocolsW (){abc("a17");return 0;} <br>int PASCAL FAR GetTypeByNameA (){abc("a18");return 0;} <br>int PASCAL FAR GetTypeByNameW (){abc("a19");return 0;} <br>int PASCAL FAR GetNameByTypeA (){abc("a20");return 0;} <br>int PASCAL FAR GetNameByTypeW (){abc("a21");return 0;} <br>int PASCAL FAR SetServiceA (){abc("a22");return 0;} <br>int PASCAL FAR SetServiceW (){abc("a23");return 0;} <br>int PASCAL FAR GetServiceA (){abc("a24");return 0;} <br>int PASCAL FAR GetServiceW (){abc("a25");return 0;} <br><br><br>//BOOL PASCAL FAR AcceptEx (IN SOCKET sListenSocket,IN SOCKET sAcceptSocket,IN PVOID lpOutputBuffer,IN DWORD dwReceiveDataLength,IN DWORD dwLocalAddressLength,IN DWORD dwRemoteAddressLength,OUT LPDWORD lpdwBytesReceived,IN LPOVERLAPPED lpOverlapped){abc("1");return 0;} <br>//VOID PASCAL FAR GetAcceptExSockaddrs (IN PVOID lpOutputBuffer,IN DWORD dwReceiveDataLength,IN DWORD dwLocalAddressLength,IN DWORD dwRemoteAddressLength,OUT struct sockaddr **LocalSockaddr,OUT LPINT LocalSockaddrLength,OUT struct sockaddr **RemoteSockaddr,OUT LPINT RemoteSockaddrLength){abc("1");return 0;} <br><br>//在WSOCK32.DEF中定义输出函数 <br><br>msock32.def <br>LIBRARY "wsock32" <br>EXPORTS <br> accept @1 <br> bind @2 <br> closesocket @3 <br> connect @4 <br> getpeername @5 <br> getsockname @6 <br> getsockopt @7 <br> htonl @8 <br> htons @9 <br> inet_addr @10 <br> inet_ntoa @11 <br> ioctlsocket @12 <br> listen @13 <br> ntohl @14 <br> ntohs @15 <br> recv @16 <br> recvfrom @17 <br> select @18 <br> send @19 <br> sendto @20 <br> setsockopt @21 <br> shutdown @22 <br> socket @23 <br> gethostbyaddr @51 <br> gethostbyname @52 <br> getprotobyname @53 <br> getprotobynumber @54 <br> getservbyname @55 <br> getservbyport @56 <br> gethostname @57 <br> WSAAsyncSelect @101 <br> WSAAsyncGetHostByAddr @102 <br> WSAAsyncGetHostByName @103 <br> WSAAsyncGetProtoByNumber @104 <br> WSAAsyncGetProtoByName @105 <br> WSAAsyncGetServByPort @106 <br> WSAAsyncGetServByName @107 <br> WSACancelAsyncRequest @108 <br> WSASetBlockingHook @109 <br> WSAUnhookBlockingHook @110 <br> WSAGetLastError @111 <br> WSASetLastError @112 <br> WSACancelBlockingCall @113 <br> WSAIsBlocking @114 <br> WSAStartup @115 <br> WSACleanup @116 <br> __WSAFDIsSet @151 <br>WsControl @1001 <br>closesockinfo @1002 <br>Arecv @1003 <br>Asend @1004 <br>WSHEnumProtocols @1005 <br>inet_network @1100 <br>getnetbyname @1101 <br>rcmd @1102 <br>rexec @1103 <br>rresvport @1104 <br>sethostname @1105 <br>dn_expand @1106 <br> WSARecvEx @1107 <br>s_perror @1108 <br>GetAddressByNameA @1109 <br>GetAddressByNameW @1110 <br>EnumProtocolsA @1111 <br>EnumProtocolsW @1112 <br>GetTypeByNameA @1113 <br>GetTypeByNameW @1114 <br>GetNameByTypeA @1115 <br>GetNameByTypeW @1116 <br>SetServiceA @1117 <br>SetServiceW @1118 <br>GetServiceA @1119 <br>GetServiceW @1120 <br>NPLoadNameSpaces @1130 <br> TransmitFile @1140 <br><br><br> 先将WINSOCK库WSOCK32.DLL该名为AAA.DLL,WSOCK32.AAA <br><br> 利用VISUAL C++创建一个DLL项目 WSOCK32.DLL <br><br> 目前加入的模块为一个日志处理。 <br>特别感谢『九头鸟』自发编辑『 dy 』| | <br> <br> <br> <br> <br> <br>