游戏对战平台研究终结

来源:互联网 发布:淘宝店类目在哪里修改 编辑:程序博客网 时间:2024/04/29 18:27
游戏对战平台研究终结

引用:

       游戏对战平台,在没有了解的情况下,总是给人一种很神秘的感觉,然而,当你对socket的理解到达一定程度之后,你就不会再觉得神秘。
       用一句话来总结这种技术:虚拟局域网(VLAN)。

   实现这种平台,主要是客户端,而客户端有很多种方法,就我所了解,可以用面三种方法实现:
    1. 替换Windows socket DLL,然后,你想做什么就做什么吧。
    2. 进程注入,HOOK WinSock函数调用。
    3. 虚拟网卡驱动。

       其实,前两种技术,也是许多木马使用的方法。正所谓技术是一面双刃剑,看你要用到什么地方了。现在的对战平台,就我了解,使用的是后两种方法。大多数是第2中----毕竟,驱动在有些用户权限下是无法安装和使用的。
       浩方,QQ对战平台,VS等,基本上都是采用第二中方法。第三种方法,见过一个。效果还可以。

    下面介绍一下我研究时写的平台结构:
       整个平台包含两个组成部分:服务端和客户端。
       通讯方式:全部采用UDP通讯。
 
  零、基础知识:
     如果你有志与开发这样一个类似平台,我建议你先了解以下内容:
     a. Windows协议栈的简单了解。
     b. WinSock通讯。
     c. HOOK技术。
     d. 线程,进程之间的数据交换和通讯。
     e. 线程之间的同步。
     f. 线程注入。
     e. 其它的一些Windows开发的基础知识,就不一一列举了。

     这些都是基本功,基本功如何,决定了你能走到哪一步。

  一、服务端:
      服务器在逻辑上被分为了两部分:
      a. 用户服务器: 虚拟IP分配,用户管理,消息通知等。
      b. 转发服务器: 进行必要的数据转发(无法进行P2P通讯的)

  二、客户端:
     客户端也包含两个部分,
     a. 客户端EXE: 负责进行进程注入,与服务器通讯。
     b. 客户端DLL: 负责进行socket函数替换和处理。

    注:这里,服务器和客户端都有KeepAlive的功能,如果在一定时间内未收到包,则认为用户已经掉线。

  三、主要工作流程:
     这里主要对用户登陆和登出,启动和退出游戏这连个主要环节进行总结。
 
    a. 用户登陆过程
     +-------------------------------+
      |  输入用户名和密码,登陆 |
     +-------------------------------+
                     |
     +-----------------------------+
     |   发送登陆包到服务器    |
     +-----------------------------+
                    |
     +-----------------------------+
     |        处理反馈信息        |
     +------------------------------+
                |
           <登陆成功>   ------------失败-------------> [提示用户]
                |
     +------------------------------+
     |  请求其他在线用户信息 |
     +-----------------------------+

   用户登陆信息客户端处理流程
 
         +--------------------+
         | 收到用户登陆包 |
         +--------------------+
                  |
             <数据解析>----------------> [丢弃不合法数据包]
                  |
         <验证用户登陆信息> -----------失-败-------+
                  |                                                      |
                  |                                                      |
    +----------------------------+        +---------------------------------+
    |      分配虚拟IP地址        |        |反馈登陆失败信息到客户端|
    +----------------------------+        +-------------------------------+

                      |
    +--------------------------------------+
    |      添加用户到在线用户列表     |
    +--------------------------------------+
    |反馈用户登陆成功,服务器信息|
    |                   到客户端                |  (* 这里包含了转发服务器信息)
    +--------------------------------------+
                           |
       +------------------------------+
       |广播信息到所有登陆用户|
       +-----------------------------+

           用户登陆信息服务端处理流程(由用户服务器处理)

    b. 用户登出过程
     
             +--------------------+
             | 收到用户退出包 |
             +--------------------+
                       |
                   <数据解析>----------------> [丢弃不合法数据包]
                       |
             +----------------------+
             <  查找将用户信息  >   ------------> 未找到,不处理
             +---------------------+
                       |
       +----------------------------------------+
       |   将用户从在线用户列表中删除   |
       +---------------------------------------+
                       |
       +------------------------------------+
       |     回收虚拟IP给其他用户       |
       +-----------------------------------+
                       |
       +-------------------------------------------+
       | 广播用户登出信息到所有在线用户 |
       +-------------------------------------------+

           服务器处理过程

         <判断用户是否在游戏中>   -----------是------------> 提示用户
                  |
                否
                 |
       +-----------------------------+
       |   发送登出包到服务器    |
       +-----------------------------+
                  |
       +-------------------------+
       |          退出                |
       +-------------------------+
            客户端处理过程

  c. 游戏启动过程
 
       +--------------------------+
       |      创建内存共享        |
       |  (CreateFileMapping) |
       |   写入游戏当前配置    |
       | (包含在线用户信息和 |
       |    转发服务器信息)     |
       +--------------------------+
                 |
       +-----------------------------+
       | 根据用户选择启动游戏 |
       | (调用CreateProcess)   |
       +----------------------------+
                 |
          <是否启动成功>  ------------否----------> [提示用户失败信息]
                 |
       +-----------------------------+
       | 将游戏DLL注入到游戏 |
       +----------------------------+
                  |
    +--------------------------------+
    |     读取游戏的配置信息     |
    +-------------------------------+
                  |
    +-----------------------------+
    |       连接转发服务器       |
    +-----------------------------+
                  |
    +--------------------------------------+
    |  游戏DLL HOOK所有网络函数  |
    |   (采用Inline Hook方式)            |
    +-------------------------------------+
                  |
    +----------------------------------+
    |   OK, now game start OK!   |
    +----------------------------------+


  d. 游戏退出过程

   +----------------------------------------------+
   |  游戏DLL释放所有已经HOOK的函数  |
   +---------------------------------------------+
                  |
   +-----------------------------------+
   |     关闭内存共享文件            |
   +-----------------------------------+
                  |
   +--------------------------------------+
   |     发送退出包到转发服务器      |
   +--------------------------------------+

  四、游戏DLL工作过程:

     整个平台运作过程中,最主要的部分恐怕就是这个部分了,所以,单独将这部分的结构进行一下说明。
   
     在这里,我将处理过程分成了三个层,每个层分别完成不同的功能:网络HOOK层,自定义协议栈,网络数据传输层。
     首先,HOOK所有上层的网络函数调用,然后交给自定义协议栈进行处理,处理完成后,如果需要发送数据,则交由下层的网络发送层进行发送。

     +----------------------------------------------------------+
     |                                                                          |
     | 网络函数HOOK层: 主要负责网络函数的替换  |
     |                  并且交由下层处理                            |
     |    这里,其实也就是对于WS2_32.dll中的          |
     | socket函数进行替换。                                      |
     |                                                                         |
     +---------------------------------------------------------+
     |                                                                         |
     | 数据处理层:主要负责将上层的各种网络        |
     |                     函数功能调用进行处理。             |
     |    举个简单的例子,当游戏调用Socket函数     |
     | 准备创建一个socket时,我们根据它的参数, |
     | 内部虚拟出一个socket句柄给它。而实际的上 |
     | Windows本身并不知道这个调用过程。           |
     |                                                                       |
     +-------------------------------------------------------+
     |                                                                       |
     | 真实网络传输层:在这一层,才是真正的将数|
     |                 据包进行包装和发送的过程            |
     |                                                                       |
     +-------------------------------------------------------+

       其实,整个客户端只创建了两个socket,一个用于和服务器通讯的socket,另外一个就是在游戏DLL中创建的一个和转发服务器以及游戏之间通讯所使用的socket。
       这里重要的就是中间的那层,主要就是对于socket调用中的每个函数进行模拟。这个就需要各位自己去了解了。我不可能也没有能力把每个都描述出来。
        其实,这里的第二层处理也可以不采用我的这种方法,可以采用协议替换法,比如,当游戏调用socket函数要创建一个IPX socket时,你可以修改其中的参数,变成UDP,然后调用Windows真实的socket函数。

  五、主要的技术难点:
      a. 模拟Windows Socket。

          这个技术点,说起来就比较多了。我们知道Windows有六中socket模型,我们必须模拟出来大部分的模型(根据游戏所使用的模型不同而需要模拟的模型就不同)。
     根据我的跟踪和测试,说说现在了解的几个游戏所使用的socket模型和协议类型:

     《红色警戒》: 使用了简单的WSAAsyncSelect模型。(IPX协议)
     《星际争霸》: 使用了Select 模型。(IPX, UDP协议,根据用户的参数)
     《暗    黑》: 使用Select模型。(使用TCP协议)
     《反恐精英》: 使用Select模型。(使用TCP, UDP协议)
     《冰封王座》: 似乎使用了IOCP Socket模型。这个还不是很清楚。(使用TCP,UDP两种协议)

      b. 改进UDP数据通讯的可靠性。
         整个平台中,所有通讯全部使用的是UDP,所以,这点很重要。如果我们的游戏中采用了TCP通讯,我们在模拟的时候就的保证所有数据都能被对方收到。

   六、开发后记:
      去年的时候,我写过一个英文的对战平台研究,现在看看,那简直是垃圾!可能是那是比较浮躁,对于什么东西都没有了解清楚。一年后,再回过头来看我写的那些代码,真是惨不忍睹。现在,我觉得自己心静了很多,技术上也成熟了许多。想说的就是Windows开发,我可以算是入门了吧!呵呵!
     整个平台,只是在我的机器上进行测试和开发,难度比较大。工程。现在,我也只对《红色警戒》, 《星际争霸》,《暗黑》三个游戏测试通过。感觉一个人开发实在太累了,而且,这些东西都是经过一次次的AV错误一步步调试出来的,想想那些岁月,真是不堪回首!暂时不想再继续下去了。等什么时候有精力和时间的时候再来处理吧。
      很多时候,为了能够调试通过一个函数,我不知要经历多少次的游戏重启过程。基本上MSDN上的大多数socket函数已经被我翻了个遍,每个函数的参数,返回值等都的了解。
     为了了解Windows实现socket的原理,阅读那份据说是Win2K的源码(如果你想阅读的话,到网上搜索一下,解压后大概有700M),关于socket的那部分代码在/win2k/private/net/sockets/winsock2/wsock32目录下(估计是WS2_32.dll的源码),读了很多内容,也了解了一些东西,也让我知道以后怎么去写socket程序。现在我有时写代码写累的时候,还会去看点Windows的源码,挺有意思的。像gina的实现,CommCtrl的实现等。
      代码大概已经写的至少有一两万行了,基本上都是我在EditPlus/NotePad中一个字母一个字母敲出来的。暂时不想共享出来了,就分享一下原理篇给大家。

 

Contents: This is a simple example of battle zone, just like HaoFangQQ battle zone. VLAN tech is used in this platform.
   
Key Words: VLAN, Hook API, DLL Inject, Memory File, NAT, Firewall tunnel.

         容:这是个以简单的对战平台示例,类似浩方,QQ等对战平台。该平台主要应用的技术是虚拟局域网。
   
关键词: 虚拟局域网,API截获,动态链接库注入, 内存映像文件,NAT,防火墙穿透。

     Generallyspeaking, battle zone client uses VLAN (Virtual Local Area Network)technique. But it’s so hard to descript this in few words. 
    In this article, we discuss how to build a battle zone, not fully use VLAN technique.
    (Written by: james.zhai[etomahawk]   2007-5    http://www.freewebs.com/y1gx)
    In order to develop a battle zone system, we need to solve the following problems:

 1. How to make a whole in the firewall?

      About this problem, please refers to this article: http://blog.csdn.net/lsaturn/archive/2004/06/29/29262.aspx

2. How to capture the game socket data?

 

   Refer to the diagram below:
  
 
     (Written by: james.zhai[etomahawk]   2007-5)
   Wehook sendto and recvfrom two functions when the game started, if thegame want to send a pack, we capture this pack and modify the data andpack the data into our own pack, then, we re-send this pack with ourUDP socket; when another application receive this pack, recvfromfunction is called here, in our recvfrom function, we can un-pack thedata and re-send the data to the game.

3. How to virtual a LAN? 
    (Written by: james.zhai[etomahawk]   2007-5)
    As we know, LAN can be formed according to MAC, IP address, protocols and others.
    If we want to make a virtual LAN, we only need to modify the IP address,
   
Inthis battle zone, I use MAC address to form a virtual LAN. There’s atable on the server which record all the machines that connected to ourserver. The table is as blow:
_________________________________________________________________
| Index  | Name |  MAC  | Virtual IP address |  Real IP address  |   Port   | Game Port |
|_____|______|______|_______________|______________|______|__________|

     When a client login, we get its basic information and broadcast this message to all the connected clients.
    
Atclient, we also save a table above. When client want to send a messageto another client (we had already hooked the send and receivefunctions), it searches the table to finds the real IP address andport, pack the message, send the message to another client. Whenanother client gets this message, it unpacks the message and resends itto local application.

 4. How my battle zone works? 

   
(Written by: james.zhai[etomahawk]   2007-5    http://www.freewebs.com/y1gx)
    Here is how my battle zone works (It contains two parts: Game client and server):
 

   Here is how it works:

   1) Login to server

     A Login process contains the following steps:
     a. Send login check pack to server.
      b. If login success, send a pack to get all players’ information.
      c. If get players’ information OK, update the player list and set share memory.

=======================Client try to connect to Server =============================

 

2) Start a game

      Start game procedure:
      a. Start game process. Create the game process.
      b. Inject the hook dll into game.
      c. The injected dll create a UDP socket.
      d. Send game information to server.
      e. Server receives game information, update the use status and broadcast this information to all players.
(Written by: james.zhai[etomahawk]   2007-5)
==============================Game started====================================

Start Game   -------[DLL Inject]---->    Game

                                      |
                                     V
                            1.  Hook API
                            2.  Bind a socket[UDP]
                            3.  Send Info to server
 
                                    |
                          
[Game Pack]
                         
          |
                        
          V
  
Change user info and send information to client and info all clients that a player’s info had changed.
                                 
 |
                                
  |
                                
  V
  Get player info change pack and update share memory content

============================Game Run========================================

 (Written by: james.zhai[etomahawk]   2007-5 http://www.freewebs.com/y1gx)

3) End game
     Send message to server to tell server about this information. 

4) Exit the battle zone client.

     Send a quit message to server, server will delete the user’s information and broadcast this information to all online players.  

   In thisbattle zone, I only capture IPX protocol package and analysis them andresend them, my test game is <<Red Alert 2>>, because I’mfamiliar with this game. J Other games are the same, if a game uses UDP/TCP transfer protocol, we can also pack the data into our pack and resend them. 

    First, we should decide whichfunction (API) should be hooked. Use exescope to spy the game, inGame.exe of <<Red Alert 2>> game, import WSOCK32.dll, thefollowing functions are imported:
   Function Index        Function Name
=====================================
    00000002                    bind
    00000003                    closesocket
    00000007                    getsockopt
    00000008                    htonl
    00000009                    htons
    00000011                    recvfrom
    00000014                    sendto
    00000015                    setsockopt
    00000017                    socket
    00000034                    gethostbyname
    00000039                    gethostname
    00000065                    WSAAsyncSelect
    00000073                    WSAStartup
    00000074                    WSACleanup
    00000457                    EnumProtocolsA
    0000006F               WSAGetLastError
    0000000B                    inet_ntoa
    0000000E                    ntohl
    0000000F                    ntohs

    Our battle field is only asimple example, so, we only need to hook some of those functions, suchas sendto, recvfrom, socket, e.g.

    Game Send game info to allplayers in the hall, this is a broadcast message, we need to analysisthis info and send the message to all the players in the virtual LAN.If the MAC address that send to address is “FF-FF-FF-FF-FF-FF” then,this is a broadcast info, we need to send the message to all theplayers, we had already get all players’ game port and real address,so, we only need to loop this broad chain and send to all players. Whenwe get the message from another user, we should resend this message tothe real port of game. Game receive this message, it will process ititself.

    This is a general idea about this battle zone.

     We use a table as blow to save other players’ information:
___________________________________________________________
| Index  |   MAC  | Virtual IP address |  Real IP address  |   Port   | Game Port |
|______|______|_______________|______________|_______|_________|

Meaning of each field:
Index: player index
MAC: Player’s MAC address, such as 00-40-D0-12-34-56
Virtual IP Address: Server allocate a virtual IP address to special player, such as 192.168.0.2
Real IP Address: the player’s real IP address, such as 61.87.12.18
Port: Player used to communicate with server or other players.
Game Port: Use witch port game exchange data.

     (Written by: james.zhai[etomahawk]   2007-5  http://www.freewebs.com/y1gx)

5. What knowledge is need in this battle zone client?

   To develop such battle zone, you need know the following knowledge:
   
1) Communication between different processes.
    2) UDP communication.
    3) Hook API
    4) Firewall tunnel.
    5) Virtual LAN.

 (Written by: james.zhai[etomahawk]   2007-5)

    If there’s any bug or batter idea, please contact me: 
    MSN: etomahawk@hotmail.com
    QQ:120038788
    Personal blog: http://etomahawk.popo.blog.163.com
    HomePage: http://www.freewebs.com/y1gx

     You can download this client and server form the following address:
     http://www.freewebs.com/y1gx/works/battle.rar

    For my other works, please visit: http://www.freewebs.com/y1gx/MyWorks.htm

Some pictures of my battle zone:

                                           Battle platform  Game Server

原创粉丝点击