利用SPI編寫類似sockscap的代理工具

轉自: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

  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

  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代理,下回修改文章再貼上。

 

[email protected]

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即可,具體代碼如下:

 

 

  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. }  
 

 

 

[email protected]

2011-05-02 18:25:39


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章