在某项目中,需要用到LSP Hook,因为浏览器比较方便测试就使用了用IE内核的MFC程序并连接测试网页。
但发现在IE7、8 (9和10未测试)中都正常进入LSP Hook的WSPConnect,但是IE11未进入WSPPROC_TABLE.lpWSPConnect对应的跳板函数WSPConnect中,也就导致WSPConnect中修改目标ip等操作无效。
通过Api Monitor工具查看该程序的winsock2函数调用情况如下,发现并没有调用connect函数。
创建socket并设置参数
发送数据
在Api Monitor的监视窗口中,可以看到最后调用的WSASend函数中的buffer里的数据就是对网页的请求"GET /getip.php xxx..."。
但问题是,为何没有connect就可以发送数据?一开始怀疑是像ie11的cookie管理一样,交给了taskhost.exe进程,但通过netstats 查看,这个网络连接确实是测试程序自己连接的。
image.png
在网上也很少找到资料,无奈之中开始了ida反汇编之旅(自动下载了wininet.dll的调试符号)。经过摸索,发现以下代码:
建立socket
- 在CWxSocket::Initialize方法中使用
WSASocket ( AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT )建立一个socket。 - 使用CreateThreadpoolIo开启一个异步io线程池。
- 调用bind绑定(呃,这里不明白不用listen,为什么需要bind?)
setsockopt ( sock, IPPROTO_TCP, TCP_NODELAY,...WSAIoctl ( sock, SIO_TCP_SET_ACK_FREQUENCY...-
其它一些设置见图:
image.png
连接socket
wininet在访问http请求的整个流程上做了相当多的事情,都略过。最终找到新增了一个网络连接的操作在下面这个调用堆栈:
image.png
CWxSocket::ConnectRequest代码如下:
image.png
可以看到,它是使用了WSAIoctl加载了ConnectEx函数指针,然后调用ConnectEx进行异步连接的工作,完成后回调函数是CSocket::ConnectCompletion。
所以,接下来就是修改LSP Hook模块,添加对WSAIoctl的SIO_GET_EXTENSION_FUNCTION_POINTER参数的处理即可。












网友评论