随笔 - 1  文章 - 37  trackbacks - 0
<2024年12月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

留言簿(16)

随笔分类

随笔档案

文章分类

文章档案

test

搜索

  •  

最新评论

数据发送接收情况:
........客户端与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)  编辑  收藏 所属分类: 反汇编

只有注册用户登录后才能发表评论。


网站导航: