最近,闲来无事,研究了一下魔域游戏的封包发送与接收,下面,就把分包发送部分的一些东西与大家分享。

相信对游戏进行过逆向分析的人都比较清楚,发送封包能够完成很多意想不到的功能,而这些功能如果通过调用游戏本身的call的话,操是非常繁杂的。所以,可以这么说,发送封包简化了对游戏逆向的步骤。发送分包是控制游戏的万能钥匙。

寻找魔域封包发送的函数并不复杂,复杂的是,怎样去找封包数据的明文,也就是找到封包数据的加密函数。其实,这也不难。只要按照正规方法,耐心寻找,最终,游戏就会像被你扒光衣服的姑娘,呈现在你面。废话不说。步骤如下:

  1. 在封包发送函数send处下断点。做一个动作,如卖物品,这是,游戏就会断在封包发送的地方。如果你看一下发送数据缓冲区,你会发现,里边全部是密文,相同动作,封包数据完全不同。所以我们必须找到封包加密的函数。
  2. 在密文封包处下硬件写入断点。这是再卖物品,你会发现,游戏断在了另一个地方。取消硬件断点。返回函数上一级。你会发现,函数的一个参数就是send函数的封包发送缓冲区,很明显,这个函数就是封包加密函数,汇编代码如下:

加密:
00DC0630    55              push    ebp
00DC0631    8B6C24 0C       mov     ebp, dword ptr [esp+C]
00DC0635    56              push    esi
00DC0636    33F6            xor     esi, esi
00DC0638    85ED            test    ebp, ebp
00DC063A    7E 6E           jle     short 00DC06AA
00DC063C    57              push    edi
00DC063D    8B7C24 10       mov     edi, dword ptr [esp+10]
00DC0641    33C0            xor     eax, eax
00DC0643    8A81 04040000   mov     al, byte ptr [ecx+404]
00DC0649    8A5408 04       mov     dl, byte ptr [eax+ecx+4]
00DC064D    8A043E          mov     al, byte ptr [esi+edi]
00DC0650    32C2            xor     al, dl
00DC0652    88043E          mov     byte ptr [esi+edi], al
00DC0655    8AD0            mov     dl, al
00DC0657    33C0            xor     eax, eax
00DC0659    8A81 04040000   mov     al, byte ptr [ecx+404]
00DC065F    8A8408 04020000 mov     al, byte ptr [eax+ecx+204]
00DC0666    02C2            add     al, dl
00DC0668    33D2            xor     edx, edx
00DC066A    88043E          mov     byte ptr [esi+edi], al
00DC066D    8A91 05040000   mov     dl, byte ptr [ecx+405]
00DC0673    8A940A 04010000 mov     dl, byte ptr [edx+ecx+104]
00DC067A    32D0            xor     dl, al
00DC067C    33C0            xor     eax, eax
00DC067E    88143E          mov     byte ptr [esi+edi], dl
00DC0681    8A81 05040000   mov     al, byte ptr [ecx+405]
00DC0687    8A8408 04030000 mov     al, byte ptr [eax+ecx+304]
00DC068E    02C2            add     al, dl
00DC0690    8AD0            mov     dl, al
00DC0692    C0EA 04         shr     dl, 4
00DC0695    C0E0 04         shl     al, 4
00DC0698    0AD0            or      dl, al
00DC069A    88143E          mov     byte ptr [esi+edi], dl
00DC069D    66:FF81 0404000>inc     word ptr [ecx+404]
00DC06A4    46              inc     esi
00DC06A5    3BF5            cmp     esi, ebp
00DC06A7  ^ 7C 98           jl      short 00DC0641
00DC06A9    5F              pop     edi
00DC06AA    5E              pop     esi
00DC06AB    5D              pop     ebp
00DC06AC    C2 0800         retn    8

3.找到send函数的socket。这一步比较简单,只要在API函数send处下断,返回寻找,socke就在函数头部附近。

4.发送封包。由于socket以及明文都已经找到,所以自己可以直接调用send函数像游戏服务器发送特定动作的封包。

int MY_EncFunc(int GameKey, int Data, int len)
{
 int Len;
 int i;
 int data;
 int result; 
 char value1;
 unsigned __int8 value_data; 
 char value2; 
 unsigned __int8 v10;

Len = len;
 i = 0;
 if ( len > 0 )
 {
  data = Data;
  do
  {
   value1 = *(BYTE *)(*(BYTE *)(GameKey + 0x404) + GameKey + 4) ^ *(BYTE *)(i + data);
   *(BYTE *)(i + data) ^= *(BYTE *)(*(BYTE *)(GameKey + 0x404) + GameKey + 4);
   value_data = value1 + *(BYTE *)(*(BYTE *)(GameKey + 0x404) + GameKey + 0x204);
   *(BYTE *)(i + data) = value_data;
   value2 = value_data ^ *(BYTE *)(*(BYTE *)(GameKey + 0x405) + GameKey + 0x104);
   *(BYTE *)(i + data) = value2;
   result = *(BYTE *)(GameKey + 0x405);
   *(BYTE *)(&result) = value2 + *(BYTE *)(result + GameKey + 0x304);
   v10 = (BYTE)result >> 4;
   *(BYTE *)(&result) = 16 * (BYTE)result;
   *(BYTE *)(i + data) = (BYTE)result | v10;
   ++*(WORD *)(GameKey + 0x404);
   ++i;
  }
  while ( i < Len );
 }
 return result;
}

int  MY_Decfunc(int GameKey, int data, int len)
{
 int Len;
 int i;
 int Data;
 int result;
 char value1;
 unsigned __int8 value_data;
 char value2;
 int value3;

Len = len;
 i = 0;
 if ( len > 0 )
 {
  Data = data;
  do
  {
   value1 = (unsigned __int8)(16 * *(BYTE *)(i + Data)) | (unsigned __int8)(*(BYTE *)(i + Data) >> 4);
   *(BYTE *)(i + Data) = (unsigned __int8)(16 * *(BYTE *)(i + Data)) | (unsigned __int8)(*(BYTE *)(i + Data) >> 4);
   value_data = value1 - *(BYTE *)(*(BYTE *)(GameKey + 0x407) + GameKey + 0x304);
   *(BYTE *)(i + Data) = value_data;
   value2 = value_data ^ *(BYTE *)(*(BYTE *)(GameKey + 0x407) + GameKey + 0x104);
   *(BYTE *)(i + Data) = value_data ^ *(BYTE *)(*(BYTE *)(GameKey + 0x407) + GameKey + 0x104);
   result = *(BYTE *)(GameKey + 0x406);
   value3 = *(BYTE *)(GameKey + 0x406);
   *(BYTE *)(&result) = value2 - *(BYTE *)(value3 + GameKey + 0x204);
   *(BYTE *)(i + Data) = value2 - *(BYTE *)(value3 + GameKey + 0x204);
   *(BYTE *)(i + Data) = (BYTE)result ^ *(BYTE *)(*(BYTE *)(GameKey + 0x406) + GameKey + 4);
   ++*(WORD *)(GameKey + 0x406);
   ++i;
  }
  while ( i < Len );
 }
 return result;
}

比如卖物
char sendstr[0x14]={0};
....
....
//参数构造这个sendstr
MY_EncFunc(GameKeyThis,sendstr,0x14);
send(sockthis,sendstr,0x14,0);

魔域游戏中的封包发送分析相关推荐

  1. 游戏中常用音乐风格分析

    不同的游戏有不同的玩法,每种不同的玩法都是不同的风格,每款游戏都配备了不同场景的音乐,根据音乐的场景不同,以及游戏风格的不同,游戏音乐风格也多种多样,今天我们来聊聊游戏音乐常用的风格有哪些? (一)按 ...

  2. Dota游戏中的护甲分析

    摘要:Dota(Defence of the Ancients,远古的守护), 是指基于魔兽争霸3:冰封王座(暴雪娱乐公司出品)的多人即时对战自定义地图,可支持10个人同时连线游戏.Dota以对立的两 ...

  3. 分析游戏中的金钱交易:Multi-view Attention Networks

    文章目录 1.摘要 2.引入 3.游戏数据描述 3.1 逆水寒中的游戏日志 3.2 社交图分析 3.3 行为序列 3.4 角色属性构造 4.MVAN模型 4.1 multi-graph attenti ...

  4. 游戏中的卡片模态面板设计【1】—运用案例分析

    什么是卡片模态面板 1)什么是模态面板 模态面板是从属于应用程序主窗口的图形控制元素.它创建了一个模式--禁用主窗口但保持主窗口可见(主窗口作为背景,菜单.弹窗.二次确认等覆盖在上一层),通常可见的是 ...

  5. 用数学方法分析哪类游戏中的AI难度最大

    2019年是AI在游戏领域全面开花的一年. 1月,DeepMind开发的AlphaStar在<星际争霸II>比赛中以5:0战胜了职业选手MaNa:4月,OpenAI开发的OpenAI Fi ...

  6. Silverlight游戏设计(Game Design):(一)游戏中斜视角的原理与分析

    "暗黑破坏神3"将采用45度斜视角设置这篇数月前貌似毫不起眼的新闻一直让我记忆深刻,不断的尝试去理解大师级的暗黑团队为何放弃目前主流的纯3D路线而回归到类2D,B大的一句话道破天机 ...

  7. 用 Redis 搞定游戏中的实时排行榜,附源码!

    原文:segmentfault.com/a/1190000019139010 1. 前言 前段时间刚为项目(手游)实现了一个实时排行榜功能, 主要特性: 实时全服排名 可查询单个玩家排名 支持双维排序 ...

  8. Serverless在游戏运营行业进行数据采集分析的最佳实践 链接:

    简介:这个架构不光适用于游戏运营行业,其实任何大数据采集传输的场景都是适用的,目前也已经有很多客户正在基于Serverless的架构跑在生产环境,或者正走在改造Serverless 架构的路上. 作者 ...

  9. Serverless在游戏运营行业进行数据采集分析的最佳实践

    简介: 这个架构不光适用于游戏运营行业,其实任何大数据采集传输的场景都是适用的,目前也已经有很多客户正在基于Serverless的架构跑在生产环境,或者正走在改造Serverless 架构的路上. 众 ...

最新文章

  1. java如何被调用_java – 如何知道Parse.initialize()是否已被调用?
  2. 深入理解最大池化为什么能够实现不变性?
  3. @property与@synthesize的差别
  4. Java Bullshifier –生成大量随机代码库
  5. QString string int double char 相互转化
  6. Python爬虫学习round01
  7. java: 读取D:\repository\org\lz4\lz4-java\1.7.1\lz4-java.jar时出错; error in opening zip file解决方案
  8. 使用MATLAB2010实现AVI视频播放
  9. 带你Git从入门到精通
  10. 手札 江湖的完美窗口化研究
  11. yum 安装没有公钥_CentOS7.7中使用yum安装进,提示尚未安装任何 GPG 公钥的解决办法...
  12. Solr vs Elasticsearch vs Lucene
  13. Qt:QTextStream
  14. hilbert算法的c语言实现,关于希尔伯特变换的 c语言实现
  15. linux环境下IO的常用函数
  16. 【杂项】JZ2440挂载NFS网络文件系统
  17. [附源码]Java计算机毕业设计SSM菜鸟驿站快递分发系统
  18. 南京邮电大学图书管理系统
  19. k8s集群下搭建数据同步工具-canal:canal-admin篇
  20. (汇编语言)逻辑地址转换物理地址

热门文章

  1. Oracle中SID INSTANCE_NAME Service_Name DB_Name等的介绍
  2. java为啥要stw_【JVM 学习】ParNew 为什么要STW
  3. oracle dataguard详细,ORACLE11G搭建dataguard详细步骤(物理standby所有操作总结)
  4. Java获取当前日期的前一天
  5. python中substr_Python中有substr函数吗
  6. java如何拷贝复制对象和集合
  7. IT组织架构、岗位职责设计实战案例
  8. 软件测试 自动化测试 Web自动化测试01 selenium 定位元素方法 元素操作 自动化脚本开发
  9. php查询车辆违章付费源码,全国交通违章查询
  10. ABAP 人民币大小写转换程序