• LSP(分层服务提供程序)


    一、简介

    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();
    }
  • 相关阅读:
    高频交易程序竟然是饿罗斯人开发的?
    系统功能在用户测试阶段被推翻
    去新华书店有感
    金桔
    结香
    金钟花
    金丝桃
    箬竹
    香茶菜
    水果兰
  • 原文地址:https://www.cnblogs.com/274914765qq/p/4729410.html
Copyright © 2020-2023  润新知