庞大资源库的计算机教程网站!
设为首页
加入收藏
总编信箱
投稿或申请专栏请先 [登 陆]
首页 操作系统 程序设计 图形图像 媒体动画 机械电子 WEB开发 数 据 库 办公系列 路由技术 网络原理 网络应用
认证考试 安全技术
首页>安全技术>黑客攻防>黑客教程>正文
资料搜索
Google搜索
Google
返回上级列表

推荐文章

快速保存网页中所有图片的方法
Windows中让光驱巧妙“隐身”技
防范非法用户入侵Win 2000/XP系
两款比较典型的ASP木马防范方法
有关表格边框的css语法整理
Windows XP中可以被禁用的服务
SQL Server导出导入数据方法
Javascript所有对象的属性的获
网页(HTML)中的特殊字符
与篮球共舞,尽显模式本色
QQ病毒的手工清除方法
Photoshop为极品美女打造性感睫
天衣无缝:IIS与PHP水火也相容
SQL Server存储过程编写和优化

游戏外挂设计技术探讨② 下

 作者:本站收集   日期:2005-5-17
字号选择〖 〗/ 双击滚屏 单击停止   
   五、封包技术

   通过对动作模拟技术的介绍,我们对游戏外挂有了一定程度上的认识,也学会了使用动作模拟技术来实现简单的动作模拟型游戏外挂的制作。这种动作模拟型游戏外挂有一定的局限性,它仅仅只能解决使用计算机代替人力完成那么有规律、繁琐而无聊的游戏动作。但是,随着网络游戏的盛行和复杂度的增加,很多游戏要求将客户端动作信息及时反馈回服务器,通过服务器对这些动作信息进行有效认证后,再向客户端发送下一步游戏动作信息,这样动作模拟技术将失去原有的效应。为了更好地“外挂”这些游戏,游戏外挂程序也进行了升级换代,它们将以前针对游戏用户界面层的模拟推进到数据通讯层,通过封包技术在客户端挡截游戏服务器发送来的游戏控制数据包,分析数据包并修改数据包;同时还需按照游戏数据包结构创建数据包,再模拟客户端发送给游戏服务器,这个过程其实就是一个封包的过程。

   封包的技术是实现第二类游戏外挂的最核心的技术。封包技术涉及的知识很广泛,实现方法也很多,如挡截WinSock、挡截API函数、挡截消息、VxD驱动程序等。在此我们也不可能在此文中将所有的封包技术都进行详细介绍,故选择两种在游戏外挂程序中最常用的两种方法:挡截WinSock和挡截API函数

   1. 挡截WinSock

   众所周知,Winsock是Windows网络编程接口,它工作于Windows应用层,它提供与底层传输协议无关的高层数据传输编程接口。在Windows系统中,使用WinSock接口为应用程序提供基于TCP/IP协议的网络访问服务,这些服务是由Wsock32.DLL动态链接库提供的函数库来完成的。

   由上说明可知,任何Windows基于TCP/IP的应用程序都必须通过WinSock接口访问网络,当然网络游戏程序也不例外。由此我们可以想象一下,如果我们可以控制WinSock接口的话,那么控制游戏客户端程序与服务器之间的数据包也将易如反掌。按着这个思路,下面的工作就是如何完成控制WinSock接口了。由上面的介绍可知,WinSock接口其实是由一个动态链接库提供的一系列函数,由这些函数实现对网络的访问。有了这层的认识,问题就好办多了,我们可以制作一个类似的动态链接库来代替原WinSock接口库,在其中实现WinSock32.dll中实现的所有函数,并保证所有函数的参数个数和顺序、返回值类型都应与原库相同。在这个自制作的动态库中,可以对我们感兴趣的函数(如发送、接收等函数)进行挡截,放入外挂控制代码,最后还继续调用原WinSock库中提供的相应功能函数,这样就可以实现对网络数据包的挡截、修改和发送等封包功能。

   下面重点介绍创建挡截WinSock外挂程序的基本步骤:

   (1) 创建DLL项目,选择Win32 Dynamic-Link Library,再选择An empty DLL project。

   (2) 新建文件wsock32.h,按如下步骤输入代码:

   ① 加入相关变量声明:

   HMODULE hModule=NULL; //模块句柄
    char buffer[1000]; //缓冲区
    FARPROC proc; //函数入口指针

   ② 定义指向原WinSock库中的所有函数地址的指针变量,因WinSock库共提供70多个函数,限于篇幅,在此就只选择几个常用的函数列出,有关这些库函数的说明可参考MSDN相关内容。

   //定义指向原WinSock库函数地址的指针变量。
    SOCKET (__stdcall *socket1)(int ,int,int);//创建Sock函数
    int (__stdcall *WSAStartup1)(WORD,LPWSADATA);//初始化WinSock库函数
    int (__stdcall *WSACleanup1)();//清除WinSock库函数
    int (__stdcall *recv1)(SOCKET ,char FAR * ,int ,int );//接收数据函数
    int (__stdcall *send1)(SOCKET ,const char * ,int ,int);//发送数据函数
    int (__stdcall *connect1)(SOCKET,const struct sockaddr *,int);//创建连接函数
    int (__stdcall *bind1)(SOCKET ,const struct sockaddr *,int );//绑定函数
    ......其它函数地址指针的定义略。

   (3) 新建wsock32.cpp文件,按如下步骤输入代码:

   ① 加入相关头文件声明:

   #include <windows.h>
    #include <stdio.h>
    #include "wsock32.h"

   ② 添加DllMain函数,在此函数中首先需要加载原WinSock库,并获取此库中所有函数的地址。代码如下:

   BOOL WINAPI DllMain (HANDLE hInst,ULONG ul_reason_for_call,LPVOID lpReserved)
    {
     if(hModule==NULL){
      //加载原WinSock库,原WinSock库已复制为wsock32.001。
    hModule=LoadLibrary("wsock32.001");
   }
     else return 1;
//获取原WinSock库中的所有函数的地址并保存,下面仅列出部分代码。
if(hModule!=NULL){
      //获取原WinSock库初始化函数的地址,并保存到WSAStartup1中。
proc=GetProcAddress(hModule,"WSAStartup");
    WSAStartup1=(int (_stdcall *)(WORD,LPWSADATA))proc;
      //获取原WinSock库消除函数的地址,并保存到WSACleanup1中。
     proc=GetProcAddress(hModule i,"WSACleanup");
     WSACleanup1=(int (_stdcall *)())proc;
      //获取原创建Sock函数的地址,并保存到socket1中。
     proc=GetProcAddress(hModule,"socket");
      socket1=(SOCKET (_stdcall *)(int ,int,int))proc;
      //获取原创建连接函数的地址,并保存到connect1中。
      proc=GetProcAddress(hModule,"connect");
      connect1=(int (_stdcall *)(SOCKET ,const struct sockaddr *,int ))proc;
      //获取原发送函数的地址,并保存到send1中。
      proc=GetProcAddress(hModule,"send");
      send1=(int (_stdcall *)(SOCKET ,const char * ,int ,int ))proc;
      //获取原接收函数的地址,并保存到recv1中。
      proc=GetProcAddress(hModule,"recv");
      recv1=(int (_stdcall *)(SOCKET ,char FAR * ,int ,int ))proc;
      ......其它获取函数地址代码略。
    }
    else return 0;
    return 1;
}

   ③ 定义库输出函数,在此可以对我们感兴趣的函数中添加外挂控制代码,在所有的输出函数的最后一步都调用原WinSock库的同名函数。部分输出函数定义代码如下:

//库输出函数定义。
//WinSock初始化函数
     int PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData)
     {
      //调用原WinSock库初始化函数
      return WSAStartup1(wVersionRequired,lpWSAData);
     }
     //WinSock结束清除函数
     int PASCAL FAR WSACleanup(void)
     {
      return WSACleanup1(); //调用原WinSock库结束清除函数
     }
     //创建Socket函数
     SOCKET PASCAL FAR socket (int af, int type, int protocol)
     {
      //调用原WinSock库创建Socket函数
      return socket1(af,type,protocol);
     }
     //发送数据函数
     int PASCAL FAR send(SOCKET s,const char * buf,int len,int flags)
     {
    //在此可以对发送的缓冲buf的内容进行修改,以实现欺骗服务器。
    外挂代码......
    //调用原WinSock库发送数据函数
      return send1(s,buf,len,flags);
     }
//接收数据函数
     int PASCAL FAR recv(SOCKET s, char FAR * buf, int len, int flags)
     {
    //在此可以挡截到服务器端发送到客户端的数据包,先将其保存到buffer中。
    strcpy(buffer,buf);
    //对buffer数据数据进行分析后,对其按照玩家的指令进行相关修改。
    外挂代码......
    //最后调用原WinSock中的接收数据函数
      return recv1(s, buffer, len, flags);
      }
     .......其它函数定义代码略。

   (4)、新建wsock32.def配置文件,在其中加入所有库输出函数的声明,部分声明代码如下:

   LIBRARY "wsock32"
    EXPORTS
     WSAStartup @1
    WSACleanup @2
     recv @3
     send @4
     socket @5
    bind @6
    closesocket @7
    connect @8

    ......其它输出函数声明代码略。

   (5)、从“工程”菜单中选择“设置”,弹出Project Setting对话框,选择Link标签,在“对象/库模块”中输入Ws2_32.lib。

   (6)、编译项目,产生wsock32.dll库文件。

   (7)、将系统目录下原wsock32.dll库文件拷贝到被外挂程序的目录下,并将其改名为wsock.001;再将上面产生的wsock32.dll文件同样拷贝到被外挂程序的目录下。重新启动游戏程序,此时游戏程序将先加载我们自己制作的wsock32.dll文件,再通过该库文件间接调用原WinSock接口函数来实现访问网络。上面我们仅仅介绍了挡载WinSock的实现过程,至于如何加入外挂控制代码,还需要外挂开发人员对游戏数据包结构、内容、加密算法等方面的仔细分析(这个过程将是一个艰辛的过程),再生成外挂控制代码。关于数据包分析方法和技巧,不是本文讲解的范围,如您感兴趣可以到网上查查相关资料。
上一篇:网络游戏通讯模型初探②    下一篇:游戏外挂设计技术探讨② 上  
[发送给好友]  [关闭窗口]  [返回顶部]   转载请注明来源:www.it00.com   
特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
责任编辑: 原点 投稿作者: 本站收集
信息来源: 网络 录入时间: 2005-5-17
关于我们 - 广告服务 - 版权申明 - 网站地图 - 联系方式 - 总编信箱 - 会员投稿