项目中有个LSP模块需要对浏览器进行hook处理,而IE或Winnet模块使用了ConnectEx,然而替换了ConnectEx后并自己进行同步的connect之后,返回值怎么处理都会导致失败或IE卡住。
MyConnnectEx中尝试了以下组合:
1、 ERROR_IO_PENDING + return FALSE = 12029错误
2、return FALSE 12029错误
3、return TRUE 卡住
它调用ConnectEx时带了lpOverlapped参数,所以hook GetOverlappedResult和WsaGetOverlappedResult、GetQueuedCompletionStatus,但都没有触发。
在ConnectEx之后,反正不是卡住就是报错,没有对overlapped进行处理。
按之前的逻辑,socket不就那几种模型么,结果一种都对不上,直接上反汇编研究吧。
卡住时的地址:
image.png
查看MyConnnectEx被调用时的堆栈,结合IDA查看winet模块的处理逻辑:
image.png
发现它使用了StartThreadPoolIo相关函数,对这块了解较少,恶补了一下,细节不表。
在设置的回调函数IoCompletionCallback 里的处理逻辑如下:
image.png
本以为可以hook相关函数,并且在MyConnectEx中手动触发IoCompletionCallback ,但是这个第一个参数是个问题,如果被拦截的不是wininet,而是自己写的代码,没有处理第一个参数的情况下,能测试成功。
但是在wininet的函数中,第一行即是 CallbackMayRunLong(instance);,而这个参数没找到办法伪造。传nullptr,或者上次IoCompletionCallback 被系统调用时的指针,都会导致程序崩溃。
后面用个不太优雅的方式,在ConnecEx消掉wininet触发的StartThreadIo,打开一个文件,用原socket CreateThreadpoolIo时的一些参数重建一个io并绑定文件句柄。然后用ConnecEx的overlapped参数进行异步读文件以及异步进行读操作,然后触发回调。
网友评论