一、简介

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 \n");
}
else
{
printf(" Install failed \n");
}
}
else
RemoveProvider();
}

LSP(分层服务提供程序)的更多相关文章

  1. node socket :10106无法加载或初始化请求的服务提供程序

    node socket :10106无法加载或初始化请求的服务提供程序 无端端的,不知道怎么回事,node突然就坏掉 了,应该是某些配置无意中改动了,问题如下: 目前能想到的解决办法就是:重置配置,用 ...

  2. 在WPF中使用.NET Core 3.0依赖项注入和服务提供程序

    前言 我们都知道.NET Core提供了对依赖项注入的内置支持.我们通常在ASP.NET Core中使用它(从Startup.cs文件中的ConfigureServices方法开始),但是该功能不限于 ...

  3. wcf 错误:无法加载或初始化请求的服务提供程序

    解决办法:cmd netsh winsock reset 恢复网络编程接口

  4. sql2008r2,以前好好可以用的,但装了vs2017后,连接不上了,服务也停了,结果手动也 启动不了, 无法加载或初始化请求的服务提供程

    日志: 2017-12-14 12:33:17.53 服务器 A self-generated certificate was successfully loaded for encryption.2 ...

  5. 无任何网络提供程序接受指定的网络路径(系统服务里没有workstation服务)

    今天同事访问公司服务器时,提示“无任何网络提供程序接受指定的网络路径”,网络ping正常,把防火墙关掉,再次尝试问题如故. 于是上网搜索: 1.服务停止:一般有workstation,server,c ...

  6. “数据提供程序或其他服务返回 E_FAIL 状态”

    “数据提供程序或其他服务返回 E_FAIL 状态” 的问题 ADO 连接SQL SERVER

  7. ADO.NET入门教程(二)了解.NET数据提供程序

    出处:http://www.cnblogs.com/liuhaorain/archive/2012/02/11/2346312.html 1. 什么是.NET数据提供程序? .NET Framewor ...

  8. “基础提供程序在Open上失败”

    本来布置在IP为[x.x.x.x]的WCF服务好好的,但是今天突然就有问题了,一调用报错"基础提供程序在Open上失败"... 服务器上的有问题,先试试本地的服务能不能用吧,连的都 ...

  9. 如何 ︰ 执行批量更新和插入使用.NET 提供程序在 C#.NET OpenXML

    https://support.microsoft.com/zh-cn/kb/315968 如何 ︰ 执行批量更新和插入使用.NET 提供程序在 C#.NET OpenXML Email Prin ...

随机推荐

  1. SharePoint2013 Online中InfoPath 无法调用WebService

    传说微软office365中国区服务器已经迁移到国内,试了下速度果然比之前快了很多,不过随后测试了个简单的功能,还是直接被打击了. 准备在online版本中做一个简单的报销流程测试测试,于是先用Inf ...

  2. 在vue中无论使用router-link 还是 @click事件,发现都没法从列表页点击跳转到内容页去

    在vue中如论使用router-link 还是 @click事件,发现都没法从列表页点击跳转到内容页去,以前都是可以的,想着唯一不同的场景就是因为运用了scroll组件(https://ustbhua ...

  3. oracle版本及字符集查询

    查询oracle版本:select * from v$version; 查询oracle字符集:select * from nls_database_parameters;

  4. TCP 、UDP、IP包的最大长度

    1.概述 首先要看TCP/IP协议,涉及到四层:链路层,网络层,传输层,应用层. 其中以太网(Ethernet)的数据帧在链路层 IP包在网络层 TCP或UDP包在传输层 TCP或UDP中的数据(Da ...

  5. GOF23设计模式之享元模式(flyweight)

    一.享元模式概述 内存属于稀缺资源,不要随便浪费.如果有很多个完全相同或相似的对象,可以通过享元模式,节省内存. 享元模式核心: (1)享元模式可以共享的.方式高效的支持大量细粒度对象的重用: (2) ...

  6. 小峰Hibernate简介与HelloWorld

    一.Hibernate简介: 二.Hibernate4 版Hello World 实现 工程结构: com.cy.model.Student: package com.cy.model; public ...

  7. git clone 后使用子分支

    git clone 项目git地址 git branch -a 切换到子分支进行开发 git ckeckout 子分支名称,如:git checkout dev_feature_call git pu ...

  8. BP神经网络的数学原理及其算法实现

    什么是BP网络 BP网络的数学原理 BP网络算法实现 转载请声明出处http://blog.csdn.net/zhongkejingwang/article/details/44514073  上一篇 ...

  9. Fastq 常用软件

    文章转载于 Original 2017-06-08 Jolvii 生信百科 由于生物信息的大部分工作都是在没有 root 权限的集群上进行的,本期我主要介绍一下非 root 用户怎么安装常用的软件.工 ...

  10. 22_java之File对象

    01IO技术概述 * A:IO技术概述 * a: Output * 把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作 * b: Input * 把持久设备上的数据读取到内存中的这 ...