联众升级协议分析1

来源:互联网 发布:head first sql 编辑:程序博客网 时间:2024/04/29 05:07

[ 转载]
联众升级协议分析

云网(jimzj@21cn.com)

记得刚到大学时,第一件和大家一起玩的就是打牌,相信很多人都会有这个经历;我也是在那时候学会升级(拖拉机)的。

大二时曾经疯狂玩过,所以对升级一直都很情有独衷;但工作后,一方面找不到人,另一方面就算找到人了也不能像以前一样通

宵的去玩。还好,一次看到别人在网上玩联众的升级,呵呵,从此后不怕找不到人了,工作之余可以随时和别人玩一下,过一把

隐;说了这么多,还没有转入正题,不意思。

       对于做外挂,以前没有做过,因为没有很多时间,所以也没有在网上去详细的找相关的网站,如果那一位有很多这方面的资

料的话,不防贴出来与大家共享一下。

       一、对于外挂,首先我们谈一下数据的获取:

      

       1、对于动作游戏类:可以通过API发命令给窗口或API控制鼠标、键盘等,使游戏里的人物进行流动或者攻击,这个是

对于本地游戏而言的,网上有很多这方面的介绍,在这里就不再写了。

 

       2、截获消息:通过hook技术,获到与游戏相关的数据,之后就看你自己怎么处理这些数据了 :)。

      

       3、拦截socket包:要替换winSock.dll或者winsock32.dll,我们写的替换函数要和原来的函数一致才行,就是说它的函数输出

什么样的,我们也要输出什么样子的函数,而且参数,参数顺序都要一样才行,然后在我们的函数里面调用真正的winSock32.dll里面

的函数就可以了。当游戏进行的时候它会调用我们的动态库,然后从我们的动态库中处理完毕后才跳转到真正动态库的函数地址,

这样我们就可以在里面处理自己的数据了;不过这程方法要自已重新去写如下面的一个例子:

       void * pSocketFun = GetProcAddress( i, "WSAStartup" );

       WSAStartup1 = (int(_stdcall *)( WORD, LPWSADATA ))pSocketFun;

winSock32.dll里有有这么多的函数,要自己一个一个的替换,有不是很累,这个动态库还是公用的,万一那一个地方写错了,不

是会出很大问题,所以还是觉得这个方法不是很好。

 

       4、直接监听网络数据包:这个方法就和sniffer和comview所用的技术差不多了,不过我们并不要直接去监听到网络层或以下

的数据包,只要到IP层的就可以了;

       利用 Raw Socket: 原始套接字

    它来发送和接收 IP 层以上的原始数据包,如 ICMP、TCP、UDP...等,一般的游戏数据量不大的话多采用TCP协议传输数据,

如联众游戏的升级就是这样,但如泡泡堂采用的就是UDP发送了,数据量很大。关于这种方法介绍大家看一篇文章,会有很大的帮

助,同时要感谢作者(shadowstar)提供了这么好的文章,我也从中得不少帮助(~_~)。

 

       http://web.nyist.net/~shadowstar/essay/security/sniffer1.html

      

       下面是我做的一段数据接收和分离出来的IP包的程序:

              ...........

              try

              {

                     nIpRevLen = recv( pCtlSocket->m_socket, cIpRevBuff, MAX_COMMAND_SIZE - 24, 0 ) ;

        }

        catch( ... )

        {

        }

 

        if( nIpRevLen == SOCKET_ERROR ) continue ;

 

        IP    * p_ip  = ( IP * )cIpRevBuff ;

           TCP * p_tcp = ( TCP * )( cIpRevBuff + IP_HdrLen( p_ip )) ;

 

        if( p_ip->DstAddr != pCtlSocket->addr_in.sin_addr.S_un.S_addr ) continue ; //这句和下一句过滤其它不要的包

        if( p_ip->Protocol != IPPROTO_TCP ) continue ;

 

        int nSrcPort = ntohs( p_tcp->SrcPort ) ;

        if( nSrcPort != PORT_DODZ ) continue ;      

 

        char * pPackConten = ( char * )p_tcp + TCP_HdrLen( p_tcp ) ;       //这里就是得到了包的内容了

        nPackLen = ntohs( p_ip->TotalLen ) - IP_HdrLen( p_ip ) - TCP_HdrLen( p_tcp ) ; //这个是包的长度

        ...........

       

       二、数据的协议分析

      

       下面来分析一下联众升级的协议,本来自己接收到数据了,就可以把数据写下来,不过还是用别人的现成工具会更好一点,

在这里我用的是comview3.3来接收数据的,这个工具还是很好用的,建议大家可以下载一个去用一下试一试;下面是一些接收到的数据:

       0x0000   05 02 00 00 22 00 00 00-00 20 00 00 C1 00 00 00   ....".... ..?..

       0x0010   00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................

       0x0020   06 00 00 00 67 67 2E 68-74 6D 05 02 00 00 23 00   ....gg.htm....#.

       0x0030   00 00 01 20 00 00 46 00-00 00 00 00 00 00 00 00   ... ..F.........

       0x0040   00 00 00 00 00 00 00 00-00 00 07 00 00 00 67 67   ..............gg

       0x0050   2E 68 74 6D 6C                                    .html

      

       像这样的数据,相信让谁都会搞不清楚是什么东西,不过不怀疑有一些天才可以异想天开,不过去从原始数据来分析别人的协

议确实要一些灵感的,:)。好像是在为自己吹嘘,不好意思了..... 不过呢,协议的分析要与实际的操作结合起来,如果你不会玩

升级,很难想像你会很容易分析出来别人的协议来。还好我自己在这方面还不算,还是升级中是一个小官员类的分数据了,呵呵。

 

       我们可以想一下游戏一整个流程,登录、进入游戏室、找到玩家、发牌,扣底、出牌和结束。有了这样一个流程在脑子中可以帮

助想像每一个数据的信息。

      

       我用的是很差的方法去让这个过程和接收到的数据合在一起分析的:

       1、启动comview或其它的接收数据包的工具,设置好过滤条件,只接收IP/TCP包,目标的IP是自己的机器,如果不设置这些条件

呵呵,那网络是的大量数据包就全被你吃下来了,到时要从几万个包中找出你所要的数据,太难了吧...

      

       2、接着就启动联众的游戏,进入升级(为了分析这些协议,我总被人家说慢得像乌龟,还失去了很多分:( ),这时你就可要注

意了收集数据了,记下当前打会,什么时候叫牌,反牌,得分,出的牌,很从数据都要记录下来,同时还要想着如何出牌才能赢,要

不真有些对不起和你一起玩的对家了。

 

       3、有了数据一实际上过程的记录,分析协议就有了着手的地方了,我们先看下面的一段数据:

       0x0000   00 02 00 80 F0 00 00 00-01 00 00 00 04 00 02 00   ...€?..........

       0x0010   00 00 00 00 63 61 6F 77-65 69 5F 30 30 31 30 00   ....ddddd_0010.

       0x0020   11 20 00 00 18 00 00 00-67 79 75 67 68 00 00 00   . ......dddd...

      

       从这里可以看到,ddddd_0010(原始数据不是这个,我修改了)与一起的玩的的名称是不是一样呢,如果是一样的就好了,这个可

是服务器返回来的与你一起玩的玩家信息;

 

       如果你做过SCOKET方面的编程,你应该可以知道一个包的大体结构,下面我来说一下:

      

              应用包头标志

              包序列号

              整个包的长度

              CRC校验(或累加和校验)

              命令字

              数据体长度

              数据体

      

       网络上的数据并不是整像我们想像的那样,发一个包出去,就会在对方接下整个包,很多时候会分几次才能接收下来整个完整的包

。我们再看一个包:

       0x0000   10 20 00 80 24 00 00 00-D9 54 DF 77 01 00 00 00   . .€$...賂遷....

       0x0010   01 00 00 00 00 00 00 00-03 00 00 00 00 00 00 00   ................

       0x0020   03 00 00 00 01 00 00 00-01 00 00 00 17 71 40 00   .............q@.

      

       这两个包有什么相同之处,就是包头开始的8个字节,是不是可以看出来一个包的整体结构了,注意网络数据格式转换为机器数据格

式的话要反转一下数据MSDN上可以找到类似这样的函数ntohl、ntohs、 htonl和htons,所以我们在看数据时也要把字倒转一下...

       如果你了解的话,和般的80是作为一个回应包的标识,这样我们就可以看到了两个命令字了:

              80 00 00 02           十六进制表示:0x80000002

              80 00 20 10                   0x80002010

             

       这两个命令都不同,可以看到,协议上并没有统计的应用包头标志,直接从命令字开始了。有了上面的概念,接下来的自然就是

长度过,因为第一个包没有完整,我们看第二个包,一般长度用两个字节就可以了,但会有用四个字节的,也就是一个int类型的值,第二

个包的长度不难看到就是0x24,假设长度使用四个字节,那么内容就应该是D9 54 .... 71 40 00,0x24 = 36,我们数据一下,刚好就是

这个长度,呵呵,到现在你和我一样,了解一包的结构形式了,我们正在一步往成功的方向去了...

 

       到了这一步,大家也差不多可以动手自己去分析一下协议了,因为一些其它的因为,我在这里就不再往下分析各个命令字的具体作用

了,不过可以告诉大家0x80000002是用户登录后服务器返回来的所有玩家信息,注意一下,我们在注册联众用户时,最长的登录名称不能

超过19个字节,所以在包就应加上一个结束符,就是20个字节了。

       上面的分析只是一个引子,由本人水平有限,有什么错误的地方请大家指出,共同学习。

      

       另外我做的一个联众升级助理V1.0在www.csdn.net中软件(游戏类,其它类型)上发布了,大家可以下载使用,是完全免费的。因为时间有限,没有做完整

的测试,如果发现在什么bug,可以用邮件方式通知我,谢谢!