Windows下创建不使用LSP的套接字

Windows下创建不使用LSP的套接字

LSP:LayeredService Provider,分层服务提供程序,是Windows提供的一种hook socket的标准机制,通过LSP可以实现如流量监控,网络加速器,代理等功能,也可以用来DLL注入。

问题:修改网络底层代码后,机器上出现连接失败的情况,表现为连接必然失败,换回老版本后正常,老版本组件使用select网络模型,新版本组件使用iocp,估计问题就出在这里。

我们可以通过命令netshwinsock show catalog查看本机已经安装的LSP组件。对于不同的地址类型(IPv4,IPv6等),Socket类型,协议类型,都有对应的服务提供程序,在没有安装任何第三方LSP时,默认使用的IPv4的UDP、TCP是下面两个,其实都是同一个DLL。

简单介绍下输出的信息:地址族,Socket类型与协议分别对应了::socket函数的三个参数,AF_INET=2; SOCK_STREAM=1,SOCK_DGRAM=2; IPPROTO_TCP=6,IPPROTO_UDP=17。目录项ID是每个SP的ID,本机唯一。协议链长度表示这是一个分层协议链或基础协议链,长度为1表示是一个基础协议链,默认情况下机器上是只有基础协议链的。

顺便提一句,我们使用::socket函数的时候,最后一个protocol参数写0表示查找Socket类型匹配的第一个SP。用netsh这个命令得到的列表是按目录项ID(Entry ID)排序的,第三方的LSP会排在靠下面,但是在调用::socket查询可用SP的时候不是按这个顺序,真实的顺序可以用WSAEnumProtocols或WSCEnumProtocols来获取。其实这些API,命令行都是从注册表中来获取LSP信息的,WSCInstallProvider这类操作LSP的API也是通过修改注册表来实现安装,移除LSP注册信息。

注册表路径:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\WinSock2\

这里给出常用的协议类型定义,用户过socket API的不必多解释了

翻到后面就可以发现这个东西了,可以发现这个LSP的类型对应了IPv4的TCP套接字,再下面还有NSP(命名空间提供程序),,这个和我们的问题没太大关系了。

下一步就是找到这个DLL所属的程序,然后把这个程序卸载掉。比较暴力的话可以直接使用netsh winsock reset来重置LSP设置,直接删除LSP对应的DLL后一般会直接无法上网。

注意有些程序没有打开时,也会默认关联到这个程序的LSP。比如ProxyCap,Proxifier,可以设置对具体某个软件进行代理,但是没有代理的软件同样也经会过他们的LSP程序。

删除对应软件后,程序功能恢复正常,证明我们的怀疑是正确的,下面就是要找到方法不使用第三方分层协议,只使用微软提供的基础协议,这里最终使用的方法并不复杂,但有一些坑需要注意。

首先使用WSCEnumProtocols来查看协议链信息,发现TSFilter这个协议是排在最前面的,并且Socket Type与Protocol都与微软的相同,也就是我们指定::socket函数的第三个参数,还是会把TSFilter加载起来。

Windows上除了socket函数外,还有一个WSASocket函数也可以创建套接字,这个函数支持传入一个WSAPROTOCOL_INFO结构,通过这个结构就可以指定基础协议链了。

坑1:使用socket创建套接字后,如果我们使用getsockopt来获取socket的协议信息,那么我们得到的信息表示这个socket是微软的基础协议,其实这个信息是错误的,原因在于LSP程序没有正确处理getsockopt函数,调用被直接转给下层LSP处理,所以我们得到的是下层的LSP的协议信息。

坑2:在一些极端情况下,微软的基础协议链可能会被完全干掉,比如一些监控软件,拨号软件。这种情况下使用上面的WSASocket就会失败,这里需要做好保护。

其他:这里其实还有其他实现方法,如Hook注册表,Hook socket函数等。这里使用的WSASocket方法有一定局限性,需要修改所有创建socket的地方。

路遥知马力,日久见人心。

Windows下创建不使用LSP的套接字

相关文章:

你感兴趣的文章:

标签云: