用IDA看下这游戏从ws2_32导入了哪些函数..网络游戏通迅一般用到的是send,recv,WSASend,WSARecv这四个API函数.发现用到了recv,WSASend,WSARecv,游戏中时发现并未用recv,所以有可能登陆用到了,初步分析是游戏过程中用WSASend和WSARecv通讯,recv用来登陆收包
进游戏后下断bp WSASend,游戏中按V(坐下),游戏被断下,看堆栈区:
0012F1B8 0056616A /CALL 到 WSASend 来自 GAME1_.00566164
0012F1BC 00000318 |Socket = 318
0012F1C0 03E9B07C |pBuffers = 03E9B07C
0012F1C4 00000001 |nBuffers = 1
0012F1C8 0012F1E8 |pBytesSent = 0012F1E8
0012F1CC 00000000 |Flags = 0
0012F1D0 00000000 |pOverlapped = NULL
0012F1D4 00000000 \Callback = NULL
疑问:某些游戏或软件没有用到WSASend断点。而是用到了send,可是BP send下断之后变成这样。
0012FB68 0061535B /CALL 到 send 来自 Game.00615355
0012FB6C 0000021C |Socket = 21C
0012FB70 7FDC0040 |Data = 7FDC0040
0012FB74 0000003D |DataSize = 3D (61.)
0012FB78 00000004 \Flags = MSG_DONTROUTE
其中0012FB70 7FDC0040 |Data = 7FDC0040是否就是buf?请大牛帮忙解释一下这些堆栈以及对比一下有什么不同?
WSASend的第二个参数buffer指向加密后的包结构,
03E9B07C 04 00 00 00 E8 0B 2E 01 DC C3 E9 03 01 00 00 00 ...?. 苊? ...
03E9B08C 00 04 00 00 00 00 00 00 E8 0B 2E 01 51 00 00 00 . ......?. Q...
观察发现 03E9B080的地址不变,dd 012E0BE8查看发现此地址存放着好像包的内容..
难道需要多次调试,对比一下才知道 03E9B080的地址不变?而dd 012E0BE8又是怎么得来的?03E9B080的地址不变和dd 012E0BE8又有什么关系啊
012E0BE8 E7FF0004
一般游戏函数调用流程是这样的:
功能函数(打坐)->明文发包函数(明文包)->加密函数(密文包)->通讯函数(send等通讯函数发送密文包..)
通讯函数(recv等通讯函数收到密文包..)->解密函数(密文包)->解密明文包(解密后的明文包)..
所以012E0BE8地址存放的是密文包.再次下断bp WSASend,按V断下,连续两次CRTL+F9,加密过程要往回找(解密过程往下找);
005605B0 A1 A4F25C00 mov eax, dword ptr [5CF2A4]//F2下断单步调试,看012E0BE8何时生成
005605B5 53 push ebx
005605B6 83F8 02 cmp eax, 2
005605B9 55 push ebp
005605BA 0F84 CE000000 je 0056068E
005605C0 83F8 03 cmp eax, 3
005605C3 0F84 C5000000 je 0056068E
005605C9 83F8 04 cmp eax, 4
005605CC 0F84 BC000000 je 0056068E
005605D2 83F8 05 cmp eax, 5
005605D5 0F84 B3000000 je 0056068E
005605DB 83F8 06 cmp eax, 6
005605DE 0F84 AA000000 je 0056068E
005605E4 83F8 07 cmp eax, 7
005605E7 0F84 A1000000 je 0056068E
005605ED 83F8 08 cmp eax, 8
005605F0 0F84 98000000 je 0056068E
005605F6 8B6C24 10 mov ebp, dword ptr [esp+10]
005605FA 85ED test ebp, ebp
005605FC 0F84 93000000 je 00560695
00560602 8B5C24 14 mov ebx, dword ptr [esp+14]
00560606 833B 00 cmp dword ptr [ebx], 0
00560609 0F84 86000000 je 00560695
0056060F 56 push esi
00560610 57 push edi
00560611 8B7C24 14 mov edi, dword ptr [esp+14]
00560615 8D4F 0C lea ecx, dword ptr [edi+C]
00560618 E8 83640000 call 00566AA0
0056061D 8BF0 mov esi, eax
0056061F 8B03 mov eax, dword ptr [ebx]
00560621 8D4C24 18 lea ecx, dword ptr [esp+18]
00560625 6A 02 push 2
00560627 83C0 02 add eax, 2
0056062A 51 push ecx
0056062B 8BCE mov ecx, esi
0056062D 894424 20 mov dword ptr [esp+20], eax
00560631 E8 3A610000 call 00566770
00560636 8B13 mov edx, dword ptr [ebx]
00560638 8BCE mov ecx, esi
0056063A 52 push edx
0056063B 55 push ebp
0056063C E8 2F610000 call 00566770
00560641 8B8F D4020000 mov ecx, dword ptr [edi+2D4]
00560647 85C9 test ecx, ecx
00560649 75 1B jnz short 00560666
0056064B 8B4E 44 mov ecx, dword ptr [esi+44]
0056064E 8B13 mov edx, dword ptr [ebx]
00560650 8D87 D8010000 lea eax, dword ptr [edi+1D8]
00560656 83C1 02 add ecx, 2
00560659 50 push eax
0056065A 51 push ecx
0056065B 52 push edx
0056065C E8 AF700000 call 00567710 //发现经过这个CALL后,12E0BE8中的包生成,所以这有可能是加密函数..重新在此处下断,去掉原先断点,F7跟进.
00560661 83C4 0C add esp, 0C
00560664 EB 16 jmp short 0056067C
00560666 8D97 D8010000 lea edx, dword ptr [edi+1D8]
0056066C 8B01 mov eax, dword ptr [ecx]
0056066E 52 push edx
0056066F 8B56 44 mov edx, dword ptr [esi+44]
00560672 83C2 02 add edx, 2
00560675 52 push edx
00560676 8B13 mov edx, dword ptr [ebx]
00560678 52 push edx
00560679 FF50 08 call dword ptr [eax+8]
0056067C 56 push esi
0056067D 8D4F 04 lea ecx, dword ptr [edi+4]
00560680 E8 4B5A0000 call 005660D0
00560685 8BCE mov ecx, esi
00560687 E8 24620000 call 005668B0
0056068C 5F pop edi
0056068D 5E pop esi
0056068E 5D pop ebp
0056068F 33C0 xor eax, eax
00560691 5B pop ebx
00560692 C2 0C00 retn 0C
00567710 8B4424 0C mov eax, dword ptr [esp+C]
00567714 8D5424 0C lea edx, dword ptr [esp+C]
00567718 52 push edx
00567719 8B08 mov ecx, dword ptr [eax]
0056771B 8B4424 0C mov eax, dword ptr [esp+C]
0056771F 894C24 10 mov dword ptr [esp+10], ecx
00567723 8B4C24 08 mov ecx, dword ptr [esp+8]
00567727 50 push eax
00567728 51 push ecx //包长
00567729 E8 82FFFFFF call 005676B0 //继续F7跟进
005676B0 53 push ebx
005676B1 8B4424 0C mov eax, dword ptr [esp+C]//明文包地址
005676B5 56 push esi
005676B6 8B7424 0C mov esi, dword ptr [esp+C]//包长度
005676BA 57 push edi
005676BB 8B7C24 18 mov edi, dword ptr [esp+18]//加密密钥
005676BF 8BD6 mov edx, esi
005676C1 8B0F mov ecx, dword ptr [edi]
005676C3 83E2 03 and edx, 3
005676C6 C1EE 02 shr esi, 2
005676C9 74 0D je short 005676D8
005676CB 8B18 mov ebx, dword ptr [eax]
005676CD 83C0 04 add eax, 4
005676D0 33D9 xor ebx, ecx
005676D2 4E dec esi
005676D3 8958 FC mov dword ptr [eax-4], ebx
005676D6 ^ 75 F3 jnz short 005676CB
005676D8 85D2 test edx, edx
005676DA 76 0D jbe short 005676E9
005676DC 8A18 mov bl, byte ptr [eax]
005676DE 32D9 xor bl, cl
005676E0 8818 mov byte ptr [eax], bl
005676E2 40 inc eax
005676E3 C1E9 08 shr ecx, 8
005676E6 4A dec edx
005676E7 ^ 75 F3 jnz short 005676DC
005676E9 8B07 mov eax, dword ptr [edi]
005676EB 8BC8 mov ecx, eax
005676ED C1E1 05 shl ecx, 5
005676F0 2BC8 sub ecx, eax
005676F2 B8 01000000 mov eax, 1
005676F7 81C1 05840808 add ecx, 8088405
005676FD 890F mov dword ptr [edi], ecx
005676FF 5F pop edi
00567700 5E pop esi
00567701 5B pop ebx
00567702 C3 retn
在单步调试的时候发现数据段中的数据是4字节4字节在变的..走完这段,密文包也就出来了..又因为这段没调用别的什么模块..所以断定这是加密函数..(希望大家学的是方法,加密往前跟,解密往后跟,,你会发现这游戏调用的加解密是同一个函数,只是密钥不同,所以解密过程就不分析了.)
CString EncAndDec(CString datestr,CString key,int len) //加解密函数
{
int j,nprev,nkey,nxor;
CString strxor,nxor1;
j=0;
strxor=NULL;
for(int i=0;i<len,i++)
{
if (i<2)
{
strxor=strxor+copy(datastr,i*2+1,2);
continue;
}
nprev=(long int)((int)("0x"+copy(datastr,i*2+1,2)));
nkey=(long int)((int)("0x"+copy(key,i*2+1,2)));
j++;
if (j>3)
{
j=0;
}
nxor=nprev ^ nkey;
strxor=strxor+nxor1.Format("%x",nxor);
}
return strxor;
}
密钥的查找:
退出游戏,在选择服务器前下断:bp recv;选择服务器后断下:
0012F928 00566447 /CALL 到 recv 来自 GAME1_.00566445
0012F92C 00000360 |Socket = 360
0012F930 04C5983C |Buffer = 04C5983C
0012F934 00000022 |BufSize = 22 (34.)
0012F938 00000000 \Flags = 0
dd 04C5983C,ALT+F9看收到的数据:
04C5983C 22 00 20 00 D4 47 EE F9 D8 3B 99 89 F0 01 6E AC ". .讷铢?槟?n
04C5984C 62 7B 1A 75 64 97 FE C9 68 8B 22 5D AC BF 86 31 b{ ud楟蒱?] ?
04C5985C 30 33 ED B8 60 03 00 00 00 00 00 00 00 00 00 00 03砀` ..........
取消recv断点,在04C59840开始下硬件访问断点,再登陆,如果没反应,在04C59844处下硬件访问断点,依次类推.发现在04C59848处下访问断点断下;
005665D5 C785 CC010000 0>mov dword ptr [ebp+1CC], 0
005665DF 8B85 E2010000 mov eax, dword ptr [ebp+1E2]
005665E5 F7D0 not eax
005665E7 8985 D0010000 mov dword ptr [ebp+1D0], eax
005665ED 8B8D E6010000 mov ecx, dword ptr [ebp+1E6]
005665F3 F7D1 not ecx
005665F5 898D D4010000 mov dword ptr [ebp+1D4], ecx
005665FB B0 01 mov al, 1
005665FD ^ EB BD jmp short 005665BC
005665FF 90 nop
00566600 83E9 08 sub ecx, 8
00566603 ^ E9 58EAFFFF jmp 00565060
分析发现它会将这buffer中的数据取字,4字节反一下,然后存到另一个地方,之后又从buffer中取出另4字节作出同样的操作..验证下.. 发现:
005676BB 8B7C24 18 mov edi, dword ptr [esp+18]//加密密钥中的值
005665E7 8985 D0010000 mov dword ptr [ebp+1D0], eax//和上面的值相等
所以此处是加密密钥..同理.解密密钥就在加密密钥后面4字节
如果服务器发送的密匙是随便发的,找他有何用?最多找到密匙存放处以及怎么存放和怎么加密算法的。才有用啊。可以依葫芦画瓢写个程序达到一样的作用吧?难道是这个意思?小弟最近学习封包的加密解密算法定位和密匙的查找。不知道大牛们有没有相关资料。如果能倾囊教授的或者有想收徒弟的。不嫌弃我愚笨的。请加QQ99869532有想一起学的也加吧.在此先膜拜一下大牛们。这年头。。。。大牛都很忙。有时候连回答个问题都很懒了。。。
那啥?这些天想哭来着。都这么多年了。一点长进都没有啊。书是看了不少。又懂又不懂。能看明白,其实又不明白。好期望有个启蒙老师。。马达..一个大老爷们竟然为这事掉眼泪。。希望大牛们帮下忙。偶尔提下问题能热心帮忙解决。也就知足了。。
还有就是封包的加密算法就一定在程序领空吧?
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课