一、简介
LSP即分层服务提供商,Winsock 作为应用程序的 Windows 的网络套接字工具,可以由称为“分层服务提供商”的机制进行扩展。Winsock LSP 可用于非常广泛的实用用途,包括 Internet 家长控制 (parental control) 和 Web 内容筛选。在以前版本的 Windows XP 中,删除不正确的(也称为“buggy”)LSP 可能会导致注册表中的 Winsock 目录损坏,潜在地导致所有网络连接的丢失。 LSP就是TCP/IP等协议的接口.LSP用在正途上可以方便程序员们编写监视系统网络通讯情况的Sniffer,可是现在常见的LSP都被用于浏览器劫持。
二、LSP操作
netsh winsock
option:
? - 显示命令列表。
audit - 显示已经安装和删除的 Winsock LSP 列表。
dump - 显示一个配置脚本。
help - 显示命令列表。
remove - 从系统中删除 Winsock LSP。
reset - 重置 Winsock 目录为清除状态。
set - 设置 Winsock 选项。
show - 显示信息。
若需要命令的更多帮助信息,请键入命令,接着是空格,
后面跟 ?。
常用指令
netsh winsock show catalog #显示已经安装LSP 列表
netsh winsock reset #重置Winsock LSP
三、实现LSP
步骤如下:
1、安装分层协议入口,以便获取系统分配的目录ID号。 2、安装一个或者多个协议链,安装的数量取决于要分层的下层协议的数量。 3、在结尾进行目录排序。
四、示例
//////////////////////////////////////////////////////// // InstDemo.cpp #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); } // 将LSP安装到UDP协议提供者之上 int InstallProvider(WCHAR *wszDllPath) { WCHAR wszLSPName[] = L"TinyLSP"; // 我们的LSP的名称 int nError = NO_ERROR; LPWSAPROTOCOL_INFOW pProtoInfo; int nProtocols; WSAPROTOCOL_INFOW UDPLayeredInfo, UDPChainInfo; // 我们要安装的UDP分层协议和协议链 DWORD dwUdpOrigCatalogId, dwLayeredCatalogId; // 在Winsock目录中找到原来的UDP协议服务提供者,我们的LSP要安装在它之上 // 枚举所有服务程序提供者 pProtoInfo = GetProvider(&nProtocols); for(int i=0; i<nProtocols; i++) { if(pProtoInfo[i].iAddressFamily == AF_INET && pProtoInfo[i].iProtocol == IPPROTO_UDP) { memcpy(&UDPChainInfo, &pProtoInfo[i], sizeof(UDPLayeredInfo)); // UDPChainInfo.dwServiceFlags1 = UDPChainInfo.dwServiceFlags1 & ~XP1_IFS_HANDLES; // 保存原来的入口ID dwUdpOrigCatalogId = pProtoInfo[i].dwCatalogEntryId; break; } } // 首先安装分层协议,获取一个Winsock库安排的目录ID号,即dwLayeredCatalogId // 直接使用下层协议的WSAPROTOCOL_INFOW结构即可 memcpy(&UDPLayeredInfo, &UDPChainInfo, sizeof(UDPLayeredInfo)); // 修改协议名称,类型,设置PFL_HIDDEN标志 wcscpy(UDPLayeredInfo.szProtocol, wszLSPName); UDPLayeredInfo.ProtocolChain.ChainLen = LAYERED_PROTOCOL; // LAYERED_PROTOCOL即0 UDPLayeredInfo.dwProviderFlags |= PFL_HIDDEN; // 安装 if(::WSCInstallProvider(&ProviderGuid, wszDllPath, &UDPLayeredInfo, 1, &nError) == SOCKET_ERROR) return nError; // 重新枚举协议,获取分层协议的目录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]; swprintf(wszChainName, L"%ws over %ws", wszLSPName, UDPChainInfo.szProtocol); wcscpy(UDPChainInfo.szProtocol, wszChainName); if(UDPChainInfo.ProtocolChain.ChainLen == 1) { UDPChainInfo.ProtocolChain.ChainEntries[1] = dwUdpOrigCatalogId; } else { for(i=UDPChainInfo.ProtocolChain.ChainLen; i>0 ; i--) { UDPChainInfo.ProtocolChain.ChainEntries[i] = UDPChainInfo.ProtocolChain.ChainEntries[i-1]; } } UDPChainInfo.ProtocolChain.ChainLen ++; // 将我们的分层协议置于此协议链的顶层 UDPChainInfo.ProtocolChain.ChainEntries[0] = dwLayeredCatalogId; // 获取一个Guid,安装之 GUID ProviderChainGuid; if(::UuidCreate(&ProviderChainGuid) == RPC_S_OK) { if(::WSCInstallProvider(&ProviderChainGuid, wszDllPath, &UDPChainInfo, 1, &nError) == SOCKET_ERROR) return nError; } else return GetLastError(); // 重新排序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目录 nError = ::WSCWriteProviderOrder(dwIds, nIndex); FreeProvider(pProtoInfo); return nError; } void 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); } } //////////////////////////////////////////////////// int binstall = 0; void main() { if(binstall) { if(InstallProvider(L"lsp.dll") == ERROR_SUCCESS) { printf(" Install successully "); } else { printf(" Install failed "); } } else RemoveProvider(); }