数据发送接收情况:
........客户端与Gateserver,Loginserver的数据互换,省略
1. 客户端向Gameserver发送[**登录用户名/角色名/验证数1/验证数2/版本验证数/1/0]
2. Gameserver向客户端发送密文,类似#eLrBHMNx<F=hgmlYA]X]ENtpGM`X@?PuN`LwT_m>RmleJ_l{PAMHQ?pUCpdbENa<F`pjBllQC=HSC\\pT?LduQ_y=PQM>JptK!
3. 客户端向Gameserver发送解密后密文,类似#3<<<<<Jx?<<<<<<<<A>xZCNLSHoPpAnQRF?ljIaaUPmlSF^L_BmtfFODJA_X\\A]T`GNlq@L!
........欢迎信息,装备信息等省略
数据格式
[#][标识位][指令头][消息体][!]
例如 #3<<<<<B\\<<<<<<<<<mi{EhL!
命令结构体
typedef struct tag_TDEFAULTMESSAGE
{
int nRecog;
WORD wIdent; 3EF
WORD wParam;
WORD wTag;
WORD wSeries;
} _TDEFAULTMESSAGE, *_LPTDEFAULTMESSAGE;
解密命令体<<<<<Jx?<<<<<<<<得到wIdent值是3EF(1007),OD打开Mir3.exe,查找常量000003EF,跟踪进入,得到如下代码
>>Method1(未知参数)
push esi
push edi
push 0
push 0
push 0
push 0
mov esi, ecx
push 3EF
lea edi, dword ptr [esi+18] ;esi+18 是命令结构体的首地址
push edi ;命令结构体首地址
call 004A0D00 ;生成命令结构体 (edi,3ef,0,0,0,0)
mov eax, dword ptr [esp+C] ; eax保存第一个参数
push 0
push eax
push edi
mov ecx, esi ;传递this指针,
call 0049E450 ;发送数据,arg3: 0, arg2: 第一个参数, arg1: 命令结构体
pop edi
pop esi
retn 4
简单分析,入栈的4个0和3EF,则对应结构体,该函数至少1个参数,目前不知这个参数是什么意思,跟进0049E450看看
>>Method2(命令结构体,未知参数,0)
mov eax, dword ptr [esp+4] ;eax=命令结构体
push ebx
push ebp
push esi
mov esi, ecx ;得到this指针
push 20
lea ebp, dword ptr [esi+24] ;esi+18是命令结构体,加密命令结构体得到的字符串保存在esi+24中
push ebp
push eax
call 004A0CA0 ;跟进发现是加密命令结构体,arg3: 20(32), arg2: esi+24, arg1: 命令结构体地址
mov eax, dword ptr [esi+14] ;eax=esi+14=标识位
cmp eax, 9
jl L015 ;如果标识位小于9,则跳到L015
mov dword ptr [esi+14], 1 ;否则标识位重设为1
jmp L017
L015:
inc eax
mov dword ptr [esi+14], eax ;标识位自加1
L017:
mov edx, dword ptr [esp+14] ;edx=第2个参数
test edx, edx ;
je L048 ;如果第2个参数为0,则跳转到L048
mov eax, dword ptr [esp+18] ;eax=第3个参数: 0
test eax, eax
push edi
jnz L031 ;eax不等于0则跳转
mov eax, edx ;eax=第2个参数
lea edi, dword ptr [eax+1]
L026:
mov cl, byte ptr [eax] ;cl=第2个参数第1个字节
inc eax ;eax
test cl, cl ;循环得到第一个参数的长度
jnz L026 ;没到字符串尾则继续循环
sub eax, edi
L031:
push 2000
push eax
lea edi, dword ptr [esi+44]
push edi
push edx
call 004A0B10 ;调用加密函数,将edx加密,保存在esi+44中
mov ecx, dword ptr [esi+14]
push edi
push ebp
push ecx
lea ebx, dword ptr [esi+2044]
push 004CBFE4 ; #%d%s%s!
push ebx
call 004BB568
add esp, 14
pop edi
jmp L056
L048:
mov edx, dword ptr [esi+14]
push ebp
push edx
lea ebx, dword ptr [esi+2044]
push 004CBFC4 ; #%d%s!
push ebx
call 004BB568 ;sprintf 格式化发送给服务器端的数据
add esp, 10
L056:
mov eax, ebx
lea edx, dword ptr [eax+1]
L058:
mov cl, byte ptr [eax]
inc eax ;这个循环得到数据长度
test cl, cl
jnz L058
push 0
sub eax, edx
push eax ; 数据长度
mov eax, dword ptr [esi+6044]
push ebx ; Data ,要发送的数据
push eax ; Socket对象
call <jmp.&WS2_32.#19> ;这里是调用send(Socket对象, 要发送的数据, 数据长度, 0 (flag));
pop esi
pop ebp
pop ebx
retn 0C
L017和L031说明Method1和Method2中的未知参数就是明文消息体,Method1只有1个消息体参数
posted on 2008-06-01 10:48
Phrancol Yang 阅读(552)
评论(0) 编辑 收藏 所属分类:
反汇编