利用SPI编写类似sockscap的代理工具

来源:互联网 发布:朝鲜有多穷 知乎 编辑:程序博客网 时间:2024/06/06 02:47

转自:http://blog.csdn.net/ze_tsin/article/details/6376831

SPI的出现其实就是微软为了方便程序员对网络API的各种HOOK,从而省去一些麻烦,然而相对的也会增加不少问题。对于SPI中的LSP这种分层的结构,可以很好的使用强盗手法将自己当作老大放在最上层,但是,如果有其他程序也使用同样的手法,那么就会产生冲突了。

好吧进入正题。。。

 

一、LSP的安装,先抛开socks代理不说

1、构造自己的LSP,并安装之;

2、遍历已有 服务提供者,找到刚安装的LSP入口ID;

3、构造自己的协议链,并安装之;

4、对所有协议链进行排序,并将我们的协议链放到最上面。

 

二、LSP的编写

主要操作都在WSPStartup中,其他WSP函数就是对原函数的HOOK,详情看下面代码。

 

MSDN有完整LSP代码的下载:

ftp://ftp.microsoft.com/bussys/WinSock/winsock2/layered.zip

 

同时,网上也有一些源代码,与MSDN代码相比,基本一样,只是在LSP安装的第一步有所不同,MSDN代码是手工构造LSP,而网上许多代码都是通过拷贝系统已有LSP进行对自己的LSP构造。

 

下面代码来自网上:

 

 


 

 

INST_LSP.Cpp

[cpp] view plaincopy
  1. #define UNICODE  
  2. #define _UNICODE  
  3. #include <Ws2spi.h>  
  4. #include <Sporder.h>        // 定义了WSCWriteProviderOrder函数  
  5. #include <windows.h>  
  6. #include <stdio.h>  
  7. #pragma comment(lib, "Ws2_32.lib")  
  8. #pragma comment(lib, "Rpcrt4.lib")    // 实现了UuidCreate函数  
  9. // 要安装的LSP的硬编码,在移除的时候还要使用它  
  10. GUID ProviderGuid = {0xd3c21122, 0x85e1, 0x48f3,   
  11.                             {0x9a,0xb6,0x23,0xd9,0x0c,0x73,0x07,0xef}};  
  12. LPWSAPROTOCOL_INFOW GetProvider(LPINT lpnTotalProtocols)  
  13. {  
  14.     DWORD dwSize = 0;  
  15.     int nError;  
  16.     LPWSAPROTOCOL_INFOW pProtoInfo = NULL;  
  17.       
  18.     // 取得需要的长度  
  19.     if(::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError) == SOCKET_ERROR)  
  20.     {  
  21.         if(nError != WSAENOBUFS)  
  22.             return NULL;  
  23.     }  
  24.       
  25.     pProtoInfo = (LPWSAPROTOCOL_INFOW)::GlobalAlloc(GPTR, dwSize);  
  26.     *lpnTotalProtocols = ::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError);  
  27.     return pProtoInfo;  
  28. }  
  29. void FreeProvider(LPWSAPROTOCOL_INFOW pProtoInfo)  
  30. {  
  31.     ::GlobalFree(pProtoInfo);  
  32. }  
  33. BOOL InstallProvider(WCHAR *pwszPathName)  
  34. {  
  35.     WCHAR wszLSPName[] = L"ZetsinLSP";  
  36.     LPWSAPROTOCOL_INFOW pProtoInfo;  
  37.     int nProtocols;  
  38.     WSAPROTOCOL_INFOW OriginalProtocolInfo[3];  
  39.     DWORD             dwOrigCatalogId[3];  
  40.     int nArrayCount = 0;  
  41.     DWORD dwLayeredCatalogId;        // 我们分层协议的目录ID号  
  42.     int nError;  
  43.       
  44.     // 找到我们的下层协议,将信息放入数组中  
  45.     // 枚举所有服务程序提供者  
  46.     pProtoInfo = GetProvider(&nProtocols);  
  47.     BOOL bFindUdp = FALSE;  
  48.     BOOL bFindTcp = FALSE;  
  49.     BOOL bFindRaw = FALSE;  
  50.     for(int i=0; i<nProtocols; i++)  
  51.     {  
  52.         if(pProtoInfo[i].iAddressFamily == AF_INET)  
  53.         {  
  54.         if(!bFindUdp && pProtoInfo[i].iProtocol == IPPROTO_UDP)  
  55.             {  
  56.                 memcpy(&OriginalProtocolInfo[nArrayCount], &pProtoInfo[i], sizeof(WSAPROTOCOL_INFOW));  
  57.                 OriginalProtocolInfo[nArrayCount].dwServiceFlags1 =   
  58.                     OriginalProtocolInfo[nArrayCount].dwServiceFlags1 & (~XP1_IFS_HANDLES);   
  59.                   
  60.                 dwOrigCatalogId[nArrayCount++] = pProtoInfo[i].dwCatalogEntryId;  
  61.                 bFindUdp = TRUE;  
  62.             }  
  63.         if(!bFindTcp && pProtoInfo[i].iProtocol == IPPROTO_TCP)  
  64.             {  
  65.                 memcpy(&OriginalProtocolInfo[nArrayCount], &pProtoInfo[i], sizeof(WSAPROTOCOL_INFOW));  
  66.                 OriginalProtocolInfo[nArrayCount].dwServiceFlags1 =   
  67.                     OriginalProtocolInfo[nArrayCount].dwServiceFlags1 & (~XP1_IFS_HANDLES);   
  68.                   
  69.                 dwOrigCatalogId[nArrayCount++] = pProtoInfo[i].dwCatalogEntryId;  
  70.                 bFindTcp = TRUE;  
  71.             }   
  72.         if(!bFindRaw && pProtoInfo[i].iProtocol == IPPROTO_IP)  
  73.             {  
  74.                 memcpy(&OriginalProtocolInfo[nArrayCount], &pProtoInfo[i], sizeof(WSAPROTOCOL_INFOW));  
  75.                 OriginalProtocolInfo[nArrayCount].dwServiceFlags1 =   
  76.                     OriginalProtocolInfo[nArrayCount].dwServiceFlags1 & (~XP1_IFS_HANDLES);   
  77.                   
  78.                 dwOrigCatalogId[nArrayCount++] = pProtoInfo[i].dwCatalogEntryId;  
  79.                 bFindRaw = TRUE;  
  80.             }  
  81.         }  
  82.     }  
  83.     // 安装我们的分层协议,获取一个dwLayeredCatalogId  
  84.     // 随便找一个下层协议的结构复制过来即可  
  85.     WSAPROTOCOL_INFOW LayeredProtocolInfo;  
  86.     memcpy(&LayeredProtocolInfo, &OriginalProtocolInfo[0], sizeof(WSAPROTOCOL_INFOW));  
  87.     // 修改协议名称,类型,设置PFL_HIDDEN标志  
  88.     wcscpy_s(LayeredProtocolInfo.szProtocol, wszLSPName);  
  89.     LayeredProtocolInfo.ProtocolChain.ChainLen = LAYERED_PROTOCOL; // 0;  
  90.     LayeredProtocolInfo.dwProviderFlags |= PFL_HIDDEN;  
  91.     // 安装  
  92.     if(::WSCInstallProvider(&ProviderGuid,   
  93.                     pwszPathName, &LayeredProtocolInfo, 1, &nError) == SOCKET_ERROR)  
  94.     {  
  95.         printf("%d", nError);  
  96.         return FALSE;  
  97.     }  
  98.     // 重新枚举协议,获取分层协议的目录ID号  
  99.     FreeProvider(pProtoInfo);  
  100.     pProtoInfo = GetProvider(&nProtocols);  
  101.     for(int i=0; i<nProtocols; i++)  
  102.     {  
  103.         if(memcmp(&pProtoInfo[i].ProviderId, &ProviderGuid, sizeof(ProviderGuid)) == 0)  
  104.         {  
  105.             dwLayeredCatalogId = pProtoInfo[i].dwCatalogEntryId;  
  106.             break;  
  107.         }  
  108.     }  
  109.     // 安装协议链  
  110.     // 修改协议名称,类型  
  111.     WCHAR wszChainName[WSAPROTOCOL_LEN + 1];  
  112.     for(int i=0; i<nArrayCount; i++)  
  113.     {  
  114.         swprintf(wszChainName, L"%ws over %ws", wszLSPName, OriginalProtocolInfo[i].szProtocol);  
  115.         wcscpy_s(OriginalProtocolInfo[i].szProtocol, wszChainName);  
  116.         if(OriginalProtocolInfo[i].ProtocolChain.ChainLen == 1)  
  117.         {  
  118.             OriginalProtocolInfo[i].ProtocolChain.ChainEntries[1] = dwOrigCatalogId[i];  
  119.         }  
  120.         else  
  121.         {  
  122.             for(int j = OriginalProtocolInfo[i].ProtocolChain.ChainLen; j>0; j--)  
  123.             {  
  124.                 OriginalProtocolInfo[i].ProtocolChain.ChainEntries[j]   
  125.                                     = OriginalProtocolInfo[i].ProtocolChain.ChainEntries[j-1];  
  126.             }  
  127.         }  
  128.         OriginalProtocolInfo[i].ProtocolChain.ChainLen ++;  
  129.         OriginalProtocolInfo[i].ProtocolChain.ChainEntries[0] = dwLayeredCatalogId;      
  130.     }  
  131.     // 获取一个Guid,安装之  
  132.     GUID ProviderChainGuid;  
  133.     if(::UuidCreate(&ProviderChainGuid) == RPC_S_OK)  
  134.     {  
  135.         if(::WSCInstallProvider(&ProviderChainGuid,   
  136.                     pwszPathName, OriginalProtocolInfo, nArrayCount, &nError) == SOCKET_ERROR)  
  137.         {  
  138.             return FALSE;      
  139.         }  
  140.     }  
  141.     else  
  142.         return FALSE;  
  143.     // 重新排序Winsock目录,将我们的协议链提前  
  144.     // 重新枚举安装的协议  
  145.     FreeProvider(pProtoInfo);  
  146.     pProtoInfo = GetProvider(&nProtocols);  
  147.     PDWORD dwIds = (PDWORD)malloc(sizeof(DWORD) * nProtocols);  
  148.     int nIndex = 0;  
  149.     // 添加我们的协议链  
  150.     for(int i=0; i<nProtocols; i++)  
  151.     {  
  152.         if((pProtoInfo[i].ProtocolChain.ChainLen > 1) &&  
  153.                     (pProtoInfo[i].ProtocolChain.ChainEntries[0] == dwLayeredCatalogId))  
  154.             dwIds[nIndex++] = pProtoInfo[i].dwCatalogEntryId;  
  155.     }  
  156.     // 添加其它协议  
  157.     for(int i=0; i<nProtocols; i++)  
  158.     {  
  159.         if((pProtoInfo[i].ProtocolChain.ChainLen <= 1) ||  
  160.                 (pProtoInfo[i].ProtocolChain.ChainEntries[0] != dwLayeredCatalogId))  
  161.             dwIds[nIndex++] = pProtoInfo[i].dwCatalogEntryId;  
  162.     }  
  163.     // 重新排序Winsock目录  
  164.     if((nError = ::WSCWriteProviderOrder(dwIds, nIndex)) != ERROR_SUCCESS)  
  165.     {  
  166.         return FALSE;  
  167.     }  
  168.     FreeProvider(pProtoInfo);  
  169.     return TRUE;  
  170. }  
  171. BOOL RemoveProvider()  
  172. {  
  173.     LPWSAPROTOCOL_INFOW pProtoInfo;  
  174.     int nProtocols;  
  175.     DWORD dwLayeredCatalogId;  
  176.     // 根据Guid取得分层协议的目录ID号  
  177.     pProtoInfo = GetProvider(&nProtocols);  
  178.     int nError;  
  179.     int i;  
  180.     for(i=0; i<nProtocols; i++)  
  181.     {  
  182.         if(memcmp(&ProviderGuid, &pProtoInfo[i].ProviderId, sizeof(ProviderGuid)) == 0)  
  183.         {  
  184.             dwLayeredCatalogId = pProtoInfo[i].dwCatalogEntryId;  
  185.             break;  
  186.         }  
  187.     }  
  188.     if(i < nProtocols)  
  189.     {  
  190.         // 移除协议链  
  191.         for(i=0; i<nProtocols; i++)  
  192.         {  
  193.             if((pProtoInfo[i].ProtocolChain.ChainLen > 1) &&  
  194.                     (pProtoInfo[i].ProtocolChain.ChainEntries[0] == dwLayeredCatalogId))  
  195.             {  
  196.                 ::WSCDeinstallProvider(&pProtoInfo[i].ProviderId, &nError);  
  197.             }  
  198.         }  
  199.           
  200.         // 移除分层协议  
  201.         ::WSCDeinstallProvider(&ProviderGuid, &nError);  
  202.     }  
  203.     else return FALSE;  
  204.     return TRUE;  
  205. }  
  206. void main(int argc, char *argv[])  
  207. {  
  208.     char *ptr;  
  209.     //if(argc==2)  
  210.     {  
  211.         ptr = argv[1];  
  212.         while (*ptr)  
  213.             *ptr++ = tolower(*ptr);  
  214.         int test;  
  215.         scanf("%d", &test);  
  216.         if(test == 1)  
  217.         //if(strcmp(argv[1], "-install")==0)     
  218.         {  
  219.             TCHAR szPathName[256];  
  220.             TCHAR* p;  
  221.             if(::GetFullPathName(L"LSP.dll", 256, szPathName, &p) != 0)  
  222.             {  
  223.                 if(InstallProvider(szPathName))  
  224.                 {  
  225.                     printf(" Install successully. /n");  
  226.                     return;  
  227.                 }  
  228.             }  
  229.             printf(" Install failed. /n");  
  230.             return;  
  231.         }  
  232.         else  
  233.         //else if(strcmp(argv[1],"-remove")==0)   
  234.         {  
  235.             if(RemoveProvider())  
  236.                 printf(" Deinstall successully. /n");  
  237.             else  
  238.                 printf(" Deinstall failed. /n");  
  239.             return;  
  240.         }  
  241.     }  
  242.       
  243.     printf(" Usage: Instlsp [ -install │ -remove ] /n");  
  244. }  
 

 


 

LSP.Cpp

[cpp] view plaincopy
  1. #define  UNICODE  
  2. #define  _UNICODE  
  3. #include <ws2spi.h>  
  4. #include <errno.h>  
  5. #include <fstream>  
  6. #pragma   comment(lib,"Ws2_32.lib")  
  7. GUID filterguid = {0xd3c21122, 0x85e1, 0x48f3,   
  8.                             {0x9a,0xb6,0x23,0xd9,0x0c,0x73,0x07,0xef}};  
  9. LPWSAPROTOCOL_INFOW  ProtoInfo=NULL;  
  10. WSPPROC_TABLE        NextProcTable;  
  11. DWORD                ProtoInfoSize=0;  
  12. int                  TotalProtos=0;  
  13. // 输出函数  
  14. int PutDbgStr(LPCTSTR lpFmt, ...)  
  15. {  
  16.   TCHAR  Msg[1024];  
  17.   int  len=wvsprintf(Msg,lpFmt,va_list(1+&lpFmt));  
  18.   OutputDebugString(Msg);  
  19.   return len;  
  20. }  
  21. // 获取各种值  
  22. BOOL GetLSP()  
  23. {  
  24.     int    errorcode;  
  25.     ProtoInfo=NULL;  
  26.     ProtoInfoSize=0;  
  27.     TotalProtos=0;  
  28.     if(WSCEnumProtocols(NULL,ProtoInfo,&ProtoInfoSize,&errorcode)==SOCKET_ERROR)  
  29.     {  
  30.         if(errorcode!=WSAENOBUFS)  
  31.         {  
  32.             PutDbgStr(L"First WSCEnumProtocols Error!");   
  33.             return FALSE;  
  34.         }  
  35.     }  
  36.     if((ProtoInfo=(LPWSAPROTOCOL_INFOW)GlobalAlloc(GPTR,ProtoInfoSize))==NULL)  
  37.     {  
  38.         PutDbgStr(L"GlobalAlloc Error!");                  
  39.         return FALSE;  
  40.     }  
  41.     if((TotalProtos=WSCEnumProtocols(NULL,ProtoInfo,&ProtoInfoSize,&errorcode))==SOCKET_ERROR)  
  42.     {  
  43.         PutDbgStr(L"Second WSCEnumProtocols Error!");     
  44.         return FALSE;  
  45.     }  
  46.     return TRUE;  
  47. }  
  48. // 释放内存  
  49. void FreeLSP()  
  50. {  
  51.     GlobalFree(ProtoInfo);  
  52. }  
  53. // DLL入口函数  
  54. BOOL WINAPI DllMain(HINSTANCE hmodule,  
  55. DWORD     reason,  
  56. LPVOID    lpreserved)  
  57. {  
  58.     TCHAR   processname[MAX_PATH];  
  59.     if(reason==DLL_PROCESS_ATTACH)  
  60.     {  
  61.         GetModuleFileName(NULL,processname,MAX_PATH);  
  62.         PutDbgStr(L"%s Loading IPFilter ...", processname);    
  63.     }  
  64.     return TRUE;  
  65. }  
  66. /********************************* 改写WSP函数,只有WSPConnect被改写成调用socksProxy函数,其它的直接调用下层WSP函数 ****************************************/  
  67. //WSPConnect  
  68. int WSPAPI WSPConnect(  
  69.     SOCKET s,  
  70.     const struct sockaddr *name,  
  71.     int namelen,  
  72.     LPWSABUF lpCallerData,  
  73.     LPWSABUF lpCalleeData,  
  74.     LPQOS lpSQOS,  
  75.     LPQOS lpGQOS,  
  76.     LPINT lpErrno)  
  77. {  
  78.     return NextProcTable.lpWSPConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS, lpErrno);   
  79.     }  
  80. }  
  81. //WSPSocket  
  82. SOCKET WINAPI WSPSocket(  
  83.   __in   int af,  
  84.   __in   int type,  
  85.   __in   int protocol,  
  86.   __in   LPWSAPROTOCOL_INFO lpProtocolInfo,  
  87.   __in   GROUP g,  
  88.   DWORD dwFlags,  
  89.   __out  LPINT lpErrno  
  90. )  
  91. {  
  92.     PutDbgStr(L"WSPSocket");    
  93.     return NextProcTable.lpWSPSocket(af, type, protocol, lpProtocolInfo, g, dwFlags, lpErrno);  
  94. }  
  95. //WSPBind  
  96. int WINAPI WSPBind(  
  97.   __in   SOCKET s,  
  98.   __in   const struct sockaddr *name,  
  99.   __in   int namelen,  
  100.   __out  LPINT lpErrno  
  101. )  
  102. {  
  103.     PutDbgStr(L"WSPBind");    
  104.     return NextProcTable.lpWSPBind(s, name, namelen, lpErrno);  
  105. }  
  106. //WSPSend  
  107. int WINAPI WSPSend(  
  108.   __in   SOCKET s,  
  109.   __in   LPWSABUF lpBuffers,  
  110.   __in   DWORD dwBufferCount,  
  111.   __out  LPDWORD lpNumberOfBytesSent,  
  112.   __in   DWORD dwFlags,  
  113.   __in   LPWSAOVERLAPPED lpOverlapped,  
  114.   __in   LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,  
  115.   __in   LPWSATHREADID lpThreadId,  
  116.   __out  LPINT lpErrno  
  117. )  
  118. {  
  119.     PutDbgStr(L"WSPSend");  
  120.     return NextProcTable.lpWSPSend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine, lpThreadId, lpErrno);  
  121. }  
  122. //WSPSendTo  
  123. int WINAPI WSPSendTo(  
  124.   __in   SOCKET s,  
  125.   __in   LPWSABUF lpBuffers,  
  126.   __in   DWORD dwBufferCount,  
  127.   __out  LPDWORD lpNumberOfBytesSent,  
  128.   __in   DWORD dwFlags,  
  129.   __in   const struct sockaddr *lpTo,  
  130.   __in   int iTolen,  
  131.   __in   LPWSAOVERLAPPED lpOverlapped,  
  132.   __in   LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,  
  133.   __in   LPWSATHREADID lpThreadId,  
  134.   __out  LPINT lpErrno  
  135. )  
  136. {  
  137.     PutDbgStr(L"WSPSendTo");   
  138.     return NextProcTable.lpWSPSendTo(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpTo, iTolen, lpOverlapped, lpCompletionRoutine, lpThreadId, lpErrno);  
  139. }  
  140. //WSPRecv  
  141. int WINAPI WSPRecv(  
  142.   __in     SOCKET s,  
  143.   __inout  LPWSABUF lpBuffers,  
  144.   __in     DWORD dwBufferCount,  
  145.   __out    LPDWORD lpNumberOfBytesRecvd,  
  146.   __inout  LPDWORD lpFlags,  
  147.   __in     LPWSAOVERLAPPED lpOverlapped,  
  148.   __in     LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,  
  149.   __in     LPWSATHREADID lpThreadId,  
  150.   __out    LPINT lpErrno  
  151. )  
  152. {  
  153.     PutDbgStr(L"WSPRecv");    
  154.     return NextProcTable.lpWSPRecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine, lpThreadId, lpErrno);  
  155. }  
  156. //WSPRecvFrom  
  157. int WINAPI WSPRecvFrom(  
  158.   __in     SOCKET s,  
  159.   __inout  LPWSABUF lpBuffers,  
  160.   __in     DWORD dwBufferCount,  
  161.   __out    LPDWORD lpNumberOfBytesRecvd,  
  162.   __inout  LPDWORD lpFlags,  
  163.   __out    struct sockaddr *lpFrom,  
  164.   __inout  LPINT lpFromlen,  
  165.   __in     LPWSAOVERLAPPED lpOverlapped,  
  166.   __in     LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,  
  167.   __in     LPWSATHREADID lpThreadId,  
  168.   __inout  LPINT lpErrno  
  169. )  
  170. {  
  171.     PutDbgStr(L"WSPRecvFrom");    
  172.     return NextProcTable.lpWSPRecvFrom(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, lpOverlapped, lpCompletionRoutine, lpThreadId, lpErrno);  
  173. }  
  174. //WSPStartup  
  175. int WSPAPI WSPStartup(  
  176. WORD wversionrequested,  
  177. LPWSPDATA         lpwspdata,  
  178. LPWSAPROTOCOL_INFOW lpProtoInfo,  
  179. WSPUPCALLTABLE upcalltable,  
  180. LPWSPPROC_TABLE lpproctable  
  181. )  
  182. {  
  183.     PutDbgStr(L"IPFilter WSPStartup ...");  
  184.     int           i;  
  185.     int           errorcode;   
  186.     int           filterpathlen;  
  187.     DWORD         layerid=0;   
  188.     DWORD         nextlayerid=0;  
  189.     TCHAR         *filterpath;  
  190.     HINSTANCE     hfilter;  
  191.     LPWSPSTARTUP  wspstartupfunc=NULL;  
  192.     if(lpProtoInfo->ProtocolChain.ChainLen<=1)  
  193.     {  
  194.         PutDbgStr(L"ChainLen<=1");    
  195.         return FALSE;  
  196.     }  
  197.     GetLSP();  
  198.     for(i=0;i<TotalProtos;i++)  
  199.     {  
  200.         if(memcmp(&ProtoInfo[i].ProviderId,&filterguid,sizeof(GUID))==0)  
  201.         {  
  202.             layerid=ProtoInfo[i].dwCatalogEntryId;  
  203.             break;  
  204.         }  
  205.     }  
  206.     for(i=0;i<lpProtoInfo->ProtocolChain.ChainLen;i++)  
  207.     {  
  208.         if(lpProtoInfo->ProtocolChain.ChainEntries[i]==layerid)  
  209.         {  
  210.             nextlayerid=lpProtoInfo->ProtocolChain.ChainEntries[i+1];  
  211.             break;  
  212.         }  
  213.     }  
  214.     filterpathlen=MAX_PATH;  
  215.     filterpath=(TCHAR*)GlobalAlloc(GPTR,filterpathlen);    
  216.     for(i=0;i<TotalProtos;i++)  
  217.     {  
  218.         if(nextlayerid==ProtoInfo[i].dwCatalogEntryId)  
  219.         {  
  220.             if(WSCGetProviderPath(&ProtoInfo[i].ProviderId,filterpath,&filterpathlen,&errorcode)==SOCKET_ERROR)  
  221.             {  
  222.                 PutDbgStr(L"WSCGetProviderPath Error!");    
  223.                 return WSAEPROVIDERFAILEDINIT;  
  224.             }  
  225.             break;  
  226.         }  
  227.     }  
  228.     if(!ExpandEnvironmentStrings(filterpath,filterpath,MAX_PATH))  
  229.     {  
  230.         PutDbgStr(L"ExpandEnvironmentStrings Error!");      
  231.         return WSAEPROVIDERFAILEDINIT;  
  232.     }  
  233.     if((hfilter=LoadLibrary(filterpath))==NULL)  
  234.     {  
  235.         PutDbgStr(L"LoadLibrary Error!");   
  236.         return WSAEPROVIDERFAILEDINIT;  
  237.     }  
  238.     if((wspstartupfunc=(LPWSPSTARTUP)GetProcAddress(hfilter,"WSPStartup"))==NULL)  
  239.     {  
  240.         PutDbgStr(L"GetProcessAddress Error!");    
  241.         return WSAEPROVIDERFAILEDINIT;  
  242.     }  
  243.     if((errorcode=wspstartupfunc(wversionrequested,lpwspdata,lpProtoInfo,upcalltable,lpproctable))!=ERROR_SUCCESS)  
  244.     {  
  245.         PutDbgStr(L"wspstartupfunc Error!");    
  246.         return errorcode;  
  247.     }  
  248.     NextProcTable=*lpproctable;// 保存原来的入口函数表  
  249.     //改写函数  
  250.     lpproctable->lpWSPSendTo = WSPSendTo;  
  251.     lpproctable->lpWSPSend = WSPSend;  
  252.     lpproctable->lpWSPBind = WSPBind;  
  253.     lpproctable->lpWSPConnect = WSPConnect;  
  254.     lpproctable->lpWSPRecv = WSPRecv;  
  255.     lpproctable->lpWSPRecvFrom = WSPRecvFrom;  
  256.     lpproctable->lpWSPSocket = WSPSocket;  
  257.     FreeLSP();  
  258.     return 0;  
  259. }  
 

 



关于SOCKS V5代理,下回修改文章再贴上。

 

zetsin@gmail.com

2011-04-30 20:57:02

 

 


 

 

要说SOCKS V5代理,其实非常简单,细读一遍RFC1928文档就OK了,文档地址如下:

http://www.ietf.org/rfc/rfc1928.txt

 

 

如果需要远程解析域名,则将上述文档中第四点的 ATYP 置为 /X03

 

 

 

 

 

 

 

 

最后将前面所写的LSP与SOCKS V5代理结合,TCP的话只要拦截WSPCONNECT函数,UDP因为不是面向连接的所以只要拦截WSPSENDTO即可,具体代码如下:

 

 

[cpp] view plaincopy
  1. // 连接socks5代理  
  2. int socksProxy(SOCKET s, const struct sockaddr *name, int namelen)  
  3. {  
  4.     int rc = 0;  
  5.     // 这里应该先保存下socket的阻塞/非阻塞类型,在最后面跟据这里的值将它还原,但是不知道怎样获取此类型  
  6.     // 修改socket为阻塞类型  
  7.     if(rc = WSAEventSelect(s, 0, NULL))//这一个可以不用执行  
  8.     {  
  9.         PutDbgStr(L"Error %d : WSAEventSelect Failure!", WSAGetLastError());  
  10.     }  
  11.     else   
  12.     {  
  13.         PutDbgStr(L"Message : WSAEventSelect successfully!");  
  14.     }  
  15.     unsigned long nonBlock = 0;  
  16.     if(rc = ioctlsocket(s, FIONBIO, &nonBlock))// 这个真正修改为阻塞类型  
  17.     {  
  18.         PutDbgStr(L"Error %d : Set Blocking Failure!", WSAGetLastError());  
  19.     }  
  20.     else  
  21.     {  
  22.         PutDbgStr(L"Message : Set Blocking successfully!");  
  23.     }  
  24.     //连接代理服务器  
  25.     sockaddr_in serveraddr;  
  26.     memset(&serveraddr, 0, sizeof(serveraddr));  
  27.     serveraddr.sin_family = AF_INET;   
  28.     serveraddr.sin_addr.S_un.S_addr = inet_addr("76.120.160.122"); //代理服务器地址,从无忧代理网获取的,质量还行,不过只能用几天,发现连不上的话重新获取吧  
  29.     serveraddr.sin_port = htons(27977); // 端口号  
  30.     WSABUF DataBuf;  
  31.     char buffer[4];  
  32.     memset(buffer, 0, sizeof(buffer));  
  33.     DataBuf.len = 4;   
  34.     DataBuf.buf = buffer;   
  35.     int err = 0;  
  36.     if((rc = NextProcTable.lpWSPConnect(s, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr), &DataBuf, NULL, NULL, NULL, &err)) != 0)  
  37.     {  
  38.         PutDbgStr(L"Error %d : attempting to connect to SOCKS server!", err);  
  39.         return rc;  
  40.     }  
  41.     else  
  42.     {  
  43.         PutDbgStr(L"Message : Connect to SOCKS server successfully!");  
  44.     }  
  45.     //发送请求来协商版本和认证方法  
  46.     //VER   NMETHODS    METHODS  
  47.     //1     1           1 to 255  
  48.     char verstring[257];  
  49.     verstring[0] = 0x05;    //VER (1 Byte)  
  50.     verstring[1] = 0x01;    //NMETHODS (1 Byte)  
  51.     verstring[2] = 0x00;    //METHODS (allow 1 - 255 bytes, current 1 byte)  
  52.     if((rc = send(s, verstring, 3, 0)) < 0)  
  53.     {  
  54.         PutDbgStr(L"Error %d : attempting to send SOCKS method negotiation!",  WSAGetLastError());  
  55.         return rc;  
  56.     }  
  57.     else  
  58.     {  
  59.         PutDbgStr(L"Message : send SOCKS method negotiation successfully!");  
  60.     }  
  61.     //接收代理服务器返回信息  
  62.     //VER   METHOD  
  63.     //1     1  
  64.     /*当前定义的方法有: 
  65.     · X’00’ 不需要认证 
  66.     · X’01’ GSSAPI 
  67.     · X’02’ 用户名/密码 
  68.     · X’03’ -- X’7F’ 由IANA分配 
  69.     · X’80’ -- X’FE’ 为私人方法所保留的 
  70.     · X’FF’ 没有可以接受的方法*/  
  71.     if((rc = recv(s, verstring, 257, 0)) < 0)  
  72.     {  
  73.         PutDbgStr(L"Error %d : attempting to receive SOCKS method negotiation reply!", WSAGetLastError());  
  74.         return rc;  
  75.     }  
  76.     else  
  77.     {  
  78.         PutDbgStr(L"Message : receive SOCKS method negotiation reply successfully!");  
  79.     }  
  80.     if(rc < 2)//返回2字节  
  81.     {  
  82.         PutDbgStr(L"Error : Short reply from SOCKS server!");  
  83.         rc = ECONNREFUSED;  
  84.         return rc;  
  85.     }  
  86.     else  
  87.     {  
  88.         PutDbgStr(L"Message : reply from SOCKS server larger than 2");  
  89.     }  
  90.     // 代理服务器选择方法  
  91.     // 判断我们的方法是否可行  
  92.     if(verstring[1] == '/xff')  
  93.     {  
  94.         PutDbgStr(L"Error : SOCKS server refused authentication methods!");  
  95.         rc = ECONNREFUSED;  
  96.         return rc;  
  97.     }  
  98.     else if(verstring[1] == '/x02')// 方法2 : 用户名/密码  
  99.     {  
  100.         //另外处理  
  101.         PutDbgStr(L"Error : SOCKS server need username/password!");  
  102.     }  
  103.     else if(verstring[1] == '/x00')// 方法0: 不需要认证  
  104.     {  
  105.         //发送SOCKS请求  
  106.         //VER   CMD RSV     ATYP    DST.ADDR    DST.PROT  
  107.         //1     1   X'00'   1       Variable    2  
  108.         /* VER 协议版本: X’05’ 
  109.         · CMD 
  110.            · CONNECT:X’01’ 
  111.            · BIND:X’02’ 
  112.            · UDP ASSOCIATE:X’03’ 
  113.         · RSV 保留 
  114.         · ATYP 后面的地址类型 
  115.            · IPV4:X’01’ 
  116.            · 域名:X’03’ 
  117.            · IPV6:X’04’' 
  118.         · DST.ADDR 目的地址 
  119.         · DST.PORT 以网络字节顺序出现的端口号 
  120.         SOCKS服务器会根据源地址和目的地址来分析请求,然后根据请求类型返回一个或多个应答。*/  
  121.         struct sockaddr_in sin;  
  122.         sin = *(const struct sockaddr_in *)name;  
  123.         char buf[10];  
  124.         buf[0] = '/x05'// 版本 SOCKS5  
  125.         buf[1] = '/x01'// 连接请求  
  126.         buf[2] = '/x00'// 保留字段  
  127.         buf[3] = '/x01'// IPV4  
  128.         memcpy(&buf[4], &sin.sin_addr.S_un.S_addr, 4);  
  129.         memcpy(&buf[8], &sin.sin_port, 2);  
  130.         //发送  
  131.         if((rc = send(s, buf, 10, 0)) < 0)  
  132.         {  
  133.             PutDbgStr(L"Error %d : attempting to send SOCKS connect command!", WSAGetLastError());  
  134.             return rc;  
  135.         }  
  136.         else  
  137.         {  
  138.             PutDbgStr(L"Message : send SOCKS connect command successfully!");  
  139.         }  
  140.         //应答  
  141.         //VER   REP RSV     ATYP    BND.ADDR    BND.PORT  
  142.         //1     1   X'00'   1       Variable    2  
  143.         /*VER 协议版本: X’05’ 
  144.         · REP 应答字段: 
  145.            · X’00’ 成功 
  146.            · X’01’ 普通的SOCKS服务器请求失败 
  147.            · X’02’ 现有的规则不允许的连接 
  148.            · X’03’ 网络不可达 
  149.            · X’04’ 主机不可达 
  150.            · X’05’ 连接被拒 
  151.            · X’06’ TTL超时 
  152.            · X’07’ 不支持的命令 
  153.            · X’08’ 不支持的地址类型 
  154.            · X’09’ – X’FF’ 未定义 
  155.         · RSV 保留 
  156.         · ATYP 后面的地址类型 
  157.            · IPV4:X’01’ 
  158.            · 域名:X’03’ 
  159.            · IPV6:X’04’ 
  160.         · BND.ADDR 服务器绑定的地址 
  161.         · BND.PORT 以网络字节顺序表示的服务器绑定的段口 
  162.         标识为RSV的字段必须设为X’00’。*/  
  163.         if((rc = recv(s, buf, 10, 0)) < 0) // 用了天翼的网络之后,这里就接收不到返回信息了,不解  
  164.         {  
  165.             PutDbgStr(L"Error %d : attempting to receive SOCKS connection reply!", WSAGetLastError());  
  166.             rc = ECONNREFUSED;  
  167.             return rc;  
  168.         }  
  169.         else  
  170.         {  
  171.             PutDbgStr(L"Message : receive SOCKS connection reply successfully!");  
  172.         }  
  173.         if(rc < 10)  
  174.         {  
  175.             PutDbgStr(L"Message : Short reply from SOCKS server!");  
  176.             return rc;  
  177.         }  
  178.         else  
  179.         {  
  180.             PutDbgStr(L"Message : reply from SOCKS larger than 10!");  
  181.         }  
  182.         //连接不成功  
  183.         if(buf[0] != '/x05')  
  184.         {  
  185.             PutDbgStr(L"Message : Socks V5 not supported!");  
  186.             return ECONNABORTED;  
  187.         }  
  188.         else  
  189.         {  
  190.             PutDbgStr(L"Message : Socks V5 is supported!");  
  191.         }  
  192.         if(buf[1] != '/x00')  
  193.         {  
  194.             PutDbgStr(L"Message : SOCKS connect failed!");  
  195.             switch((int)buf[1])  
  196.             {  
  197.             case 1:  
  198.                 PutDbgStr(L"General SOCKS server failure!");  
  199.                 return ECONNABORTED;  
  200.             case 2:  
  201.                 PutDbgStr(L"Connection denied by rule!");  
  202.                 return ECONNABORTED;  
  203.             case 3:  
  204.                 PutDbgStr(L"Network unreachable!");  
  205.                 return ENETUNREACH;  
  206.             case 4:  
  207.                 PutDbgStr(L"Host unreachable!");  
  208.                 return EHOSTUNREACH;  
  209.             case 5:  
  210.                 PutDbgStr(L"Connection refused!");  
  211.                 return ECONNREFUSED;  
  212.             case 6:  
  213.                 PutDbgStr(L"TTL Expired!");  
  214.                 return ETIMEDOUT;  
  215.             case 7:  
  216.                 PutDbgStr(L"Command not supported!");  
  217.                 return ECONNABORTED;  
  218.             case 8:  
  219.                 PutDbgStr(L"Address type not supported!");  
  220.                 return ECONNABORTED;  
  221.             default:  
  222.                 PutDbgStr(L"Unknown error!");  
  223.                 return ECONNABORTED;  
  224.             }  
  225.         }  
  226.         else  
  227.         {  
  228.             PutDbgStr(L"Message : SOCKS connect Success!");  
  229.         }  
  230.     }  
  231.     else  
  232.     {  
  233.         PutDbgStr(L"Error : Method not supported!");  
  234.     }  
  235.     //修改socket为非阻塞类型  
  236.     nonBlock = 1;  
  237.     if(rc = ioctlsocket(s, FIONBIO, &nonBlock))  
  238.     {  
  239.         PutDbgStr(L"Error %d : Set Non-Blocking Failure!", WSAGetLastError());  
  240.         return rc;  
  241.     }  
  242.     else  
  243.     {  
  244.         PutDbgStr(L"Message : Set Non-Blocking Successful!");  
  245.     }  
  246.     PutDbgStr(L"Message : Success!");  
  247.     return 0;  
  248. }  
  249. //WSPConnect  
  250. int WSPAPI WSPConnect(  
  251.     SOCKET s,  
  252.     const struct sockaddr *name,  
  253.     int namelen,  
  254.     LPWSABUF lpCallerData,  
  255.     LPWSABUF lpCalleeData,  
  256.     LPQOS lpSQOS,  
  257.     LPQOS lpGQOS,  
  258.     LPINT lpErrno)  
  259. {  
  260.     PutDbgStr(L"WSPConnect");  
  261.     struct sockaddr_in sin;  
  262.     sin=*(const struct sockaddr_in *)name;  
  263.     if(strcmp(inet_ntoa(sin.sin_addr), "127.0.0.1") == 0)  
  264.     {  
  265.         return NextProcTable.lpWSPConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS, lpErrno);   
  266.     }  
  267.     return socksProxy(s, name, namelen);  
  268. }  
  269. //WSPSendTo  
  270. int WINAPI WSPSendTo(  
  271.   __in   SOCKET s,  
  272.   __in   LPWSABUF lpBuffers,  
  273.   __in   DWORD dwBufferCount,  
  274.   __out  LPDWORD lpNumberOfBytesSent,  
  275.   __in   DWORD dwFlags,  
  276.   __in   const struct sockaddr *lpTo,  
  277.   __in   int iTolen,  
  278.   __in   LPWSAOVERLAPPED lpOverlapped,  
  279.   __in   LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,  
  280.   __in   LPWSATHREADID lpThreadId,  
  281.   __out  LPINT lpErrno  
  282. )  
  283. {  
  284.     PutDbgStr(L"WSPSendTo");   
  285.     struct sockaddr_in sin;  
  286.     sin=*(const struct sockaddr_in *)name;  
  287.     if(strcmp(inet_ntoa(sin.sin_addr), "127.0.0.1") == 0)  
  288.     {  
  289.         return NextProcTable.lpWSPSendTo(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpTo, iTolen, lpOverlapped, lpCompletionRoutine, lpThreadId, lpErrno);  
  290.     }  
  291.     return socksProxy(s, lpTo, iTolen);  
  292. }  
 

 

 

zetsin@gmail.com

2011-05-02 18:25:39


0 0