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 \n");
}
else
{
printf(" Install failed \n");
}
}
else
RemoveProvider();
}
LSP(分层服务提供程序)的更多相关文章
- node socket :10106无法加载或初始化请求的服务提供程序
node socket :10106无法加载或初始化请求的服务提供程序 无端端的,不知道怎么回事,node突然就坏掉 了,应该是某些配置无意中改动了,问题如下: 目前能想到的解决办法就是:重置配置,用 ...
- 在WPF中使用.NET Core 3.0依赖项注入和服务提供程序
前言 我们都知道.NET Core提供了对依赖项注入的内置支持.我们通常在ASP.NET Core中使用它(从Startup.cs文件中的ConfigureServices方法开始),但是该功能不限于 ...
- wcf 错误:无法加载或初始化请求的服务提供程序
解决办法:cmd netsh winsock reset 恢复网络编程接口
- sql2008r2,以前好好可以用的,但装了vs2017后,连接不上了,服务也停了,结果手动也 启动不了, 无法加载或初始化请求的服务提供程
日志: 2017-12-14 12:33:17.53 服务器 A self-generated certificate was successfully loaded for encryption.2 ...
- 无任何网络提供程序接受指定的网络路径(系统服务里没有workstation服务)
今天同事访问公司服务器时,提示“无任何网络提供程序接受指定的网络路径”,网络ping正常,把防火墙关掉,再次尝试问题如故. 于是上网搜索: 1.服务停止:一般有workstation,server,c ...
- “数据提供程序或其他服务返回 E_FAIL 状态”
“数据提供程序或其他服务返回 E_FAIL 状态” 的问题 ADO 连接SQL SERVER
- ADO.NET入门教程(二)了解.NET数据提供程序
出处:http://www.cnblogs.com/liuhaorain/archive/2012/02/11/2346312.html 1. 什么是.NET数据提供程序? .NET Framewor ...
- “基础提供程序在Open上失败”
本来布置在IP为[x.x.x.x]的WCF服务好好的,但是今天突然就有问题了,一调用报错"基础提供程序在Open上失败"... 服务器上的有问题,先试试本地的服务能不能用吧,连的都 ...
- 如何 ︰ 执行批量更新和插入使用.NET 提供程序在 C#.NET OpenXML
https://support.microsoft.com/zh-cn/kb/315968 如何 ︰ 执行批量更新和插入使用.NET 提供程序在 C#.NET OpenXML Email Prin ...
随机推荐
- 抽象工厂模式(abstract)创建型模式
(一)简单工厂模式? 现在的学习是面向对象面向接口的,但是执行时的操作需要实例化后的对象.随着我们需要的类的增加,我们就需要把这些共同的东西提取出来,放在一个抽象类中,让这些子类来继承抽象类.当我们调 ...
- GOF23设计模式之迭代器模式(iterator)
一.迭代器模式概述 提供一种可以遍历聚合对象的方式.又称为:游标(cursor)模式 结构: (1)聚合对象:存储数据 (2)迭代器:遍历数据 二.迭代器模式示例代码 定义:正向遍历迭代器和逆向遍历迭 ...
- clientHeight , scrollHeight , offsetHeight之间的区别及兼容方案
clientHeight , scrollHeight , offsetHeight相信每个人都用过,可是每次用都要查一下到底哪个是文档大小哪个是视口大小,还有头疼的兼容问题. 先来官方的了解一下这三 ...
- ThinkPHP Http工具类(用于远程采集 远程下载) phpSimpleHtmlDom采集类库_Jquery筛选方式 使用phpQuery轻松采集网页内容http://www.thinkphp.cn/extend/541.html
[php]代码库 view sourceprint? <?php // +------------------------------------------------------------ ...
- 关于调整TimePicker, DatePicker的大小,样式
最近在做一个时间选择器,想把要DatePicker和TimePicker放在一起使用,无赖他们的大小样式是被Google写死了,找不到相应的属性来设置,自己花了点时间写了一个使用的Demo,运行的效果 ...
- 检测SqlServer服务器性能
通过性能监视器监视 Avg. Disk Queue Length 小于2 Avg. Disk sec/Read , Avg. Disk sec/Write 小于10ms 可以用数据收集器定时收集 ...
- spring 4.0+quartz2.2 实现持久化
最近在搭建框架 用到quartz持久化这块 查了一些文档 如下配置即可. 这里是quartz官方提供配置步骤 http://www.quartz-scheduler.org/ Quartz包含三个抽 ...
- python 打造一个sql注入脚本 (一)
0x00前言: 昨天刚刚看完小迪老师的sql注入篇的第一章 所以有了新的笔记. 0x01笔记: sql注入原理: 网站数据传输中,接受变量传递的值未进行过滤,导致直接带入数据库查询执行的操作. sql ...
- 新浪微博Oauth2.0授权 获取Access Token
新浪微博开放平台提供了丰富的API接口,利用这些接口,开发者能够开发出独具特色的微博应用.但是,大部分接口都需要用户授权给应用,应用利用授权得到的Access Token来调用相应的接口来获取内容. ...
- 数据分析之Numpy-数组计算
引言 : 数据分析 : 就是把隐藏在一些看似杂乱无章的数据背后的信息提炼出来,总结出研究对象的内在规律 . 数据分析三剑客 : Numpy 数组计算 Pandas 表计算与数据分析 ...