MT4客戶端通訊分析(一)——登入部分分析

MT4Develop發表於2016-04-26

免責宣告:本文僅內容作為學習交流使用,不可用於任何商業途徑
MT4客戶端225通訊協議分析。

通過對send下斷,找到第一個傳送的資料包,即登入內容,通過呼叫棧往上找到關鍵的函式呼叫,登入函式接收以下4個引數
(1) 使用者ID(int) (2) 密碼(pchar) (3) 0 (4) 0
相關程式碼如下

_text:00434AD0                 sub     esp, 0A8h
_text:00434AD6                 push    ebx
_text:00434AD7                 push    ebp
_text:00434AD8                 push    esi
_text:00434AD9                 mov     esi, ecx
_text:00434ADB                 push    edi
_text:00434ADC                 xor     ebx, ebx
_text:00434ADE                 mov     ecx, 6
_text:00434AE3                 xor     eax, eax
_text:00434AE5                 lea     edi, [esp+0B8h+var_A7] ; 指向Buf的第二位元組
_text:00434AE9                 mov     [esp+0B8h+buf], bl ; Buf的第一位元組賦0
_text:00434AED                 rep stosd
_text:00434AEF                 mov     ebp, [esp+0B8h+arg_4] ; 引數密碼
_text:00434AF6                 stosw
_text:00434AF8                 cmp     ebp, ebx
_text:00434AFA                 stosb
_text:00434AFB                 jz      loc_0_434CFA    ; 密碼為空則退出
_text:00434B01                 cmp     dword ptr [esp+0B8h+ArgList], 1 ; 使用者ID為1則退出
                    (1是MT4的預設管理員, 不能用於客戶端登入)
_text:00434B09                 jl      loc_0_434CFA
_text:00434B0F                 mov     edi, ebp        ; 計算密碼的長度存於ECX
_text:00434B11                 or      ecx, 0FFFFFFFFh
_text:00434B14                 xor     eax, eax
_text:00434B16                 repne scasb
_text:00434B18                 not     ecx
_text:00434B1A                 dec     ecx
_text:00434B1B                 cmp     ecx, 1          ; 密碼最小長度1
_text:00434B1E                 jb      loc_0_434CFA
_text:00434B24                 cmp     dword ptr [esi+4], 0FFFFFFFFh
_text:00434B28                 jnz     short loc_0_434B3C ; ECX=271BBDC 一個空的Buffer
_text:00434B2A                 pop     edi
_text:00434B2B                 pop     esi
_text:00434B2C                 pop     ebp
_text:00434B2D                 mov     eax, 6
_text:00434B32                 pop     ebx
_text:00434B33                 add     esp, 0A8h
_text:00434B39                 retn    10h
_text:00434B3C ; ---------------------------------------------------------------------------
_text:00434B3C
_text:00434B3C loc_0_434B3C:                           ; CODE XREF: UserLogin+58j
_text:00434B3C                 lea     ecx, [esp+0B8h+var_6C] ; ECX=271BBDC 一個空的Buffer
_text:00434B40                 call    sub_0_433A10    ; SetMagicBufferTo ECX
_text:00434B45                 mov     edi, ebp        ; EDI = PSW
_text:00434B47                 or      ecx, 0FFFFFFFFh ; EXC = LEN(PSW)
_text:00434B4A                 xor     eax, eax
_text:00434B4C                 repne scasb
_text:00434B4E                 not     ecx
_text:00434B50                 dec     ecx
_text:00434B51                 push    ecx
_text:00434B52                 push    ebp
_text:00434B53                 lea     ecx, [esp+0C0h+var_6C]
_text:00434B57                 call    sub_0_433A40    ; FormatPswToECX
_text:00434B5C                 lea     ecx, [esp+0B8h+var_6C] ; 指向271BBDC
_text:00434B60                 call    sub_0_433B20    ; MD5
_text:00434B65                 lea     edi, [esi+18Ch] ; 120D6E0
_text:00434B6B                 lea     ecx, [esp+0B8h+var_6C] ; MD5(PSW)271BBDC
_text:00434B6F                 push    edi
_text:00434B70                 call    sub_0_433BA0    ; COPY到120D6E0
_text:00434B75                 mov     eax, edi        ; COPY 到 271BBBC
_text:00434B77                 mov     ecx, [eax]
_text:00434B79                 mov     [esp+0B8h+var_8C], ecx
_text:00434B7D                 mov     edx, [eax+4]
_text:00434B80                 mov     [esp+0B8h+var_88], edx
_text:00434B84                 mov     ecx, [eax+8]
_text:00434B87                 mov     [esp+0B8h+var_84], ecx
_text:00434B8B                 mov     edx, [eax+0Ch]
_text:00434B8E                 xor     eax, eax
_text:00434B90                 mov     [esp+0B8h+var_80], edx
_text:00434B94
_text:00434B94 loc_0_434B94:                           ; CODE XREF: UserLogin+DCj
_text:00434B94                 mov     dl, [edi+eax]   ; 對MD5進行變換, 結果(暫且稱為EnMD5)存在271BBBC
_text:00434B97                 mov     cl, byte ptr [esp+eax+0B8h+var_8C]
_text:00434B9B                 add     dl, bl
_text:00434B9D                 xor     dl, cl
_text:00434B9F                 movsx   ebp, cl
_text:00434BA2                 mov     byte ptr [esp+eax+0B8h+var_8C], dl
_text:00434BA6                 inc     eax
_text:00434BA7                 cmp     eax, 10h
_text:00434BAA                 mov     ebx, ebp
_text:00434BAC                 jl      short loc_0_434B94 ; 對MD5進行變換, 結果(暫且稱為EnMD5)存在271BBBC
_text:00434BAE                 mov     edi, [esp+0B8h+arg_8]
_text:00434BB5                 mov     eax, edi
_text:00434BB7                 dec     eax
_text:00434BB8                 neg     eax
_text:00434BBA                 sbb     al, al
_text:00434BBC                 xor     ebx, ebx
_text:00434BBE                 and     al, 0F5h
_text:00434BC0                 push    ebx             ; Time
_text:00434BC1                 add     al, 0Bh
_text:00434BC3                 mov     [esp+0BCh+buf], al
_text:00434BC7                 call    ds:time         ; 用時間取一個隨機數
_text:00434BCD                 mov     ecx, [esp+0BCh+var_8C]
_text:00434BD1                 mov     edx, [esp+0BCh+var_88]
_text:00434BD5                 mov     ebp, dword ptr [esp+0BCh+ArgList] ; Login
_text:00434BDC                 add     esp, 4
_text:00434BDF                 cmp     edi, 2
_text:00434BE2                 mov     [esp+0B8h+var_A5], ecx ; EnMD5(0)
_text:00434BE6                 mov     ecx, [esp+0B8h+var_80]
_text:00434BEA                 mov     [esp+0B8h+var_A1], edx ; EnMD5(1)
_text:00434BEE                 setz    dl
_text:00434BF1                 mov     [esp+0B8h+var_A7], al ; 隨機數存到Buf的01位元組
_text:00434BF5                 mov     eax, [esp+0B8h+var_84]
_text:00434BF9                 mov     [esp+0B8h+var_99], ecx ; MD5(3)
_text:00434BFD                 mov     [esp+0B8h+var_8D], dl
_text:00434C01                 mov     edx, 1Bh        ; Buf的長度-1
_text:00434C06                 lea     ecx, [esp+0B8h+var_A7]
_text:00434C0A                 mov     [esp+0B8h+var_A6], bl
_text:00434C0E                 mov     [esp+0B8h+var_95], ebp ; Login
_text:00434C12                 mov     [esp+0B8h+var_9D], eax ; MD5(2)
_text:00434C16                 mov     [esp+0B8h+var_91], 190h ; Ver
_text:00434C1D                 mov     [esp+0B8h+var_8F], 0E1h ; Build
_text:00434C24                 call    sub_0_433990    ; 轉換Buf
_text:00434C29                 lea     eax, [esp+0B8h+buf]
_text:00434C2D                 push    1Ch             ; len
_text:00434C2F                 push    eax             ; buf
_text:00434C30                 mov     ecx, esi
_text:00434C32                 call    sub_0_50AD60
_text:00434C37                 cmp     eax, 1
_text:00434C3A                 jz      short loc_0_434C55 ; 傳送成功, ECX=120D51C
_text:00434C3C                 mov     ecx, esi
_text:00434C3E                 call    sub_0_508240
_text:00434C43                 pop     edi
_text:00434C44                 pop     esi
_text:00434C45                 pop     ebp
_text:00434C46                 mov     eax, 2
_text:00434C4B                 pop     ebx
_text:00434C4C                 add     esp, 0A8h
_text:00434C52                 retn    10h
_text:00434C55 ; ---------------------------------------------------------------------------
_text:00434C55
_text:00434C55 loc_0_434C55:                           ; CODE XREF: UserLogin+16Aj
_text:00434C55                 mov     ecx, esi        ; 傳送成功, ECX=120D51C
_text:00434C57                 mov     [esi+1BCh], ebp
_text:00434C5D                 call    sub_0_50B710    ; 從Socket讀1位元組
_text:00434C62                 mov     edi, eax
_text:00434C64                 cmp     edi, ebx        ; 返回值=0,則登入成功
_text:00434C66                 jz      short loc_0_434C88 ; ECX<-271BBBC, EnMD5
_text:00434C68                 cmp     edi, 0Ah
_text:00434C6B                 jz      short loc_0_434C79
_text:00434C6D                 cmp     edi, 0Bh
_text:00434C70                 jz      short loc_0_434C79
_text:00434C72                 mov     ecx, esi
_text:00434C74                 call    sub_0_508240
_text:00434C79
_text:00434C79 loc_0_434C79:                           ; CODE XREF: UserLogin+19Bj
_text:00434C79                                         ; UserLogin+1A0j
_text:00434C79                 mov     eax, edi
_text:00434C7B                 pop     edi
_text:00434C7C                 pop     esi
_text:00434C7D                 pop     ebp
_text:00434C7E                 pop     ebx
_text:00434C7F                 add     esp, 0A8h
_text:00434C85                 retn    10h
_text:00434C88 ; ---------------------------------------------------------------------------
_text:00434C88
_text:00434C88 loc_0_434C88:                           ; CODE XREF: UserLogin+196j
_text:00434C88                 lea     ecx, [esp+0B8h+var_8C] ; ECX<-271BBBC, EnMD5
_text:00434C8C                 push    1               ; len
_text:00434C8E                 push    ecx             ; buf
_text:00434C8F                 mov     ecx, esi
_text:00434C91                 mov     [esi+1ACh], ebx ; 清空Buf
_text:00434C97                 mov     [esi+1B0h], ebx
_text:00434C9D                 mov     [esi+1B4h], ebx
_text:00434CA3                 mov     [esi+1B8h], ebx
_text:00434CA9                 call    sub_0_50AE20    ; 接收資料並解密
_text:00434CAE                 lea     edx, [esi+1C0h]
_text:00434CB4                 push    2               ; len
_text:00434CB6                 push    edx             ; buf
_text:00434CB7                 mov     ecx, esi
_text:00434CB9                 call    sub_0_50AE20    ; 接收資料並解密
_text:00434CBE                 lea     eax, [esi+1C4h]
_text:00434CC4                 push    4               ; len
_text:00434CC6                 push    eax             ; buf
_text:00434CC7                 mov     ecx, esi
_text:00434CC9                 call    sub_0_50AE20    ; 接收資料並解密
_text:00434CCE                 cmp     [esp+0B8h+arg_C], ebx
_text:00434CD5                 jnz     short loc_0_434CEB
_text:00434CD7                 push    ebp             ; ArgList
_text:00434CD8                 push    offset aDLogin  ; "'%d': login"
_text:00434CDD                 push    ebx             ; __int16
_text:00434CDE                 push    offset stru_0_596558 ; lpCriticalSection
_text:00434CE3                 call    sub_0_4AA400
_text:00434CE8                 add     esp, 10h
_text:00434CEB
_text:00434CEB loc_0_434CEB:                           ; CODE XREF: UserLogin+205j
_text:00434CEB                 pop     edi
_text:00434CEC                 pop     esi
_text:00434CED                 pop     ebp
_text:00434CEE                 xor     eax, eax
_text:00434CF0                 pop     ebx
_text:00434CF1                 add     esp, 0A8h
_text:00434CF7                 retn    10h
_text:00434CFA ; ---------------------------------------------------------------------------
_text:00434CFA
_text:00434CFA loc_0_434CFA:                           ; CODE XREF: UserLogin+2Bj
_text:00434CFA                                         ; UserLogin+39j ...
_text:00434CFA                 pop     edi
_text:00434CFB                 pop     esi
_text:00434CFC                 pop     ebp
_text:00434CFD                 mov     eax, 3
_text:00434D02                 pop     ebx
_text:00434D03                 add     esp, 0A8h
_text:00434D09                 retn    10h
_text:00434D09 UserLogin       endp
_text:00434D09
_text:00434D09 ; ---------------------------------------------------------------------------
_text:00434D0C                 align 10h

根據分析整理出登入資料包的結構如下

#pragma pack(push,1)
struct MT4_LOGIN_tag
{
    char  First;         //除錯時此值一直為0
    char  Random;        //通過機器時間取的一個隨機數 
    char  UnKnow;        //0
    char  MD5Codes[16];     //密碼MD5運算後再變換一次的結果
    int   Login;            //使用者ID
    short  Version;         //客戶端版本
    short  Build;        //客戶端版本
    char   ClientType;      //客戶端型別
}
#pragma pack(pop)

對於要傳送的資料包, 整個資料包從第2位元組開始進行了一次變換, 在00434C24處呼叫子函式sub_0_433990進行處理, 相關分析如下

_text:00433990                 push    esi
_text:00433991                 mov     esi, ecx        ; Buf指標
_text:00433993                 xor     ecx, ecx
_text:00433995                 push    edi
_text:00433996                 test    esi, esi
_text:00433998                 mov     edi, edx        ; Buf的長度
_text:0043399A                 jz      short loc_0_4339C0
_text:0043399C                 xor     eax, eax
_text:0043399E                 test    edi, edi
_text:004339A0                 jle     short loc_0_4339C0
_text:004339A2
_text:004339A2 loc_0_4339A2:                           ; CODE XREF: sub_0_433990+2Ej
_text:004339A2                 mov     edx, eax
_text:004339A4                 and     edx, 0Fh
_text:004339A7                 mov     dl, ds:byte_0_56B734[edx*4] ; 一個常量MD5資料
_text:004339AE                 add     dl, cl          ; 加上前一位元組變換後的值
_text:004339B0                 mov     cl, [eax+esi]   ; 取當前位元組
_text:004339B3                 xor     cl, dl          ; 異或的記過即為變換的結果
_text:004339B5                 mov     [eax+esi], cl
_text:004339B8                 inc     eax
_text:004339B9                 cmp     eax, edi
_text:004339BB                 movsx   ecx, cl
_text:004339BE                 jl      short loc_0_4339A2
_text:004339C0
_text:004339C0 loc_0_4339C0:                           ; CODE XREF: sub_0_433990+Aj
_text:004339C0                                         ; sub_0_433990+10j
_text:004339C0                 pop     edi
_text:004339C1                 pop     esi
_text:004339C2                 retn

根據以上資訊既可以模擬程式去傳送登入資料包。

相關文章