先用command下recv断点,F9运行
输入帐号密码后,程序被断下
位置在recv入口,直接Ctrl+F9,去到retn,按F8,回来SO2Game领空
看到游戏调用recv的情况
005A4EB0 push 0 ; recv的flag
005A4EB2 mov edx,2C
005A4EB7 sub edx,edi
005A4EB9 push edx ; 用于取回封包长度
005A4EBA lea eax,dword ptr ds:[edi+esi+1D8]
005A4EC1 push eax ; 封包内容存放地址
005A4EC2 push ebp ; socket句柄
005A4EC3 call ebx ; 执行recv
接收到第一个recv后,校验封包是否为key包
005A4EC5 test eax,eax <---从recv出来后,EIP在这里
005A4EC7 jle SO2Game.005A4F9F
005A4ECD add edi,eax
005A4ECF cmp edi,2C ;检查长度是否为2C,如果是,就是key封包
005A4ED2 jnz short SO2Game.005A4E80
005A4ED4 cmp byte ptr ds:[esi+1DA],20
005A4EDB jnz short SO2Game.005A4E80
005A4EDD mov al,byte ptr ds:[esi+1DB]
005A4EE3 test al,al
005A4EE5 je SO2Game.005A4FB7 ; 如果正常,跳到005A4FB7取key函数
005A4EEB push SO2Game.005D7888 ; ASCII "Server send cliper mode error!"
省略异常处理语句,有兴趣的自己看
005A4FAF pop edi
005A4FB0 pop esi
005A4FB1 pop ebp
005A4FB2 pop ebx
005A4FB3 mov esp,ebp
005A4FB5 pop ebp
005A4FB6 retn
取出两个dword,做异或和移位操作后,做为加解密key
以这个封包为例
2C 00 20 00 61 69 79 65 66 75(9F 4A ED CC)00 00
00 00 00[34 D5 25 28]00 00 00 00 00 00 00 00 00
00 00 00 CF C6 01 00 8F AB 47 E4 82
[xxxxxx]为第一次取出的key原码
(xxxxxx)为第二次取出的key原码
005A4FB7 mov dword ptr ds:[esi+1CC],0 ; 不知是啥,好像是置某个状态为0
005A4FC1 mov eax,dword ptr ds:[esi+1EB] ; 开始取原始key1,封包起始地址偏移19字节,2825D534
005A4FC7 mov ecx,eax ; 原始key1复制一份到ecx寄存器
005A4FC9 xor ecx,6D23CF ; 原始key1与6D23CF异或,存入ecx寄存器
005A4FCF mov edx,eax ; 原始key1复制一份到edx寄存器
005A4FD1 sub ecx,SO2Game.006D2399 ; 异或后的key1减去006D2399(立即寻址方式),结果:27DBD362
005A4FD7 xor edx,2E6D23CF ; 原始key1与2E6D23CF异或
005A4FDD xor eax,FFFFFFCF ; 原始key1与FFFFFFCF异或
005A4FE0 not ecx ; ecx取反,操作数27DBD362,结果D8242C9D
005A4FE2 sub edx,2E6D2399 ; edx减去2E6D2399,结果D7DBD362
005A4FE8 add eax,67 ; eax加67H,结果D7DA2B62
005A4FEB and ecx,0FFFF00 ; ecx按位与,即清掉最高位和最低两位,结果00242C00
005A4FF1 not edx ; edx按位取反,结果28242C9D
005A4FF3 shr edx,18 ; edx右移18H位,24位,结果00000028
005A4FF6 or ecx,edx ; ecx和edx进行按位或,结果ecx=00242C28
005A4FF8 not eax ;eax=2825D49D
005A4FFA shl eax,18 ;eax=9D000000
005A4FFD or ecx,eax ;ecx=9D242C28
005A4FFF mov dword ptr ds:[esi+1D0],ecx ;第一个key生成完毕,放入内存中
005A5005 mov eax,dword ptr ds:[esi+1E2] ;取原始key2,接下来与上面大同小异,不详写了
005A500B mov ecx,eax
005A500D mov edx,eax
005A500F xor ecx,6D23CF
005A5015 xor edx,2E6D23CF
005A501B sub ecx,SO2Game.006D2399
005A5021 xor eax,FFFFFFCF
005A5024 sub edx,2E6D2399
005A502A not ecx
005A502C add eax,67
005A502F and ecx,0FFFF00
005A5035 not edx
005A5037 shr edx,18
005A503A not eax
005A503C or ecx,edx
005A503E shl eax,18
005A5041 or ecx,eax ; ecx=48ECBA4B,第二个key生成啦
005A5043 mov dword ptr ds:[esi+1D4],ecx ;第二个key生成完毕,放入内存中
005A5049 mov ecx,dword ptr ss:[esp+17C]
005A5050 pop edi
005A5051 mov al,1
005A5053 mov dword ptr fs:[0],ecx
005A505A pop esi
005A505B pop ebp
005A505C pop ebx
005A505D mov esp,ebp
005A505F pop ebp
005A5060 retn
结论:两个key被入在ds:[esi+1D0]和ds:[esi+1D4]中
快下班了,今天就搞到这里,明天再来看看剑侠2是怎么用这两个key加解密游戏封包的。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!