由于加密是RC4算法,那么发包必须要共用加密密匙表,需要同步处理。
游戏中的代码
110DFB73 6A 01 push 1
110DFB75 8D4C24 0A lea ecx, dword ptr [esp+A]
110DFB79 51 push ecx
110DFB7A 8D5424 0F lea edx, dword ptr [esp+F]
110DFB7E 52 push edx
110DFB7F E8 2CA00500 call 11139BB0
110DFB84 83C4 0C add esp, 0C
110DFB87 6A 01 push 1
110DFB89 8D4424 0A lea eax, dword ptr [esp+A]
110DFB8D 50 push eax
110DFB8E B9 44F55611 mov ecx, 1156F544
110DFB93 E8 586B0500 call 111366F0
110DFB98 8D4C24 08 lea ecx, dword ptr [esp+8]
110DFB9C 51 push ecx
110DFB9D 8B0D 446C6411 mov ecx, dword ptr [11646C44]
110DFBA3 56 push esi
110DFBA4 E8 37B30500 call 1113AEE0
110DFBA9 46 inc esi
110DFBAA 837C24 08 00 cmp dword ptr [esp+8], 0
110DFBAF 884424 07 mov byte ptr [esp+7], al
110DFBB3 ^ 7D BE jge short 110DFB73
第一个CALL是加密要发送的明文数据,第二个CALL是把加密后的数据保存至缓冲区,第三个CALL取明文(明文是加密过的,这里其实是解密明文)
这是第一个CALL加密代码
11136780 > A1 A07E6811 mov eax, dword ptr [11687EA0]
11136785 . |40 inc eax
11136786 . |25 FF000000 and eax, 0FF
1113678B . |A3 A07E6811 mov dword ptr [11687EA0], eax
11136790 . |0FB688 A07D68>movzx ecx, byte ptr [eax+11687DA0]
11136797 . |030D A47E6811 add ecx, dword ptr [11687EA4]
1113679D . |46 inc esi
1113679E . |81E1 FF000000 and ecx, 0FF
111367A4 . |890D A47E6811 mov dword ptr [11687EA4], ecx
111367AA . |8A90 A07D6811 mov dl, byte ptr [eax+11687DA0]
111367B0 . |8A89 A07D6811 mov cl, byte ptr [ecx+11687DA0]
111367B6 . |8888 A07D6811 mov byte ptr [eax+11687DA0], cl
111367BC . |A1 A47E6811 mov eax, dword ptr [11687EA4]
111367C1 . |02CA add cl, dl
111367C3 . |0FB6C9 movzx ecx, cl
111367C6 . |8890 A07D6811 mov byte ptr [eax+11687DA0], dl
111367CC . |0FB691 A07D68>movzx edx, byte ptr [ecx+11687DA0]
111367D3 . |32542E FF xor dl, byte ptr [esi+ebp-1]
111367D7 . |88541E FF mov byte ptr [esi+ebx-1], dl
111367DB . |3BF7 cmp esi, edi
111367DD .^\7C A1 jl short 11136780
我的假设方法如下:
cs.Lock();
110DFB73 6A 01 push 1
110DFB75 8D4C24 0A lea ecx, dword ptr [esp+A]
110DFB79 51 push ecx
110DFB7A 8D5424 0F lea edx, dword ptr [esp+F]
110DFB7E 52 push edx
110DFB7F E8 2CA00500 call 11139BB0
110DFB84 83C4 0C add esp, 0C
110DFB87 6A 01 push 1
110DFB89 8D4424 0A lea eax, dword ptr [esp+A]
110DFB8D 50 push eax
110DFB8E B9 44F55611 mov ecx, 1156F544
110DFB93 E8 586B0500 call 111366F0
110DFB98 8D4C24 08 lea ecx, dword ptr [esp+8]
110DFB9C 51 push ecx
110DFB9D 8B0D 446C6411 mov ecx, dword ptr [11646C44]
110DFBA3 56 push esi
110DFBA4 E8 37B30500 call 1113AEE0
110DFBA9 46 inc esi
110DFBAA 837C24 08 00 cmp dword ptr [esp+8], 0
110DFBAF 884424 07 mov byte ptr [esp+7], al
110DFBB3 ^ 7D BE jge short 110DFB73
cs.Unlock();
我在游戏的代码中,加入了临界区
然后,在我自已的加密发包函数中也用了临界区
// 发送加密数据包函数
void SendDataPacket(int len, BYTE *buf)
{
cs.Lock();
for (int i=0; i<len; i++)
{
// 加密过程在此省略 算法是RC4
buf[i] = *(pEncrypt + ((key_1 + key_2) & 255)) ^ buf[i];
}
send(GET_DWORD(SockedAddr), (char *)buf, len, 0);
cs.Unlock();
}
我现在能发包了,在游戏中也能看到我的喊话,但是有一个问题,就是有时发一个包,有时能发两三个包后就再也不能与NPC对话了,地图也不能跳过,但能看到玩家移动,实际就是send数据出问题了?请问这是什么问题,同步没做好吗?想大牛们帮帮小弟,小弟在此感激不尽~~!
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!