首页
社区
课程
招聘
[旧帖] [原创]分析QQ是如何检查网络状况并自动重新上线的 [邀请码已发] 0.00雪花
发表于: 2011-10-20 12:25 3858

[旧帖] [原创]分析QQ是如何检查网络状况并自动重新上线的 [邀请码已发] 0.00雪花

2011-10-20 12:25
3858
本人发现一些IM在网络异常后,如何决定自动重新上线这个问题上,QQ做得不错。

比如我将本地连接给禁用了或者发现异常后。我觉得对于UDP这种通信模式的应用软件是不容易立刻检测到网络异常的。但是就我测试发现QQ有这样的检测机能。他会检测到网络是不可用的,所以不会盲目的自动不断尝试重新登录(小企鹅一直灰色)。而当我重新启用本地连接后,QQ几乎立刻就检测到网络可用。自动重新登录(小企鹅挥动起来了)。
作为一个要保持在线的桌面应用软件,这个检测机制确实很有意义。

问题:QQ是如何快速得到本地网络可用的呢?
思路:是否windows有这样的事件通知接口?

先OD挂上QQ, 验证这个思路我首先想到QQ检测到网络不可用后立刻托盘图标变灰色。于是下断点Shell_NotifyIconW,然后手动禁用本地连接。断点立刻触发。开始检测栈回溯的相关代码。

[图1]


回溯返回后看到的显然不是我想要的:通过这3个API断定是QQ自己实现的一个消息队列机制。一个线程一直到执行WaitForSingleObject等待事件。事件等待其他线程插入队列消息后处理之。 查看hEvent的值后继而需要“条件断点”SetEvent了。重复启用本地连接再禁用本地连接,这样可以断下想要的那个关键线程。断下SetEvent后查看耐心的翻阅回溯栈的相关代码,我也是走马观花的看,突然某代码段一个字符串“OnConnectionBroken”出现让我喜出望外啊,QQ内部有很多方便Log而加上去的字符串信息对我这种肤浅的分析人是很有意义的。
[图2]


继而在附近发现QQ的Common.dll有个导出函数,函数名是IsNetConnectionOK,显然核心代码是他了。剩下的精力就应该是深入IsNetConnectionOK。
[图3]

IsNetConnectionOK这个函数根据断点发生频率是有一个Timer大概每3秒会触发一次。但是我在win7下测试的实际情况,禁用网络连接后发现几乎一直不需要有2或3秒的延时。

针对是否windows有类似OnConnectionBroken这样的事件通知接口,如果有那么QQ也不用搞个timer不停的执行IsNetConnectionOK。

IsNetConnectionOK 内部有一处代码调用了CoCreateInstance,根据参数的CLSID搜索出来的系统组件叫CLSID_NetworkListManager,这个MSDN上介绍只有vista+的系统才有。我自己也折腾了一下这个接口写了点测试代码,后来发现MSDN有C++和C#的sample。
MSDN sample:
C#:  http://ppe.archive.msdn.microsoft.com/NLM/Release/ProjectReleases.aspx?ReleaseId=3010
C++: http://ppe.archive.msdn.microsoft.com/NLM/Release/ProjectReleases.aspx?ReleaseId=3011

Vista+的环境可以用CLSID_NetworkListManager组件接口事件通知快速检测系统网络是否可用。
至于XP环境如何快速检测本地网络是否可用,timer是必须的了,具体还得深入了解IsNetConnectionOK。里面的代码量也不少。由于我目前时间有限打算日后再深入研究。

此贴也就是抛砖引玉,如果你知道细节的话就麻烦抛出玉来吧。省下菜鸟们的一点时间和精力。 如果各位看官不过瘾急着要了解XP环境的检测手段,就先自己操刀分析IsNetConnectionOK。

NLM_sample.rar

[课程]Android-CTF解题方法汇总!

上传的附件:
收藏
免费 1
支持
分享
最新回复 (10)
雪    币: 54
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
路过,学习,打酱油
2011-10-20 12:37
0
雪    币: 602
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
根本不用Timer 有这样的函数
2011-10-20 13:02
0
雪    币: 128
活跃值: (27)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
请问是什么函数呢
2011-10-20 19:51
0
雪    币: 527
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
分享了 受教了
2011-10-21 08:49
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
总是需要学习啊
2011-10-21 08:56
0
雪    币: 141
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
路过,学习,打酱油
2011-10-21 09:18
0
雪    币: 24
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
学习顶下
2011-10-24 07:09
0
雪    币: 1644
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
IsNetConnectionOK是Program Files\QQ2009\bin\Common.dll中导出的, 分析Common.dll因该就可以知道检测方式。
2011-10-24 11:12
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
10
2011 里面没有发现这个导出函数。
2011-10-24 12:56
0
雪    币: 138
活跃值: (460)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
IsNetConnectionOK 内部有一处代码调用了CoCreateInstance,根据参数的CLSID搜索出来的系统组件叫CLSID_NetworkListManager,这个MSDN上介绍只有vista+的系统才有。我自己也折腾了一下这个接口写了点测试代码,后来发现MSDN有C++和C#的sample。
MSDN sample:
C#: http://ppe.archive.msdn.microsoft.com/NLM/Release/ProjectReleases.aspx?ReleaseId=3010
C++: http://ppe.archive.msdn.microsoft.com/NLM/Release/ProjectReleases.aspx?ReleaseId=3011


连接好像被墙了, 如果方便楼主可否复制一篇c++的doc 附件下?  多谢了
2011-12-5 06:25
0
游客
登录 | 注册 方可回帖
返回
//