Chinaunix首页 | 论坛 | 博客
  • 博客访问: 16500822
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 21:08:00

下载本文示例代码
  前一段时间研究了下QQ目前各种外挂的机理,包括著名的coralQQ。鉴于目前网上关于这方面的文章少之又少,一般能找到的应该就这下面3篇(由于可能涉及版权问题,我链接就不给出了:  a.木子版显IPQQ的制作教程  b.关于QQ外挂DLL的加载原理的分析  c.明日帝国(sunwangme)写的我是这样来做破解qq,做QQ外挂的系列  在开始我的分析前我简要对上面这些资料作下评价,首先我觉得如果你也想写个类似的外挂插件,他们的文章你是必看的,而且特别是你想真的写出什么有用的东西的话,明日帝国得文章一定要看,而且必须看懂。对于木子版的教程应该说是最早“公开”的资料了,很多人都是看了这个教程开始写自己的外挂的。但是他通过直接修改QQ来做显IP补丁,可能引起的法律问题不说(如果你只是自娱自乐的话),他不能适应不同版本的QQ,而且用户也不太能接受直接的修改,而且教程已经不能直接用于目前版本的QQ了。  第二个教程是做外挂DLL插件必看的,但是他丝毫没涉及显示IP的问题,只是简单介绍了DLL注入的问题,并对win9x环境下手动加载dll到进程空间作了分析。但是目前win9x已逐渐退出舞台,所以一般只要使用CreateRemoteThread即可。  第一部分:  1.1 主流的外挂插件如何获取IP和其他信息的?  也许你会认为他拦截了底层的Socket通讯?当然不至于,但这样肯定是最有效的办法。  让我们换个思路:如果你现在需要和一个QQ好友传输文件或者进行语音聊天或者发送了图片或自定义表情。那么QQ必须知道对方的IP地址和端口信息,这样才能把数据传给对方。  所以,很有可能QQ内部已经实现了获取IP地址和其他信息的相关函数了。的确如此。这也是木子版QQ教程里面提到的办法,调用QQ内部的函数。  下面是截至QQ组件之一的CQQApplication.dll中的汇编代码:(建议先浏览木子版QQ的教程)   027832C7 8B45 F0 mov eax,dword ptr ss:[ebp-10]  027832CA 53 push ebx  027832CB 68 38558302 push CQQAppli.02835538 ; ASCII dwIP  027832D0 50 push eax  027832D1 8B08 mov ecx,dword ptr ds:[eax]  027832D3 FF51 18 call dword ptr ds:[ecx 18]  027832D6 8B45 F0 mov eax,dword ptr ss:[ebp-10]  027832D9 53 push ebx  027832DA 68 40558302 push CQQAppli.02835540 ; ASCII wPort  027832DF 50 push eax  027832E0 8B08 mov ecx,dword ptr ds:[eax]  027832E2 FF51 14 call dword ptr ds:[ecx 14]   CQQApplication.dll通俗来说就是负责显示和实现QQ聊天窗口的模块。就是那些和xxx聊天中的窗口,所以这就是为什么要在其中寻找这样的代码的依据。  从上面的汇编来看,显然是调用了2个thiscall规范的函数,也就是我们所说的C 类成员函数。  2个成员函数的的大致形式是this->Func(void *ptr1,char *cmd,DWORD *ptr2);其中cmd就是上面dwIP、wPort这些字符串,而ptr2也很容易知道是函数返回值得存储指针。现在关键是要获取this指针,也就是ecx寄存器的数据和ptr1这个神秘指针的数据。  如果你有兴趣反汇编CoralQQ中相关的代码,也会发现与上面类似的调用部分。  这里暂时不深入这些函数的作用和那个cmd指针的细节,我们先来研究如何获取this指针和ptr2吧。  注意  027832DF 50 push eax  027832E0 8B08 mov ecx,dword ptr ds:[eax]  这2段代码,也就是说ptr2获取了,那么this指针也可以得到。所以现在一切的关键就是找出ptr2的来历。这样我们就能很轻松的实现显示ip了。  1.2 神秘的ptr2指针  为了能更快的说明问题,这里就不厚道的引用CoralQQ.dll的汇编了~   0056D97F 51 push ecx  0056D980 52 push edx  0056D981 50 push eax  0056D982 FF15 38AB5A00 call dword ptr ds:[5AAB38] ; BasicCtr.GetFriendQQData  0056D988 8B4424 14 mov eax,dword ptr ss:[esp 14]  0056D98C 83C4 0C add esp,0C  0056D98F 3BC3 cmp eax,ebx  0056D991 0F84 03020000 je CoralQQ.0056DB9A  0056D997 57 push edi  0056D998 895C24 14 mov dword ptr ss:[esp 14],ebx  0056D99C 8D5424 14 lea edx,dword ptr ss:[esp 14]  0056D9A0 52 push edx  0056D9A1 68 50BB5900 push CoralQQ.0059BB50  0056D9A6 C64424 30 01 mov byte ptr ss:[esp 30],1  0056D9AB 8B08 mov ecx,dword ptr ds:[eax]  0056D9AD 68 C8BA5900 push CoralQQ.0059BAC8 ; ASCII QQUSER_DYNAMIC_DATA  0056D9B2 50 push eax  0056D9B3 8B41 54 mov eax,dword ptr ds:[ecx 54]  0056D9B6 FFD0 call eax  0056D9B8 8B4424 14 mov eax,dword ptr ss:[esp 14]  0056D9BC 3BC3 cmp eax,ebx  0056D9BE 0F84 F9000000 je CoralQQ.0056DABD  0056D9C4 8B08 mov ecx,dword ptr ds:[eax]  0056D9C6 8D5424 1C lea edx,dword ptr ss:[esp 1C]  0056D9CA 52 push edx  0056D9CB 68 ACA15900 push CoralQQ.0059A1AC ; ASCII wProcotol  0056D9D0 50 push eax  0056D9D1 8B41 30 mov eax,dword ptr ds:[ecx 30]  0056D9D4 FFD0 call eax  0056D9D6 8B4424 14 mov eax,dword ptr ss:[esp 14]  0056D9DA 8B08 mov ecx,dword ptr ds:[eax]  0056D9DC 8D5424 10 lea edx,dword ptr ss:[esp 10]  0056D9E0 52 push edx  0056D9E1 68 94A15900 push CoralQQ.0059A194 ; ASCII dwRecentIP  0056D9E6 50 push eax  0056D9E7 8B41 34 mov eax,dword ptr ds:[ecx 34]  0056D9EA FFD0 call eax  以上代码正式coralQQ 4.5版获取IP信息的片断。我们只需要关注上面的0056D982和0056D9B6地址的2个调用函数。  为什么这样说了,先看下面获取dwRecentIP数据的代码,它和上面提到的那个成员函数是属于一个类的(这里没提供出完整代码,你可以自己验证下:-P)。那么这里的this指针从哪里来呢?  0056D9DA 8B08 mov ecx,dword ptr ds:[eax]  0056D9D6 8B4424 14 mov eax,dword ptr ss:[esp 14]  按照thiscall规范,ecx就保存了this指针,上面代码说明ecx是来自[esp 14]的,我们再往上看:   0056D99C 8D5424 14 lea edx,dword ptr ss:[esp 14]  0056D9A0 52 push edx  0056D9A1 68 50BB5900 push CoralQQ.0059BB50  0056D9A6 C64424 30 01 mov byte ptr ss:[esp 30],1  0056D9AB 8B08 mov ecx,dword ptr ds:[eax]  0056D9AD 68 C8BA5900 push CoralQQ.0059BAC8 ; ASCII QQUSER_DYNAMIC_DATA  0056D9B2 50 push eax  0056D9B3 8B41 54 mov eax,dword ptr ds:[ecx 54]  0056D9B6 FFD0 call eax  看到么0056D99C lea edx,dword ptr ss:[esp 14]!!  也就是说this指针和ptr2时由这个函数获得的,我们暂时以它的一个参数命名:QQUSER_DYNAMIC_DATA。  但不幸的是,这个函数同样也是thiscall调用规范的,也就说也是需要得到this指针……不过不慌:   0056D97F 51 push ecx  0056D980 52 push edx  0056D981 50 push eax  0056D982 FF15 38AB5A00 call dword ptr ds:[5AAB38] ; BasicCtr.GetFriendQQData  0056D988 8B4424 14 mov eax,dword ptr ss:[esp 14]   0056D9AB 8B08 mov ecx,dword ptr ds:[eax]  注意上面2段代码,QQUSER_DYNAMIC_DATA函数的this指针最终是[esp 14],而esp 14的数据是  0056D97F 51 push ecx  这段代码压入的。所幸的是GetFriendQQData是个导出函数(位于BasicCtrDll.dll),我们看看他的申明:  int GetFriendQQData(struct IQQCore *,unsigned long,struct IQQData * *);  上面这个push ecx实际上是压入了参数struct IQQData * *。  所以现在的只要获得struct IQQCore *,和第二个神秘参数的含义就能实现显示IP的功能了。共4页。 1 2 3 4 :   前一段时间研究了下QQ目前各种外挂的机理,包括著名的coralQQ。鉴于目前网上关于这方面的文章少之又少,一般能找到的应该就这下面3篇(由于可能涉及版权问题,我链接就不给出了:  a.木子版显IPQQ的制作教程  b.关于QQ外挂DLL的加载原理的分析  c.明日帝国(sunwangme)写的我是这样来做破解qq,做QQ外挂的系列  在开始我的分析前我简要对上面这些资料作下评价,首先我觉得如果你也想写个类似的外挂插件,他们的文章你是必看的,而且特别是你想真的写出什么有用的东西的话,明日帝国得文章一定要看,而且必须看懂。对于木子版的教程应该说是最早“公开”的资料了,很多人都是看了这个教程开始写自己的外挂的。但是他通过直接修改QQ来做显IP补丁,可能引起的法律问题不说(如果你只是自娱自乐的话),他不能适应不同版本的QQ,而且用户也不太能接受直接的修改,而且教程已经不能直接用于目前版本的QQ了。  第二个教程是做外挂DLL插件必看的,但是他丝毫没涉及显示IP的问题,只是简单介绍了DLL注入的问题,并对win9x环境下手动加载dll到进程空间作了分析。但是目前win9x已逐渐退出舞台,所以一般只要使用CreateRemoteThread即可。  第一部分:  1.1 主流的外挂插件如何获取IP和其他信息的?  也许你会认为他拦截了底层的Socket通讯?当然不至于,但这样肯定是最有效的办法。  让我们换个思路:如果你现在需要和一个QQ好友传输文件或者进行语音聊天或者发送了图片或自定义表情。那么QQ必须知道对方的IP地址和端口信息,这样才能把数据传给对方。  所以,很有可能QQ内部已经实现了获取IP地址和其他信息的相关函数了。的确如此。这也是木子版QQ教程里面提到的办法,调用QQ内部的函数。  下面是截至QQ组件之一的CQQApplication.dll中的汇编代码:(建议先浏览木子版QQ的教程)   027832C7 8B45 F0 mov eax,dword ptr ss:[ebp-10]  027832CA 53 push ebx  027832CB 68 38558302 push CQQAppli.02835538 ; ASCII dwIP  027832D0 50 push eax  027832D1 8B08 mov ecx,dword ptr ds:[eax]  027832D3 FF51 18 call dword ptr ds:[ecx 18]  027832D6 8B45 F0 mov eax,dword ptr ss:[ebp-10]  027832D9 53 push ebx  027832DA 68 40558302 push CQQAppli.02835540 ; ASCII wPort  027832DF 50 push eax  027832E0 8B08 mov ecx,dword ptr ds:[eax]  027832E2 FF51 14 call dword ptr ds:[ecx 14]   CQQApplication.dll通俗来说就是负责显示和实现QQ聊天窗口的模块。就是那些和xxx聊天中的窗口,所以这就是为什么要在其中寻找这样的代码的依据。  从上面的汇编来看,显然是调用了2个thiscall规范的函数,也就是我们所说的C 类成员函数。  2个成员函数的的大致形式是this->Func(void *ptr1,char *cmd,DWORD *ptr2);其中cmd就是上面dwIP、wPort这些字符串,而ptr2也很容易知道是函数返回值得存储指针。现在关键是要获取this指针,也就是ecx寄存器的数据和ptr1这个神秘指针的数据。  如果你有兴趣反汇编CoralQQ中相关的代码,也会发现与上面类似的调用部分。  这里暂时不深入这些函数的作用和那个cmd指针的细节,我们先来研究如何获取this指针和ptr2吧。  注意  027832DF 50 push eax  027832E0 8B08 mov ecx,dword ptr ds:[eax]  这2段代码,也就是说ptr2获取了,那么this指针也可以得到。所以现在一切的关键就是找出ptr2的来历。这样我们就能很轻松的实现显示ip了。  1.2 神秘的ptr2指针  为了能更快的说明问题,这里就不厚道的引用CoralQQ.dll的汇编了~   0056D97F 51 push ecx  0056D980 52 push edx  0056D981 50 push eax  0056D982 FF15 38AB5A00 call dword ptr ds:[5AAB38] ; BasicCtr.GetFriendQQData  0056D988 8B4424 14 mov eax,dword ptr ss:[esp 14]  0056D98C 83C4 0C add esp,0C  0056D98F 3BC3 cmp eax,ebx  0056D991 0F84 03020000 je CoralQQ.0056DB9A  0056D997 57 push edi  0056D998 895C24 14 mov dword ptr ss:[esp 14],ebx  0056D99C 8D5424 14 lea edx,dword ptr ss:[esp 14]  0056D9A0 52 push edx  0056D9A1 68 50BB5900 push CoralQQ.0059BB50  0056D9A6 C64424 30 01 mov byte ptr ss:[esp 30],1  0056D9AB 8B08 mov ecx,dword ptr ds:[eax]  0056D9AD 68 C8BA5900 push CoralQQ.0059BAC8 ; ASCII QQUSER_DYNAMIC_DATA  0056D9B2 50 push eax  0056D9B3 8B41 54 mov eax,dword ptr ds:[ecx 54]  0056D9B6 FFD0 call eax  0056D9B8 8B4424 14 mov eax,dword ptr ss:[esp 14]  0056D9BC 3BC3 cmp eax,ebx  0056D9BE 0F84 F9000000 je CoralQQ.0056DABD  0056D9C4 8B08 mov ecx,dword ptr ds:[eax]  0056D9C6 8D5424 1C lea edx,dword ptr ss:[esp 1C]  0056D9CA 52 push edx  0056D9CB 68 ACA15900 push CoralQQ.0059A1AC ; ASCII wProcotol  0056D9D0 50 push eax  0056D9D1 8B41 30 mov eax,dword ptr ds:[ecx 30]  0056D9D4 FFD0 call eax  0056D9D6 8B4424 14 mov eax,dword ptr ss:[esp 14]  0056D9DA 8B08 mov ecx,dword ptr ds:[eax]  0056D9DC 8D5424 10 lea edx,dword ptr ss:[esp 10]  0056D9E0 52 push edx  0056D9E1 68 94A15900 push CoralQQ.0059A194 ; ASCII dwRecentIP  0056D9E6 50 push eax  0056D9E7 8B41 34 mov eax,dword ptr ds:[ecx 34]  0056D9EA FFD0 call eax  以上代码正式coralQQ 4.5版获取IP信息的片断。我们只需要关注上面的0056D982和0056D9B6地址的2个调用函数。  为什么这样说了,先看下面获取dwRecentIP数据的代码,它和上面提到的那个成员函数是属于一个类的(这里没提供出完整代码,你可以自己验证下:-P)。那么这里的this指针从哪里来呢?  0056D9DA 8B08 mov ecx,dword ptr ds:[eax]  0056D9D6 8B4424 14 mov eax,dword ptr ss:[esp 14]  按照thiscall规范,ecx就保存了this指针,上面代码说明ecx是来自[esp 14]的,我们再往上看:   0056D99C 8D5424 14 lea edx,dword ptr ss:[esp 14]  0056D9A0 52 push edx  0056D9A1 68 50BB5900 push CoralQQ.0059BB50  0056D9A6 C64424 30 01 mov byte ptr ss:[esp 30],1  0056D9AB 8B08 mov ecx,dword ptr ds:[eax]  0056D9AD 68 C8BA5900 push CoralQQ.0059BAC8 ; ASCII QQUSER_DYNAMIC_DATA  0056D9B2 50 push eax  0056D9B3 8B41 54 mov eax,dword ptr ds:[ecx 54]  0056D9B6 FFD0 call eax  看到么0056D99C lea edx,dword ptr ss:[esp 14]!!  也就是说this指针和ptr2时由这个函数获得的,我们暂时以它的一个参数命名:QQUSER_DYNAMIC_DATA。  但不幸的是,这个函数同样也是thiscall调用规范的,也就说也是需要得到this指针……不过不慌:   0056D97F 51 push ecx  0056D980 52 push edx  0056D981 50 push eax  0056D982 FF15 38AB5A00 call dword ptr ds:[5AAB38] ; BasicCtr.GetFriendQQData  0056D988 8B4424 14 mov eax,dword ptr ss:[esp 14]   0056D9AB 8B08 mov ecx,dword ptr ds:[eax]  注意上面2段代码,QQUSER_DYNAMIC_DATA函数的this指针最终是[esp 14],而esp 14的数据是  0056D97F 51 push ecx  这段代码压入的。所幸的是GetFriendQQData是个导出函数(位于BasicCtrDll.dll),我们看看他的申明:  int GetFriendQQData(struct IQQCore *,unsigned long,struct IQQData * *);  上面这个push ecx实际上是压入了参数struct IQQData * *。  所以现在的只要获得struct IQQCore *,和第二个神秘参数的含义就能实现显示IP的功能了。共4页。 1 2 3 4 : 下载本文示例代码


编写QQ外挂插件的原理和方法编写QQ外挂插件的原理和方法编写QQ外挂插件的原理和方法编写QQ外挂插件的原理和方法编写QQ外挂插件的原理和方法编写QQ外挂插件的原理和方法编写QQ外挂插件的原理和方法编写QQ外挂插件的原理和方法编写QQ外挂插件的原理和方法编写QQ外挂插件的原理和方法编写QQ外挂插件的原理和方法编写QQ外挂插件的原理和方法编写QQ外挂插件的原理和方法编写QQ外挂插件的原理和方法编写QQ外挂插件的原理和方法
阅读(99) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~