首页
社区
课程
招聘
7
[原创]某游戏封包加解密算法及其算法KEY的算法
发表于: 2009-10-23 13:49 39872

[原创]某游戏封包加解密算法及其算法KEY的算法

2009-10-23 13:49
39872

free Q.744303 (只接受志同道合的技术研究伙伴,验证说明“看雪”,无聊人士勿扰)



潜水很多年,第一次发技术贴,不会排版还请版主帮忙。。



下载了某游戏的客户端,目的就是练习一下算法逆向,并且目标不是汇编代码,是C++代码。



研究了两天,有可能有疏漏,还请大侠批评指教!



用到的调试工具只有OllyDBG。



 



一、获取与运算封包Key



获取很简单,直接连接服务器,会收到服务器返回的包含了SendKey和RecvKey的钥匙包。



经过一定的算法,得到两个Key,在后续的游戏中,将使用这两个Key进行加密通信。



封包[0][1]为封包长度,不进行加解密操作。



封包:



2C 00 20 00 00 0A 00 0A 00 BD 

AD F2 A5 D5 

75 61 6E 78 75 

0B 73 D6 7C 

38 38 38 40 31 36 33 2E 63 6F 6D 00 00 00 00 00 00 00 00 00 00



下断点在 AD 这个字节上,运行,会断在访问的地址,如下汇编代码:



mov     edx, dword ptr [esi+11]  //取得 0B 73 D6 7C 


mov     esi, dword ptr [esi+8]   //取得 AD F2 A5 D5


mov     ecx, edx        //第二个KEY开始运算


mov     ebx, edx


xor     ecx, 6D23CF


sub     ecx, 6D2399


xor     edx, FFFFFFCF


not     ecx


add     edx, 67


xor     ebx, 2E6D23CF


and     ecx, 0FFFF00


not     edx


sub     ebx, 2E6D2399


shl     edx, 18


not     ebx


shr     ebx, 18


or      ecx, ebx


or      ecx, edx


push    ebp


push    ecx


mov     edx, esi      //第一个KEY开始运算


mov     ecx, esi


xor     edx, 6D23CF


xor     ecx, 2E6D23CF


sub     edx, 6D2399


sub     ecx, 2E6D2399


xor     esi, FFFFFFCF


not     edx


not     ecx


add     esi, 67


and     edx, 0FFFF00


shr     ecx, 18


or      edx, ecx


not     esi


shl     esi, 18


or      edx, esi



 



经过逆向,逆出C++代码如下:



DWORD __stdcall GetRecvKey(DWORD PacketRecvKey)
{

  DWORD sKey = 0;
  sKey = (((~((PacketRecvKey ^ 0x006D23CF) - 0x006D2399)) & 0x0FFFF00)
       | (~((PacketRecvKey ^ 0x2E6D23CF) - 0x2E6D2399)) >> 0x18)
      | ((~((PacketRecvKey ^ 0xFFFFFFCF) + 0x67)) << 0x18);
 return sKey;
}

 

DWORD __stdcall GetSendKey(DWORD PacketSendKey)
{

  DWORD sKey = 0;
  sKey  = (((~((PacketSendKey ^ 0x6D23CF) - 0x6D2399)) & 0xffff00)
       | ((~((PacketSendKey ^ 0x2E6D23CF) - 0x2E6D2399)) >> 0x18))
       | ((~((PacketSendKey ^ 0xFFFFFFCF) + 0x67)) << 0x18);
 return sKey ;
}


 



这两个KEY逆完后,继续逆封包加解密算法,中间碰到一个包,经过分析是心跳包,以07 00 01开头。



其实只是以01开头,刚才说过第一位和第二位是长度,所以07 00 是封包长度而已。心跳包是提交时间的。



这个封包的组成是这样的:



07 00 01 (XX XX XX XX)_time32()



蓝色是长度,红色是封包类型,后面的四位由MSVCR80.DLL里面的_time32() 函数得到结果。



在VS 2005+ 里可以直接使用这个函数,头文件:time.h。



 



通过类似的断点方法,找到解密用的函数,汇编如下:



push    ebx


push    ebp


mov     ebp, dword ptr [esp+14]


mov     ecx, dword ptr [ebp]


push    esi


mov     esi, dword ptr [esp+10]


mov     ebx, esi


and     ebx, 3                //求余数,下面以DWORD(4Byte)操作,如果有余数还要另行操作


shr     esi, 2                


push    edi


mov     edi, dword ptr [esp+18]


je      short 004D5605


lea     ecx, dword ptr [ecx]          //取得传入的经过运算的KEY


sub     esi, 1


lea     eax, dword ptr [ecx+esi]


xor     edx, edx


div     dword ptr [51FEDC]


add     edi, 4


mov     ecx, dword ptr [edx*4+51A620]    //进行完上面的运算,进行异或,注意是以DWORD(4字节)为单位的



add     ecx, 2E6D23C1          


xor     dword ptr [edi-4], ecx


test    esi, esi              //全完成了吗?


ja      short 004D55E0          //没有全完成的话继续


xor     edx, edx


mov     eax, ebx


div     dword ptr [51FEDC]


xor     ecx, dword ptr [edx*4+51A620]


test    ebx, ebx              //有余数吗?


jbe     short 004D562F          //没有的话就不继续处理剩下的字节了


lea     ebx, dword ptr [ebx]


xor     byte ptr [edi], cl


sub     ebx, 1


add     edi, 1


shr     ecx, 8


test    ebx, ebx              //余下的几个字节处理完了吗?


ja      short 004D5620          //没处理完继续


mov     eax, dword ptr [ebp]


mov     ecx, eax


shl     ecx, 5


sub     ecx, eax


pop     edi


add     ecx, 8088405


pop     esi


mov     dword ptr [ebp], ecx


pop     ebp


mov     eax, 1


pop     ebx


retn



 



经过分析,逆出的C++代码如下:



VOID __stdcall EncryptionPacket(DWORD *enbyte,int len,DWORD PacketKey)
{
  int NextLen = len % 4,PacketLength = len / 4;
  int i=0,j=0;
  DWORD NextKey = 0,AddNum = 0;
  BYTE *NewPacketAddr = (BYTE *)enbyte;
  AddNum = PacketKey;
 
  while (PacketLength--)
  {
    AddNum += PacketLength;
    NextKey = Pack_Tabel[AddNum % 0x162F] + 0x2E6D23C1;
    enbyte[i] = enbyte[i] ^ NextKey;
    AddNum = NextKey;
    i++;
  }

 

  j=i*4;
  NextKey ^= Pack_Tabel[NextLen % 0x162F];
 
  if (NextLen != 0)
  {
     while (NextLen--)
    {
      (BYTE)NewPacketAddr[j] = (BYTE)NewPacketAddr[j] ^ (BYTE)NextKey;
      NextKey = NextKey >> 8;
      j++;
    }
  }
}


 



至此封包算法已经逆完了,经过测试,是正确的:



 



取得服务端封包验证KEY...


开始发送帐号密码...


验证正常...


取得人物信息了...


帐号:h3389@vip.qq.com


人物:凌行恶


性别:男


等级:4



 



其实直接套汇编速度非常快,解了此游戏算法的人也不少,这里只是作为真正逆向代码的练习方法罢了。



接下来说一下是如何将算法逆成C++代码的,上面只给出了结果,其实我在个人空间里面分了两个贴子来说的,在这里直接就贴在下面给各位朋友参考,有不妥的地方还请大家批评指教:



寻找修改变量的代码,一直找到计算完毕,废话不多说,拿昨天的代码再来继续做个示例,看看我是如何把它逆成C++代码的:



 



(一)使用变量修改追踪找出单独的计算代码:



[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
赞赏记录
参与人
雪币
留言
时间
Youlor
为你点赞~
2024-3-14 00:25
伟叔叔
为你点赞~
2024-1-6 04:19
QinBeast
为你点赞~
2024-1-4 03:29
shinratensei
为你点赞~
2023-11-20 00:07
PLEBFE
为你点赞~
2023-11-17 04:01
心游尘世外
为你点赞~
2023-11-2 04:53
飘零丶
为你点赞~
2023-10-7 01:08
最新回复 (59)
雪    币: 44
活跃值: (24)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
版主帮忙把标题多了好几个的 原创 去掉吧,我编辑贴子编辑不了标题
2009-10-23 13:52
0
雪    币: 375
活跃值: (246)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
od 找关键代码 然后ida上场F5 收工
2009-10-23 14:22
0
雪    币: 44
活跃值: (24)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
牛人。。不过只是为了练习。。微软编译器这么强大,还是依然有人在研究编译原理不是。
2009-10-23 14:27
0
雪    币: 113
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
- -...根本沒必要把汇编逆向成C++或者C。。
汇编就是汇编。难不成有人会说把某个软件根据汇编码用C重写出来?
只要能看懂的就是代码。。
希望大家都明白这点。呵呵。
把汇编重写成高级语言我想应该是多此一举。
2009-10-23 16:55
0
雪    币: 44
活跃值: (24)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
啊,那请问下,如果能看得懂汇编,又只懂VB或易语言或Java,VB或易语言或Java又不能用内联汇编,是不是要转成高级语言再去使用呢?
如果用C/C++这种操作我已经说了,是浪费的,直接套汇编比什么都快。世界上语言这么多种,不能以C/C++为所有语言的标准来说事吧?
这里我用C++写的代码是因为我只对C++一知半解,其它的语言我不懂。
智者见智的事了。
2009-10-23 17:27
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
7
VB貌似也能内联汇编的,忘记是要加装什么控件了,是收费的
2009-10-23 18:09
0
雪    币: 18
活跃值: (80)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
在帖的精华
2009-10-23 18:26
0
雪    币: 370
活跃值: (52)
能力值: ( LV13,RANK:350 )
在线值:
发帖
回帖
粉丝
9
amwmqj在理 支持+学习 谢谢分享
技术学习和实际应用不能混为一谈的
2009-10-23 18:38
0
雪    币: 213
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
支持,科普知识!支持 free!
2009-10-24 10:22
0
雪    币: 243
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
咋不写出找加密算法的过程..
2009-10-24 11:53
0
雪    币: 433
活跃值: (1885)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
12
强悍!膜拜!!!!!!!
2009-10-24 12:17
0
雪    币: 356
活跃值: (38)
能力值: ( LV9,RANK:220 )
在线值:
发帖
回帖
粉丝
13
强大……顶礼膜拜……收藏了
2009-10-24 12:35
0
雪    币: 0
活跃值: (964)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
14
这个游戏,见过,不想说。
2009-10-24 13:08
0
雪    币: 8833
活跃值: (2419)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
15
...路过一下~
2009-10-24 13:20
0
雪    币: 193
活跃值: (1469)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
16
google 一下  xor     ebx, 2E6D23CF
我也不知道是不是那个游戏
没玩过
2009-10-24 13:56
0
雪    币: 22
活跃值: (48)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
等你发现技术比你高的人后。你也会见到这句话-----无聊人士勿扰

因为你以及未来的那个高人都生活在无聊/有聊的世界中

物以类聚,人以群分
2009-10-24 18:49
0
雪    币: 44
活跃值: (24)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18
有理,要改正。大家都是菜过来的,不过我想仁兄误解我的意思了。比我水平低的,有问题我懂的我也会回答,交流。我指的无聊人士,是那种……嗯。。。以后的事大家都知道了。。。
2009-10-24 20:04
0
雪    币: 213
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
请问老大,Pack_Tabel是什么东西
2009-10-26 10:28
0
雪    币: 44
活跃值: (24)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
20
密码表。

mov     ecx, dword ptr [edx*4+51A620]

就是上面这句获得的数据。

它是一个数组,起始位置是0x51A620,*4是以4递增,因为它是一个DWORD的数组。

EDX 即为数组下标。

长度:

div     dword ptr [51FEDC]  //这个常量是0x162F

由于取了0x162F 的余数来做数组下标

故余数不可能大于0x162F

这就是数组长度了。

Packet_Table[0x162F] = {...这里写上从0x51A620复制出来的内容就可以了}
2009-10-26 12:39
0
雪    币: 103
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
嗯, 强悍, 膜拜, 支持
2009-10-26 13:31
0
雪    币: 213
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
[QUOTE=amwmqj;704115]密码表。

mov     ecx, dword ptr [edx*4+51A620]

就是上面这句获得的数据。

它是一个数组,起始位置是0x51A620,*4是以4递增,因为它是一个DWORD的数组。

EDX 即为数组下标。

长度:

div     dword ...[/QUOTE]

谢谢,老大指点!
2009-10-26 13:44
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
哈哈,是**三网络版
2009-10-26 14:50
0
雪    币: 291
活跃值: (1759)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
24
写的很不错,学习..
2009-10-26 15:49
0
雪    币: 194
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
不顶对不起自已
2009-10-26 21:29
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册