VC++基于LSP拦截数据封包

来源:互联网 发布:天猫魔盒直播软件 编辑:程序博客网 时间:2024/04/30 14:11

LSP即分层服务提供商,Winsock 作为应用程序的 Windows 的网络套接字工具,可以由称为“分层服务提供商”的机制进行扩展。

Winsock LSP 可用于非常广泛的实用用途,包括 Internet 家长控制 (parental control) 和 Web 内容筛选。在以前版本的 Windows XP 中,删除不正确的(也称为“buggy”)LSP 可能会导致注册表中的 Winsock 目录损坏,潜在地导致所有网络连接的丢失。
LSP(Layered Service Provider )  中文名为分层服务提供程序。 LSP就是TCP/IP等协议的接口.LSP用在正途上可以方便程序员们编写监视系统网络通讯情况的Sniffer,可是现在常见的LSP都被用于浏览器劫持.

 LSP安装卸载代码如下

//////////////////////////////////////////////////////////////// InstLSP.cpp文件// 包含了安装LSP的代码// InstallProvider(WCHAR *pwszPathName) 将指定LSP提供者安装到TCP UDP 和原始套节字之上// RemoveProvider()移除InstallProvider函数安装的LSP#define UNICODE#define _UNICODE#include <Ws2spi.h>#include <Sporder.h>// 定义了WSCWriteProviderOrder函数#include <windows.h>#include <stdio.h>#pragma comment(lib, "Ws2_32.lib")#pragma comment(lib, "Rpcrt4.lib")// 实现了UuidCreate函数// 要安装的LSP的硬编码,在移除的时候还要使用它GUID  ProviderGuid = {0xd3c21122, 0x85e1, 0x48f3, {0x9a,0xb6,0x23,0xd9,0x0c,0x73,0x07,0xef}};LPWSAPROTOCOL_INFOW GetProvider(LPINT lpnTotalProtocols){DWORD dwSize = 0;int nError;LPWSAPROTOCOL_INFOW pProtoInfo = NULL;// 取得需要的长度if(::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError) == SOCKET_ERROR){if(nError != WSAENOBUFS)return NULL;}pProtoInfo = (LPWSAPROTOCOL_INFOW)::GlobalAlloc(GPTR, dwSize);*lpnTotalProtocols = ::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError);return pProtoInfo;}void FreeProvider(LPWSAPROTOCOL_INFOW pProtoInfo){::GlobalFree(pProtoInfo);}BOOL InstallProvider(WCHAR *pwszPathName){WCHAR wszLSPName[] = L"PhoenixLSP";LPWSAPROTOCOL_INFOW pProtoInfo;int nProtocols;WSAPROTOCOL_INFOW OriginalProtocolInfo[3];DWORD dwOrigCatalogId[3];int nArrayCount = 0;DWORD dwLayeredCatalogId;// 我们分层协议的目录ID号int nError;// 找到我们的下层协议,将信息放入数组中// 枚举所有服务程序提供者pProtoInfo = GetProvider(&nProtocols);BOOL bFindUdp = FALSE;BOOL bFindTcp = FALSE;BOOL bFindRaw = FALSE;for(int i=0; i<nProtocols; i++){if(pProtoInfo[i].iAddressFamily == AF_INET){if(!bFindUdp && pProtoInfo[i].iProtocol == IPPROTO_UDP){memcpy(&OriginalProtocolInfo[nArrayCount], &pProtoInfo[i], sizeof(WSAPROTOCOL_INFOW));OriginalProtocolInfo[nArrayCount].dwServiceFlags1 = OriginalProtocolInfo[nArrayCount].dwServiceFlags1 & (~XP1_IFS_HANDLES); dwOrigCatalogId[nArrayCount++] = pProtoInfo[i].dwCatalogEntryId;bFindUdp = TRUE;}if(!bFindTcp && pProtoInfo[i].iProtocol == IPPROTO_TCP){memcpy(&OriginalProtocolInfo[nArrayCount], &pProtoInfo[i], sizeof(WSAPROTOCOL_INFOW));OriginalProtocolInfo[nArrayCount].dwServiceFlags1 = OriginalProtocolInfo[nArrayCount].dwServiceFlags1 & (~XP1_IFS_HANDLES); dwOrigCatalogId[nArrayCount++] = pProtoInfo[i].dwCatalogEntryId;bFindTcp = TRUE;} if(!bFindRaw && pProtoInfo[i].iProtocol == IPPROTO_IP){memcpy(&OriginalProtocolInfo[nArrayCount], &pProtoInfo[i], sizeof(WSAPROTOCOL_INFOW));OriginalProtocolInfo[nArrayCount].dwServiceFlags1 = OriginalProtocolInfo[nArrayCount].dwServiceFlags1 & (~XP1_IFS_HANDLES); dwOrigCatalogId[nArrayCount++] = pProtoInfo[i].dwCatalogEntryId;bFindRaw = TRUE;}}}  // 安装我们的分层协议,获取一个dwLayeredCatalogId// 随便找一个下层协议的结构复制过来即可WSAPROTOCOL_INFOW LayeredProtocolInfo;memcpy(&LayeredProtocolInfo, &OriginalProtocolInfo[0], sizeof(WSAPROTOCOL_INFOW));// 修改协议名称,类型,设置PFL_HIDDEN标志wcscpy(LayeredProtocolInfo.szProtocol, wszLSPName);LayeredProtocolInfo.ProtocolChain.ChainLen = LAYERED_PROTOCOL; // 0;LayeredProtocolInfo.dwProviderFlags |= PFL_HIDDEN;// 安装if(::WSCInstallProvider(&ProviderGuid, pwszPathName, &LayeredProtocolInfo, 1, &nError) == SOCKET_ERROR){return FALSE;}// 重新枚举协议,获取分层协议的目录ID号FreeProvider(pProtoInfo);pProtoInfo = GetProvider(&nProtocols);for(i=0; i<nProtocols; i++){if(memcmp(&pProtoInfo[i].ProviderId, &ProviderGuid, sizeof(ProviderGuid)) == 0){dwLayeredCatalogId = pProtoInfo[i].dwCatalogEntryId;break;}}// 安装协议链// 修改协议名称,类型WCHAR wszChainName[WSAPROTOCOL_LEN + 1];for(i=0; i<nArrayCount; i++){swprintf(wszChainName, L"%ws over %ws", wszLSPName, OriginalProtocolInfo[i].szProtocol);wcscpy(OriginalProtocolInfo[i].szProtocol, wszChainName);if(OriginalProtocolInfo[i].ProtocolChain.ChainLen == 1){OriginalProtocolInfo[i].ProtocolChain.ChainEntries[1] = dwOrigCatalogId[i];}else{for(int j = OriginalProtocolInfo[i].ProtocolChain.ChainLen; j>0; j--){OriginalProtocolInfo[i].ProtocolChain.ChainEntries[j] = OriginalProtocolInfo[i].ProtocolChain.ChainEntries[j-1];}}OriginalProtocolInfo[i].ProtocolChain.ChainLen ++;OriginalProtocolInfo[i].ProtocolChain.ChainEntries[0] = dwLayeredCatalogId;}// 获取一个Guid,安装之GUID ProviderChainGuid;if(::UuidCreate(&ProviderChainGuid) == RPC_S_OK){if(::WSCInstallProvider(&ProviderChainGuid, pwszPathName, OriginalProtocolInfo, nArrayCount, &nError) == SOCKET_ERROR){return FALSE;}}elsereturn FALSE;// 重新排序Winsock目录,将我们的协议链提前// 重新枚举安装的协议FreeProvider(pProtoInfo);pProtoInfo = GetProvider(&nProtocols);DWORD dwIds[20];int nIndex = 0;// 添加我们的协议链for(i=0; i<nProtocols; i++){if((pProtoInfo[i].ProtocolChain.ChainLen > 1) &&(pProtoInfo[i].ProtocolChain.ChainEntries[0] == dwLayeredCatalogId))dwIds[nIndex++] = pProtoInfo[i].dwCatalogEntryId;}// 添加其它协议for(i=0; i<nProtocols; i++){if((pProtoInfo[i].ProtocolChain.ChainLen <= 1) ||(pProtoInfo[i].ProtocolChain.ChainEntries[0] != dwLayeredCatalogId))dwIds[nIndex++] = pProtoInfo[i].dwCatalogEntryId;}// 重新排序Winsock目录if((nError = ::WSCWriteProviderOrder(dwIds, nIndex)) != ERROR_SUCCESS){return FALSE;}FreeProvider(pProtoInfo);return TRUE;}BOOL RemoveProvider(){LPWSAPROTOCOL_INFOW pProtoInfo;int nProtocols;DWORD dwLayeredCatalogId;// 根据Guid取得分层协议的目录ID号pProtoInfo = GetProvider(&nProtocols);int nError;for(int i=0; i<nProtocols; i++){if(memcmp(&ProviderGuid, &pProtoInfo[i].ProviderId, sizeof(ProviderGuid)) == 0){dwLayeredCatalogId = pProtoInfo[i].dwCatalogEntryId;break;}}if(i < nProtocols){// 移除协议链for(i=0; i<nProtocols; i++){if((pProtoInfo[i].ProtocolChain.ChainLen > 1) &&(pProtoInfo[i].ProtocolChain.ChainEntries[0] == dwLayeredCatalogId)){::WSCDeinstallProvider(&pProtoInfo[i].ProviderId, &nError);}}// 移除分层协议::WSCDeinstallProvider(&ProviderGuid, &nError);}return TRUE;}void main(int argc, char *argv[]){if(argc==2){if(strcmp(argv[1], "-install")==0)   {TCHAR szPathName[256];TCHAR* p;if(::GetFullPathName(L"LSP.dll", 256, szPathName, &p) != 0){if(InstallProvider(szPathName)){printf(" Install successully. \n");return;}}printf(" Install failed. \n");return;}else if(strcmp(argv[1],"-remove")==0)  {if(RemoveProvider())printf(" Deinstall successully. \n");elseprintf(" Deinstall failed. \n");return;}}printf(" Usage: Instlsp [ -install │ -remove ] \n");}


 

 LSP实现代码如下

//////////////////////////////////////////////////// LSP.cpp文件// 声明要使用UNICODE字符串#define UNICODE#define _UNICODE#include <Winsock2.h>#include <Ws2spi.h>#include <Windows.h>#include <tchar.h>#include "Debug.h"#pragma comment(lib, "Ws2_32.lib")WSPUPCALLTABLE g_pUpCallTable;// 上层函数列表。如果LSP创建了自己的伪句柄,才使用这个函数列表WSPPROC_TABLE g_NextProcTable;// 下层函数列表TCHARg_szCurrentApp[MAX_PATH];// 当前调用本DLL的程序的名称BOOL APIENTRY DllMain( HANDLE hModule,                        DWORD  ul_reason_for_call,                        LPVOID lpReserved ){switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:{// 取得主模块的名称::GetModuleFileName(NULL, g_szCurrentApp, MAX_PATH);}break;}return TRUE;}LPWSAPROTOCOL_INFOW GetProvider(LPINT lpnTotalProtocols){DWORD dwSize = 0;int nError;LPWSAPROTOCOL_INFOW pProtoInfo = NULL;// 取得需要的长度if(::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError) == SOCKET_ERROR){if(nError != WSAENOBUFS)return NULL;}pProtoInfo = (LPWSAPROTOCOL_INFOW)::GlobalAlloc(GPTR, dwSize);*lpnTotalProtocols = ::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError);return pProtoInfo;}void FreeProvider(LPWSAPROTOCOL_INFOW pProtoInfo){::GlobalFree(pProtoInfo);}int WSPAPI WSPSendTo(SOCKETs,LPWSABUFlpBuffers,DWORDdwBufferCount,LPDWORDlpNumberOfBytesSent,DWORDdwFlags,const struct sockaddr FAR * lpTo,intiTolen,LPWSAOVERLAPPEDlpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,LPWSATHREADIDlpThreadId,LPINTlpErrno){ODS1(L" query send to... %s", g_szCurrentApp);// 拒绝所有目的端口为4567的UDP封包SOCKADDR_IN sa = *(SOCKADDR_IN*)lpTo;if(sa.sin_port == htons(4567)){intiError;g_NextProcTable.lpWSPShutdown(s, SD_BOTH, &iError);*lpErrno = WSAECONNABORTED;ODS(L" deny a sendto ");return SOCKET_ERROR;}return g_NextProcTable.lpWSPSendTo(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpTo, iTolen, lpOverlapped, lpCompletionRoutine, lpThreadId, lpErrno);}int WSPAPI WSPStartup(  WORD wVersionRequested,  LPWSPDATA lpWSPData,  LPWSAPROTOCOL_INFO lpProtocolInfo,  WSPUPCALLTABLE UpcallTable,  LPWSPPROC_TABLE lpProcTable){ODS1(L"  WSPStartup...  %s \n", g_szCurrentApp);if(lpProtocolInfo->ProtocolChain.ChainLen <= 1){return WSAEPROVIDERFAILEDINIT;}// 保存向上调用的函数表指针(这里我们不使用它)g_pUpCallTable = UpcallTable;// 枚举协议,找到下层协议的WSAPROTOCOL_INFOW结构WSAPROTOCOL_INFOWNextProtocolInfo;int nTotalProtos;LPWSAPROTOCOL_INFOW pProtoInfo = GetProvider(&nTotalProtos);// 下层入口IDDWORD dwBaseEntryId = lpProtocolInfo->ProtocolChain.ChainEntries[1];for(int i=0; i<nTotalProtos; i++){if(pProtoInfo[i].dwCatalogEntryId == dwBaseEntryId){memcpy(&NextProtocolInfo, &pProtoInfo[i], sizeof(NextProtocolInfo));break;}}if(i >= nTotalProtos){ODS(L" WSPStartup:Can not find underlying protocol \n");return WSAEPROVIDERFAILEDINIT;}// 加载下层协议的DLLint nError;TCHAR szBaseProviderDll[MAX_PATH];int nLen = MAX_PATH;// 取得下层提供程序DLL路径if(::WSCGetProviderPath(&NextProtocolInfo.ProviderId, szBaseProviderDll, &nLen, &nError) == SOCKET_ERROR){ODS1(L" WSPStartup: WSCGetProviderPath() failed %d \n", nError);return WSAEPROVIDERFAILEDINIT;}if(!::ExpandEnvironmentStrings(szBaseProviderDll, szBaseProviderDll, MAX_PATH)){ODS1(L" WSPStartup:  ExpandEnvironmentStrings() failed %d \n", ::GetLastError());return WSAEPROVIDERFAILEDINIT;}// 加载下层提供程序HMODULE hModule = ::LoadLibrary(szBaseProviderDll);if(hModule == NULL){ODS1(L" WSPStartup:  LoadLibrary() failed %d \n", ::GetLastError());return WSAEPROVIDERFAILEDINIT;}// 导入下层提供程序的WSPStartup函数LPWSPSTARTUP  pfnWSPStartup = NULL;pfnWSPStartup = (LPWSPSTARTUP)::GetProcAddress(hModule, "WSPStartup");if(pfnWSPStartup == NULL){ODS1(L" WSPStartup:  GetProcAddress() failed %d \n", ::GetLastError());return WSAEPROVIDERFAILEDINIT;}// 调用下层提供程序的WSPStartup函数LPWSAPROTOCOL_INFOW pInfo = lpProtocolInfo;if(NextProtocolInfo.ProtocolChain.ChainLen == BASE_PROTOCOL)pInfo = &NextProtocolInfo;int nRet = pfnWSPStartup(wVersionRequested, lpWSPData, pInfo, UpcallTable, lpProcTable);if(nRet != ERROR_SUCCESS){ODS1(L" WSPStartup:  underlying provider's WSPStartup() failed %d \n", nRet);return nRet;}// 保存下层提供者的函数表g_NextProcTable = *lpProcTable;// 修改传递给上层的函数表,Hook感兴趣的函数,这里做为示例,仅Hook了WSPSendTo函数// 您还可以Hook其它函数,如WSPSocket、WSPCloseSocket、WSPConnect等lpProcTable->lpWSPSendTo = WSPSendTo;FreeProvider(pProtoInfo);return nRet;}