能力值:
( LV2,RANK:10 )
在线值:
|
-
-
2 楼
呵呵,人家有做好的多开大厅补丁!!我也正想学呢
|
能力值:
( LV12,RANK:290 )
在线值:

|
-
-
3 楼
QQGame浅析系列(2) –从哪里开始
[LEFT] 我选择的是对”欢乐斗地主”进行分析,当时我的想法是三人斗地主总比四人斗地主要好分析的,实际上这是个错误的决定。在我具体分析时才知道三人斗地主的限制是多么的多,例如游戏玩家要受“欢乐豆”数量的限制,程序还有检测响应时间的机制,如果你在OD里时间过长,再返回到程序时就不能再玩了,一切还得重来。然而在四人斗地主里则没有上述两点的限制。我既然选择了对”欢乐斗地主”进行分析,那就不能回头了,一如既往![/LEFT]
让我们先理清一下玩家进行”欢乐斗地主”的过程:
1. 运行QQGame登录程序
2. 进入大厅
3. 选择”欢乐斗地主”游戏
4. 进入某个房间(Room)
5. 选择某个桌子(Table)坐下(sit down)
6. 准备
7. 当前桌子的玩家齐全且都为准备状态时,游戏开始,进入游戏LOOP
8. 游戏结束
9. 玩家可以离开此桌(stand up)回到房间,也可以退出此房间重新选择……
总之大致过程是这样的,我没有分析得很细,因为我们并不从这里切入,那要从哪里入手呢?要知道游戏整个过程都在不停地与服务器交换数据(send and recv),这些数据的流向才是我们所关心的。所以第一步应该截获网络数据,但是你千万不要使用什么网络数据截获(或者分析)之类的工具,那个对我们没有什么用处。我们这里要确切地知道数据的流向,而那些工具仅仅提供给我们冗余的数据(当然与游戏有关的数据也在其中,但都是加了密的),甚至还要误导我们思路。自己动手丰衣足食,下面开始分析数据的接受过程。
与网络数据发送有关的几个重要函数:send, recv, WSASend, WSARecv。所以我们的断点应该是:bp send,bp recv,bp WSASend, bp WSARecv。下完这四个断点后下一步是确定其中哪个与数据的接收发送有关。
相关知识点:如何对recv和WSARecv断点分析。
首先讲recv,中断这里后在堆栈窗口对buffer进行数据窗口跟随。按CTRL+F9,发现内存中有了接收的数据,然后在数据的第一个字节下读硬件中断,继续按F9运行,很快会中断到读取内存的地方。
一个实例,下面是欲调用recv时的堆栈提示,可以看清参数序列。
0393D628 03BD4606 /CALL 到 recv 来自 NetMod.03BD4600
0393D62C 00000534 |Socket = 534
0393D630 0393D648 |Buffer = 0393D648
0393D634 00002800 |BufSize = 2800 (10240.)
0393D638 00000000 \Flags = 0
在Buffer处右键“数据窗口中跟随”,这个Buffer就是数据的地址,没有什么复杂的结构,直接写硬件访问断点就OK,F9运行后就能观察哪里的代码使用了这里的数据。
然后是WSARecv,WSARecv的buffer是个结构指针,第一个双字是buffer大小,后面的才是数据,按CTRL+F9,发现接收数据,要在第5个字节地方下硬件访问中断,然后F9运行观看哪里的代码使用了这里的数据。
一个实例,下面是欲调用WSARecv时的堆栈提示,可以看清参数序列。
0013FB08 71A42EA3 /CALL 到 WSARecv 来自 WSOCK32.71A42E9E
0013FB0C 000000BC |Socket = BC
0013FB10 0013FB28 |pBuffers = 0013FB28
0013FB14 00000001 |nBuffers = 1
0013FB18 0013FB40 |pReceivedCount = 0013FB40
0013FB1C 0013FB3C |pFlags = 0013FB3C
0013FB20 00000000 |pOverlapped = NULL
0013FB24 00000000 \Callback = NULL
数据窗口中跟随pBuffers,要对其第五个字节开始的地方下硬件访问中断。
以上是需要知道的知识点,下面我们来确定游戏使用了上述的哪个函数,还是两个都使用了。下完所有断点,开始游戏,发现只有send和recv函数被中断下来。现在只分析接受数据,send中断暂且不理。按照上述知识点,完成对接收数据的硬件访问中断后F9,中断在:
03C54682 |. 57 |push edi ; /n
03C54683 |. 51 |push ecx ; |src
03C54684 |. 50 |push eax ; |dest
03C54685 |. 8946 10 |mov dword ptr [esi+10], eax ; |
03C54688 |. E8 65110000 |call <jmp.&MSVCRT.memcpy> ; \memcpy
03C5468D |. 56 |push esi
03C5468E |. FF75 E8 |push dword ptr [ebp-18]
03C54691 |. FF75 E4 |push dword ptr [ebp-1C]
03C54694 |. E8 E6000000 |call 03C5477F
这里是NetMod领空,看看所在的子过程吧:
*NetMod核心代码*
03C54410 /. 55 push ebp
03C54411 |. 8BEC mov ebp, esp
03C54413 |. B8 38290000 mov eax, 2938
03C54418 |. E8 23140000 call 03C55840
03C5441D |. 53 push ebx
03C5441E |. 56 push esi
03C5441F |. 8B75 08 mov esi, dword ptr [ebp+8]
03C54422 |. 57 push edi
03C54423 |. 8D7D E4 lea edi, dword ptr [ebp-1C]
03C54426 |. FF75 08 push dword ptr [ebp+8]
03C54429 |. A5 movs dword ptr es:[edi], dword ptr [e>
03C5442A |. A5 movs dword ptr es:[edi], dword ptr [e>
03C5442B |. A5 movs dword ptr es:[edi], dword ptr [e>
03C5442C |. A5 movs dword ptr es:[edi], dword ptr [e>
03C5442D |. E8 38030000 call 03C5476A
03C54432 |. 33DB xor ebx, ebx
03C54434 |. 33C0 xor eax, eax
03C54436 |. 8D7D D6 lea edi, dword ptr [ebp-2A]
03C54439 |. 66:895D D4 mov word ptr [ebp-2C], bx
03C5443D |. AB stos dword ptr es:[edi]
03C5443E |. AB stos dword ptr es:[edi]
03C5443F |. 59 pop ecx
03C54440 |. AB stos dword ptr es:[edi]
03C54441 |. 53 push ebx ; /Protocol => IPPROTO_IP
03C54442 |. 6A 01 push 1 ; |Type = SOCK_STREAM
03C54444 |. 6A 02 push 2 ; |Family = AF_INET
03C54446 |. 66:AB stos word ptr es:[edi] ; |
03C54448 |. FF15 1461C503 call dword ptr [<&WS2_32.#23>] ; \socket
03C5444E |. 8B7D EC mov edi, dword ptr [ebp-14]
03C54451 |. FF75 F0 push dword ptr [ebp-10] ; /NetShort
03C54454 |. 8BF0 mov esi, eax ; |
03C54456 |. 66:C745 D4 02>mov word ptr [ebp-2C], 2 ; |
03C5445C |. 8975 08 mov dword ptr [ebp+8], esi ; |
03C5445F |. 897D D8 mov dword ptr [ebp-28], edi ; |
03C54462 |. FF15 4061C503 call dword ptr [<&WS2_32.#9>] ; \ntohs
03C54468 |. 66:8945 D6 mov word ptr [ebp-2A], ax
03C5446C |. 8B45 E4 mov eax, dword ptr [ebp-1C]
03C5446F |. 3958 08 cmp dword ptr [eax+8], ebx
03C54472 |. 0F85 C4020000 jnz 03C5473C
03C54478 |. 8B1D 4C61C503 mov ebx, dword ptr [<&WS2_32.#12>] ; WS2_32.inet_ntoa
03C5447E |. 57 push edi
03C5447F |. FFD3 call ebx ; <&WS2_32.#12>
03C54481 |. 50 push eax
03C54482 |. 68 BC85C503 push 03C585BC ; ASCII "socketthread start connect ip %s!",LF
03C54487 |. 56 push esi
03C54488 |. E8 3B030000 call 03C547C8
03C5448D |. 83C4 0C add esp, 0C
03C54490 |. 8D45 D4 lea eax, dword ptr [ebp-2C]
03C54493 |. 6A 10 push 10 ; /AddrLen = 10 (16.) |