网络完成端口模型的流程
对于接收数据,如果是recv函数那就是开一个多线程一个while循环不停收数据然后解密数据 在投递数据 进入 处理队列,另外一个线程再通过队列去处理数据
但WSASend 和 WSARecv就不一样了又变成了单线程操作
比如WSASend函数 前面进行的组包,加密再调用这个函数,一调用这个函数马上就结束了,数据并没有发送完成, 发送这个东西是由WSASend和操作系统协作去完成的,如果需要发送失败或者发送成功的消息WSASend会接到通知 (当然是利用回调函数这一类操作),接到通知就去处理
WSARecv呢,因为不知道什么时候接收消息,一般都是建立连接首先调用WSARecv函数,调用以后马上可以做别的事情了,有消息到了以后,还可以利用完成端口,完成端口就告诉有消息进来了,就可以去处理这个消息,就到了解密数据 处理数据
完成端口模型
- 创建完成端口:CreateIOCompletionPort
- 投递完成端口 WSARecv
- 完成端口维护线程:
循环
{
查询完成端口状态 GetQueuedCompletionStatus
根据完成端口接口类型执行对应操作
再次投递完成端口请求WSARecv
}
给了一个回执,我们就可以通过自定义一个结构加上完成端口给我们约定的重叠结构,通过这两种结构就可以拿到想要的东西。(有可能不完整,就要再次读入)
然后就要感觉收到的请求依次去处理 就会有针对WSASend的处理,WSARecv的处理..accept的处理... 这里面就会有解密数据,解密完数据以后,把数据分发给客户端去处理然后再调用WSARecv
然后就有两种思路
- 可以通过WSARecv,要调用这个代表处理完了数据,就看他前面的这一系列东西
- 通过GetQueuedCompletionStatus找到完成端口响应的过程,在后面找到和WSARecv有关联的,找到中间过程,在中间过程中找到可以识别的内容 比如buffer lenth 有了这两项数据,关于recv的解读就可以开始了
首先登录了 这个时候完成端口已经创建 WSARecv已经投递
WSARecv和WSASend可不是一个线程 线程ID就不一样
会到一个循环里面 :
一直回跳 发现没反应了 表明已经进入循环
这个函数里有一个最最重要的参数就是它的重叠结构,这个重叠结构里会记录它的类型、其他关联数据...每个设计的都不一样,但下面肯定是会根据不同的情况执行不同的操作
回到WSARecv
再在 这个函数下断往回走
这个调用了Recv
继续往前走
这个调用了edx ,edx要不是虚函数要不是函数指针,看看是啥情况
它来自esi+eax*4+204 那肯定是个函数指针了
这个函数指针调用了Recv函数
eax决定了函数指针执行哪个操作,继续往前走
这个的上面就是查询完成端口了,也是进入了循环
这个完成端口不是为一个Recv设计的,而是为很多流程设计的,所以这个地方要密切关注的还有其他的地方咋办,所以这里要精确的吧Recv的流程筛选出来
这个函数下断直接就断下来了,进去看看没看到之前打了备注的函数,那么 这个函数就是一个分叉口
这个函数又是个虚函数看看这个edi是啥
edi来自 esp+10
再看看完成端口参数
看一眼文档:
执行完:
得到了数据长度 1E
edi!=NULL 就把这个放ecx里 看一眼
这个就是重叠结构的指针了
eax来自这个 看看edi
eax = 01情况下执行recv
所以这个过程就是处理recv了
函数尾部再次调用Recv 没毛病
所以数据的解密和数据的处理都是在这一块,我们还需要明文信息
给所有函数下断 看参数
发现在这个函数参数中
出现了我们要的东西
但长度06 不太应该 ,往下再看看
别的没长度信息 就不看了,基本就这俩
这俩还是同一个函数,两次调用
一开始 长度是1B
这里又读了一个大小
比较和6 比6大一直跑
后面又来了这波操作
....
然后ebx变成了15
这个数据分了两次处理 或者N次处理 处理完之后才是真正数据包的内容
改一下这个值 发现接收到的数据也变了
这下我们看看这个数据包好不好解读
02 06 00 4D 61 73 74 65 72 14 00 31 31 32 32 33 33 34 34 35 35 36 36 37 37 38 38 39 39
02是说话的频道type
也就是头部
02
06 00
4D 61 73 74 65 72
14 00
31 31 32 32 33 33 34 34 35 35 36 36 37 37 38 38 39 39
在抓一个
那改05就是工会频道了
试了试果然如此
分析就差不多到这了。