LSP劫持与网络数据转发代理服务器的心得笔记

前言

本文的目标读者是那些对LSP劫持有一定了解,也写了一些lsp程序,并想进一步深研lsp,意图做LSP代理工具的人。

如果读者对LSP没有一点了解,可以参考下面的文章:

网游加速器原理、技术与实现 的第5章节

VC++基于LSP实现数据拦截

LSP网络监控

正文

简介:

LSP是分层服务代理的英文简写。可以这么理解,windows中任何一个socket连接最终都要调用系统库,如wship6.dll,wshtcpip.dll等。但一个系统中可能有多个符合协议的dll库可以为socket连接服务。具体选哪个库通过查注册表得知。lsp与注册表的关系,可以参考:LSP修复工具原理

LSP技术就是创建一个符合官方标准的dll库,并将该dll库设置为默认库。

研究历程:

参考

网游加速器原理、技术与实现 的第5章节

VC++基于LSP实现数据拦截

LSP网络监控

这三篇文章后,我创建了一个dll库,可以拦截到socket的方法,比如send,recv等。不过有缺陷,现在我将碰到的问题一一说明。

一、如何查询socket的阻塞状态。

如果你看过网游加速器原理、技术与实现 的第5章节 ,文章 告诉你,非阻塞的socket与代理服务器的连接时要将socket连接设置为阻塞状态,与代理服务器连接后再与代理服务器进行协议握手。

但是如何查询socket是否是阻塞状态的呢?悲摧的是,windows貌似没有提供这样的查询函数。

VC++基于LSP实现数据拦截 的解决方法是不查询,宁可错杀三千,不肯放过一个,将所有socket都设置为阻塞状态,然后再恢复。这是有问题的。

经过我的研究,会让socket变为非阻塞的函数有三个,分别是ioctlsocket,wsaasyncselect,wsaeventselect。我们声明一个std::map的全局变量,并且lsp劫持这三个函数。当socket调用这三个函数时,就将相关信息记录到map全局变量中。于是我们就可以通过查询map变量,来了解socket是否是阻塞状态的。

二、与代理服务器握手的时机

通过解决上面的问题,在我们安装lsp之后,在部分场景下可以实现数据转发。但浏览网页时,却显示网络无法连接。我用的是2345浏览器,ie内核。经过调查,是因为浏览器在调用connect时返回-1;无论你如何阻塞socket,或者恢复socket,都无法解决这个问题。皇天不负有心人,后来查到一篇文章 :PRX 通过LSP实现浏览器Socks5/Tcp代理,里面将与代理服务器的握手功能从LPWSPConnect中转移到LPWSPSend中。 

这样的好处是"实际上在规避异步链接处理的问题 如果需要在connect时就进行handshake那么必须要对SOCKET 进行一系列的操作 最明显的一个例子就是需要剔除与此SOCKET的所有异步事件 如AsyncEvent、EventSelect等 同时需要将其转成同步的方式进行处理  还有一点如果是ConnectEx中处理在无hook的情况下会更不可实现 因为它可能会使用“完成端口” 而如果仅仅只是“完成例程”到是无妨;对于Chrome是可以直接返回NO_ERROR 但Firebox是不吃这一套的。"

按照此种方法修改代码,connect终于返回可用的socket,用浏览器访问网页也正常了。

三、chrome的坑

对于ie内核的浏览器,上面的方法就能很好的解决网页连接的问题。但是chrome内核的浏览器,如chrome,搜狗浏览器就无效了。甚至发现,lsp根本无法劫持到send,recv等函数。

chrome的坑还在研究中,后面有空更新吧。

猜你喜欢

转载自blog.csdn.net/sspdfn/article/details/86520816
今日推荐