欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
qq反匯編日志
剛開(kāi)始學(xué)習逆向,看著(zhù)表面上“毫無(wú)規律”的代碼,真的不知道如何下手。經(jīng)群里一位同志的推薦,看到了此文,看完后感覺(jué)思路上清晰了很多。我想這篇文章既然獲得了“看雪06年最佳逆向工程獎”自然尤其看點(diǎn),相信對于初學(xué)者來(lái)說(shuō)是很好的一篇參考文章

標 題: 【原創(chuàng )】qq反匯編日志1
作 者: freeGod
時(shí) 間: 2006-06-15,18:20
鏈 接: http://bbs.pediy.com/showthread.php?t=27458
2006年6月15日 9:30
oo,前兩天的反匯編記錄下來(lái)的東西都丟了(昨天重做系統時(shí),忘了),不過(guò)還好,丟的東西大部分都是我的曲折錯誤分析
現在從新開(kāi)始:(為寫(xiě)遠程暴力破解qq密碼程序而反匯編qq)
反匯編工具:OllyICE
現在開(kāi)始:
用OllyICE加載qq.exe,qq登錄對話(huà)框出現,隨便輸入密碼:123,運行,一個(gè)錯誤對話(huà)框出現,
錯誤
輸入密碼與上次成功登錄得密碼不一致,
是否到服務(wù)器驗證?

好,打開(kāi)OllyICE的模塊窗口,然后找到user32模塊,打開(kāi)右鍵菜單選中查看名稱(chēng),OllyICE的名稱(chēng)窗口出現了,這里的函數都是
User32模塊中的,好,找到MessageBoxA,打開(kāi)右鍵菜單選中反匯編窗口中跟隨,這樣就到了MessageBoxA函數的入口點(diǎn),按f2鍵設下
端點(diǎn),設好后點(diǎn)剛才qq跳出來(lái)的錯誤對話(huà)框上的否,qq用戶(hù)登錄又出現了,再輸入123
OllyICE在我們剛才設置的MessageBoxA函數的入口點(diǎn)停了下來(lái),察看堆棧窗口

0012FC2C   60B5C8E7  /CALL 到 MessageBoxA 來(lái)自 MFC42.60B5C8E1

-

說(shuō)明調用是MFC42庫中的60b5c8e1處的指令的前一條指令調用了MessageBoxA,在CALL 到 MessageBoxA 來(lái)自 MFC42.60B5C8E1上
右鍵,打開(kāi)右鍵菜單,選中反匯編窗口跟隨,就到mfc42地址空間的60b5c8e7指令位置(不同的電腦,可能值不一樣),上一條指令
就是調用MessageBoxA函數的,如下所示

60B5C8DC  |.  FF7424 10     push    dword ptr [esp+10]               ; |Text
60B5C8E0  |.  51            push    ecx                              ; |hOwner
60B5C8E1  |.  FF15 D0B5B960 call    [<&USER32.MessageBoxA>]          ; \MessageBoxA
60B5C8E7  |.  5E            pop     esi
60B5C8E8  |.  C2 0C00       retn    0C

在 60b5c8e7 pop esi上設置端點(diǎn),然后點(diǎn)運行,剛才的那個(gè)錯誤對話(huà)框又出現了,點(diǎn)否,好,現在程序停在了我們剛才設置端點(diǎn)的位
置605c8e7處,現在在MFC42地址空間中,不管它,我們想到的位置是qq空間,按兩下f8鍵,到了 00415c35 cmp eax,6 指令處,看一
下OllyICE的標題欄 OllyICE - QQ.exe -[cpu -主線(xiàn)程,模塊 - qq]
好了這就是我們的目的地。

反匯編就從這里開(kāi)始,第一個(gè)分析的函數就是:包含 指令地址00415c35 的函數
第一步:找出 包含指令地址 00415c35 的 函數入口點(diǎn)
        向上滾動(dòng)反匯編窗口,找到00415b55 地址
  00415B52  \.  C2 0400       retn    4
  00415B55  /$  B8 5CD24C00   mov     eax, 004CD25C
  00415B5A  |.  E8 41A10500   call    0046FCA0
  00415B5F  |.  83EC 48       sub     esp, 48

  OllyICE 分析出這個(gè)是函數的入口點(diǎn),因為上面緊跟的是retn指令,不過(guò)一般的函數入口處:應該是
  push  ebp
  mov  ebp,esp
  才對,如果是羅函數的話(huà),經(jīng)過(guò)優(yōu)化編譯的話(huà)就不是這個(gè)樣子了,我們先在反匯編的是qq,qq的軟件工程師水平應該是可以
  的,有可能經(jīng)過(guò)特殊處理,

  004CD25C=004CD25C
  eax=0012FCBC
  本地調用來(lái)自 00414FE8, 00416FEE
  這個(gè)交叉引用說(shuō)明,的確是函數的入口點(diǎn)

  這樣函數入口點(diǎn)就確定了:004b5b55
第二步:確定函數結束地址,按OllyICE 的提示 結束地址應為:00415c9b retn 14,一個(gè)函數有可能有多個(gè)出口
        我們來(lái)做進(jìn)一步的鑒定,看看從004b5b55 到 00415c9b 之間的指令有無(wú)交叉引用到 00415c9b 以后的指令
  答:沒(méi)有,因此 00415c9b 即為函數的結束地址,至此我們確定了函數的入口點(diǎn)和結束地址
  004b5b55--00415c9b
現在我們開(kāi)始還原 函數 qq004b55 的源代碼

第三步:確定參數個(gè)數和參數類(lèi)型
  找到調用 004b5b55 函數 指令 :00414fe8 ------------------------------------
                                                                                  |
00414FD6  |.  C645 FC 05    mov     byte ptr [ebp-4], 5                           |
00414FDA  |.  E8 A1A60500   call    <jmp.&MFC42.#535_CString::CString>            |
00414FDF  |.  FF75 EC       push    dword ptr [ebp-14]                            |
00414FE2  |.  8BCB          mov     ecx, ebx                                      |
00414FE4  |.  C645 FC 05    mov     byte ptr [ebp-4], 5                           |
00414FE8  |.  E8 680B0000   call    00415B55      ---------------------------------                   
00414FED  |.  FFD6          call    esi  

  00414FE2  |.  8BCB          mov     ecx, ebx --- ecx 應該是個(gè)寄存器參數,要不這條指令就是個(gè)垃圾指令
  函數004b5b55 可能有一個(gè)寄存器參數,說(shuō)可能,是因為編譯器生成的垃圾指令到處可見(jiàn),要對ecx進(jìn)一步鑒定,要
  分析004b5b55 函數的代碼
00415B55  /$  B8 5CD24C00   mov     eax, 004CD25C
00415B5A  |.  E8 41A10500   call    0046FCA0
00415B5F  |.  83EC 48       sub     esp, 48
00415B62  |.  53            push    ebx
00415B63  |.  56            push    esi
00415B64  |.  33DB          xor     ebx, ebx
00415B66  |.  895D FC       mov     [ebp-4], ebx
00415B69  |.  895D F0       mov     [ebp-10], ebx
00415B6C  |.  8B81 84000000 mov     eax, [ecx+84]
  在函數的開(kāi)始處,調用了一個(gè)函數 0046fca0,察看一下它的代碼,看看和ecx有染沒(méi)有
0046FCA0  /$  6A FF         push    -1
0046FCA2  |.  50            push    eax
0046FCA3  |.  64:A1 0000000>mov     eax, fs:[0]
0046FCA9  |.  50            push    eax
0046FCAA  |.  8B4424 0C     mov     eax, [esp+C]
0046FCAE  |.  64:8925 00000>mov     fs:[0], esp
0046FCB5  |.  896C24 0C     mov     [esp+C], ebp
0046FCB9  |.  8D6C24 0C     lea     ebp, [esp+C]
0046FCBD  |.  50            push    eax
0046FCBE  \.  C3            retn
  哈哈,這個(gè)函數挺簡(jiǎn)練的,和ecx無(wú)關(guān),這就好,再看看00415b6c地址 以上的指令都與ecx無(wú)關(guān),而在00415b6c處引用了
  ecx,因此斷定ecx就是一個(gè)寄存器參數,不錯,good
  下面來(lái)看一下004b5b55 函數 有多少個(gè)堆棧參數
  從函數結束地址 00415C9B  \.  C2 1400       retn    14
  可知 堆棧參數個(gè)數為 14h / 4 = 5
  到此我們確定了參數的個(gè)數:一個(gè)寄存器參數 + 5 個(gè)堆棧參數 = 6(說(shuō)明函數采用的是fastcall調用方式)
  給他們編號分別為:arg1,arg2,arg3,arg4,arg5,arg6
  
  下面我們來(lái)確定參數類(lèi)型
  在指令中識別參數
  函數004b5b55 每有標準的函數頭 即 push ebp ; mov ebp,esp,如果是采用優(yōu)化編譯的話(huà),參數應該用esp寄存器來(lái)尋址
  可在函數過(guò)程中只在分配局部變量時(shí),用了一次esp
00415B5F  |.  83EC 48       sub     esp, 48
  其他的地方都沒(méi)有,令人奇怪的是到處都是用ebp寄存器尋址的,對了,函數入口點(diǎn),調用了一個(gè)函數:0046fca0
  看看它都實(shí)現了什么功能
  
0046FCA0  /$  6A FF         push    -1
執行指令后堆棧數據
相對esp的地址    數據
esp      -1
esp+4      ret addr
0046FCA2  |.  50            push    eax
執行指令后堆棧數據
相對esp的地址    數據
esp      eax (通過(guò)寄存器eax傳遞過(guò)來(lái)的參數進(jìn)棧)
esp+4      -1
esp+8      ret addr
0046FCA3  |.  64:A1 0000000>mov     eax, fs:[0]    ;eax 指向 seh (結構化異常處理)
0046FCA9  |.  50            push    eax
執行指令后堆棧數據
相對esp的地址    數據
esp      eax (seh 指針)
esp+4      eax (通過(guò)寄存器eax傳遞過(guò)來(lái)的參數進(jìn)棧)
esp+8      -1
esp+c      ret addr
0046FCAA  |.  8B4424 0C     mov     eax, [esp+C]  ;把ret addr 傳遞給eax
執行指令后堆棧數據
相對esp的地址    數據
esp      eax (seh 指針)
esp+4      eax (通過(guò)寄存器eax傳遞過(guò)來(lái)的參數進(jìn)棧)
esp+8      -1
esp+c      ret addr
0046FCAE  |.  64:8925 00000>mov     fs:[0], esp    ;此時(shí)esp指向一個(gè) EXCEPTION_REGISTRATION 結構
              ;表明同過(guò)寄存器eax傳遞給函數的是異?;卣{函數地址
              ;-1 則是seh 的附加數據
執行指令后堆棧數據
相對esp的地址    數據
esp      eax (seh 指針)<-------------------------------fs:[0]
esp+4      eax (通過(guò)寄存器eax傳遞過(guò)來(lái)的參數進(jìn)棧)
esp+8      -1
esp+c      ret addr

0046FCB5  |.  896C24 0C     mov     [esp+C], ebp  ;保存ebp 到 原來(lái) ret addr 所占堆棧位置
執行指令后堆棧數據
相對esp的地址    數據
esp      eax (seh 指針)<-------------------------------fs:[0]
esp+4      eax (通過(guò)寄存器eax傳遞過(guò)來(lái)的參數進(jìn)棧)
esp+8      -1
esp+c      ebp  ----- 注意發(fā)生變化了

0046FCB9  |.  8D6C24 0C     lea     ebp, [esp+C]  ;ebp指向 保存ebp的位置(也即原來(lái) ret addr 的位置)
執行指令后堆棧數據
相對esp的地址    數據
esp      eax (seh 指針)<-------------------------------fs:[0]
esp+4      eax (通過(guò)寄存器eax傳遞過(guò)來(lái)的參數進(jìn)棧)
esp+8      -1
esp+c      ebp  ----- 注意發(fā)生變化了<------------------------ ebp
0046FCBD  |.  50            push    eax
執行指令后堆棧數據
相對ebp的地址    相對esp的地址    數據
ebp-10      esp      eax(函數的返回地址)
ebp-c      esp+4      eax (seh 指針)<-------------------------------fs:[0]
ebp-8      esp+8      eax (通過(guò)寄存器eax傳遞過(guò)來(lái)的參數進(jìn)棧)
ebp-4      esp+c      -1
ebp      esp+10      ebp  ----- 注意發(fā)生變化了<------------------------ ebp
0046FCBE  \.  C3            retn
執行指令后堆棧數據
相對ebp的地址    相對esp的地址    數據
ebp-c      esp      eax (seh 指針)<-------------------------------fs:[0]
ebp-8      esp+4      eax (通過(guò)寄存器eax傳遞過(guò)來(lái)的參數進(jìn)棧)
ebp-4      esp+8      -1
ebp      esp+c      ebp  ----- 注意發(fā)生變化了<------------------------ ebp

因為 函數0046fca0沒(méi)有堆棧參數,所以 ebp+4 指向的是它的父函數即 004b5b55 結束時(shí)要返回的地址

相對ebp的地址    相對esp的地址    數據
ebp-c      esp      eax (seh 指針)<-------------------------------fs:[0]
ebp-8      esp+4      eax (通過(guò)寄存器eax傳遞過(guò)來(lái)的參數進(jìn)棧)
ebp-4      esp+8      -1
ebp      esp+c      ebp  ----- 注意發(fā)生變化了<------------------------ ebp
ebp +4      esp+10      004b5b55函數 結束時(shí)要返回的地址

綜上所述:0046fca0 實(shí)現的功能為:《1》注冊異?;卣{函數
         《2》實(shí)現了和 push  ebp
                 mov  ebp,esp
          查不多的功能,調用0046fca0函數的函數的第一個(gè)堆棧參數地址為 ebp +8
          這和push ebp ;move ebp,esp 是一樣的,但是局部變量的尋址就不一樣了
          調用0046fca0 函數的函數局部變量是從ebp-d 開(kāi)始的,而不是從ebp-4開(kāi)始的
          搞定……^_^
現在我們就可以很輕松的識別出參數了,開(kāi)始吧
識別參數類(lèi)型
首先我用32位匯編語(yǔ)言來(lái)實(shí)現00415b55,我給他起個(gè)名字叫 _lastStep 吧,我把寄存器傳參也改成堆棧方式

_LastStep  proc  _arg1,_arg2,_arg3,_arg4,_arg5,_arg6
    mov  eax,004cd25c
    call  0046fca0
    sub  esp,48h
    push  ebx
    push  esi
    xor  ebx,ebx
    mov  [ebp-4],ebx  ;[ebp-4] 是seh附加數據的地址,原來(lái)值為-1,現在要把它置零了
    mov  @dwVar1,ebx
    mov  ecx,_arg1
    mov  eax,[ecx+84]  ;可知_arg1 是一個(gè)指針
    lea  edx,@dwVar1
    push  edx
    push  004e7460
    mov  ecx,[eax]
    push  eax
    mov  byte ptr[ebp-4],1  ;[ebp-4] 是seh附加數據的地址
    call  [ecx+1c]    ;表明_arg1 是一個(gè)函數指針的指針的指針
    test  eax,eax
    jnz  lable1
    mov  eax,@dwVar1
    lea  edx,@dwVar2
    push  edx
    push  004e8940    ;ascii "ewh.db"
    mov  ecx,[eax]
    push  eax
    call  [ecx+14]
    test  eax,eax
    je  label2
  lable1:
    mov  eax,_arg4    ;可知_arg4 是一個(gè)int*
    mov  dword ptr[eax],2
    jmp  lable3
  lable2:
    mov  eax,_arg3
    push  edi
    mov  edx,@dwVar1
    push  1
    mov  ecx,[eax-8]
    pop  esi
    mov  edi,[edx]
    push  esi
    push  eax
    push  ecx
    push  ebx
    push  dword ptr _arg2
    push  edx
    call  [edi+1c]
    test  eax,eax
    pop  edi
    je  lable4  
    cmp  _arg6,esi
    je  lable5
    mov  eax,_arg4
    mov  [eax],ebx  ;可知_arg4是個(gè)指針
    jmp  lable3
  lable5:
    lea  ecx,_arg6
    call  CString::CString
    lea  ecx,_arg2
    mov  byte ptr [ebp-4],2
    call  CString::CString
    mov  esi,BasicCtrDll.BasicLoadStr
    lea  eax,_arg6
    push  281
    push  eax
    mov  byte prt[ebp-4],3
    call  esi
    lea  eax,_arg2
    push  28d
    push  eax
    call  esi
    add  esp,10
    lea  ecx,[ebp-54]  ;ebp-54 指向一個(gè)結構
    call  CWNd::CWnd
    push  114
    lea  ecx,[ebp-54]
    push  dword ptr _arg2
    mov  byte prt[ebp-4],4
    push  dword ptr _arg6
    call  CWnd::MessageBoxA
    cmp  eax,6
    mov  eax,_arg4
    jnz  Lable6
    mov  dword prt[eax],2
    jmp  lable7
  lable6:
    mov  [eax],ebx
  lable7:
    lea  ecx,[ebp-54]
    mov  byte ptr[ebp-4],3
    call  CWnd::~Cwnd
    lea  ecx,_arg2
    mov  byte ptr[ebp-4],2
    call  CString::~CString
    lea  ecx,_arg6
    mov  byte ptr[ebp-4],1
    call  CString::~Cstring
    jmp  lable3
  lable4:
    mov  eax,_arg4
    mov  [eax],esi
  lable3:
    mov  eax,@dwVar1
    mov  [ebp-4],bl
    cmp  eax,ebx
    je  lable8
    mov  ecx,[eax]
    push  eax
    call  [ecx+8]
  lable8:
    or  dwword ptr[ebp-4],0ffffffffh
    lea  ecx,_arg3
    call  CString::~CString
    mov  ecx,[ebp-c]  ; pre seh handler 指針
    pop  esi
    pop  ebx
    mov  fs:[0],ecx
    leave
    retn  14
_LastSetp  enp
 2006-06-17 20:00

識別函數中的參數和局部變量
經(jīng)過(guò)上面的分析我們已經(jīng)知道在qq00405b55函數中參數和局部變量都是用ebp寄存器來(lái)表示的,現在我們來(lái)找出函數中的參數,和局部變量
首先:我們把函數中使用ebp寄存器尋找的變量找出來(lái),刪除重復的并按從低地址到高地址排序,得到如下結果:
ebp-54h
ebp-14h
ebp-10h
ebp-ch
ebp-4h
ebp+8h
ebp+ch
ebp+10h
ebp+18h
我們知道堆棧參數是:從ebp+8開(kāi)始向高地址方向的,局部變量是從ebp-d開(kāi)始向低地址方向的
現在給他們分組:
堆棧參數有:ebp+8h,ebp+ch,ebp+10h,ebp+18h,堆棧參數名我們規定從低地址開(kāi)始編號_arg1,_arg2,_arg3,....,所以就有 :
ebp+8h = _arg1
ebp+ch = _arg2
ebp+10h = _arg3
ebp+18h = _arg4 少了一個(gè) 怎么沒(méi)有ebp+14h 呢,_arg3 占了8個(gè)字節的地盤(pán)???先不管它,呆會(huì )分析參數類(lèi)型的時(shí)候在看
局部變量有:ebp-10h,ebp-14h,ebp-54h,局部變量我們規定從高地址開(kāi)始編號@var1,@var2,@var3,.....所以有:
ebp-10h = @var1  因為局部變量是從ebp-d開(kāi)始的所以可知這個(gè)局部變量的大小為(10h-d)+1 4 byte
ebp-14h = @var2 同理:這個(gè)緊挨著(zhù)@var1 可知他也為(14h-11h)+1 4 byte 
ebp-54h = @var3 這是最后一個(gè)變量,它的大小為:(54h-15h)+1 = 40h byte
還有幾個(gè)孤兒,沒(méi)有組的,他們是ebp-ch,和ebp-4h,日至1中已經(jīng)知道他們分別是seh指針和seh的附加數據
第二步:我們將參數名、局部變量名替換到反匯編代碼中去,還有跳轉地址我們也用相應的標號替換掉就得到了

  mov     eax, 004CD25C
  call    0046FCA0
  sub     esp, 48
  push    ebx
  push    esi
  xor     ebx, ebx
  mov     [ebp-4], ebx
  mov     @var1, ebx
  mov     eax, [ecx+84]
  lea     edx, @var1
  push    edx
  push    004E7460
  mov     ecx, [eax]
  push    eax
  mov     byte ptr [ebp-4], 1
  call    [ecx+1C]
  test    eax, eax
  jnz     lable1    ;short 00415B9F
  mov     eax, @var1
  lea     edx, @var2
  push    edx
  push    004E8940
  mov     ecx, [eax]
  push    eax
  call    [ecx+14]
  test    eax, eax
  je      lable2    ;short 00415BAD
lable1:
  mov     eax, _arg3
  mov     dword ptr [eax], 2
  jmp     lable3    ;00415C72
lable2:
  mov     eax, _arg2
  push    edi
  mov     edx, @var1
  push    1
  mov     ecx, [eax-8]
  pop     esi
  mov     edi, [edx]
  push    esi
  push    eax
  push    ecx
  push    ebx
  push    dword ptr _arg1
  push    edx
  call    [edi+1C]
  test    eax, eax
  pop     edi
  je      lable4    ;00415C6D
  cmp     _arg4, esi
  je      lable5    ;short 00415BDF
  mov     eax, _arg3
  mov     [eax], ebx
  jmp     lable3    ;00415C72
lable5:
  lea     ecx, _arg4
  call    <jmp.&MFC42.#540_CString::CStrin>
  lea     ecx, _arg1
  mov     byte ptr [ebp-4], 2
  call    <jmp.&MFC42.#540_CString::CStrin>
  mov     esi, [<&BasicCtrlDll.BasicLoadSt>;  BasicCtr.BasicLoadStr
  lea     eax, _arg4
  push    281
  push    eax
  mov     byte ptr [ebp-4], 3
  call    esi                              ;  <&BasicCtrlDll.BasicLoadStr>
  lea     eax, _arg1
  push    28D
  push    eax
  call    esi
  add     esp, 10
  lea     ecx, @var3
  call    <jmp.&MFC42.#567_CWnd::CWnd>
  push    114
  lea     ecx, @var3
  push    dword ptr _arg1
  mov     byte ptr [ebp-4], 4
  push    dword ptr _arg4
  call    <jmp.&MFC42.#4224_CWnd::MessageB>
  cmp     eax, 6
  mov     eax, _arg3
  jnz     label6        ;short 00415C45
  mov     dword ptr [eax], 2               ;  [eax]可能保存的是某個(gè)標志,2代表本地登陸失敗,到服務(wù)器上去驗證去
  jmp     lable7        ;short 00415C47
lable6:
  mov     [eax], ebx
lable7:
  lea     ecx, @var3
  mov     byte ptr [ebp-4], 3              ;  [12fcac]
  call    <jmp.&MFC42.#818_CWnd::~CWnd>
  lea     ecx, _arg1
  mov     byte ptr [ebp-4], 2
  call    <jmp.&MFC42.#800_CString::~CStri>
  lea     ecx, _arg4
  mov     byte ptr [ebp-4], 1
  call    <jmp.&MFC42.#800_CString::~CStri>
  jmp     lable3        ;short 00415C72
lable4:
  mov     eax, _arg3
  mov     [eax], esi
lable3:
  mov     eax, _arg3
  mov     [ebp-4], bl
  cmp     eax, ebx
  je      lable8        ;short 00415C82
  mov     ecx, [eax]
  push    eax
  call    [ecx+8]
lable8:
  or      dword ptr [ebp-4], FFFFFFFF
  lea     ecx, _arg2
  call    <jmp.&MFC42.#800_CString::~CStri>
  mov     ecx, [ebp-C]                     ;  seh 指針
  pop     esi
  pop     ebx
  mov     fs:[0], ecx
  leave
  retn    14                               ;  父函數傳遞了5個(gè)參數

靠,終于整完了

下一步:去掉編譯器自己添加的或與函數功能無(wú)關(guān)的,異常處理東東
刪掉
mov     eax, 004CD25C
  call    0046FCA0
  注冊異常處理函數,打開(kāi)堆棧頁(yè)面
  sub     esp, 48    ;分配局部變量空間
刪掉
  mov     ecx, [ebp-C]                     ;  seh 指針
刪掉
  mov     fs:[0], ecx
  leave
  retn    14  
  將注冊的異常處理函數刪除掉,堆棧平衡

剩下的就是裸函數了

  push    ebx
  push    esi
  xor     ebx, ebx
  mov     [ebp-4], ebx
  mov     @var1, ebx
  mov     eax, [ecx+84]
  lea     edx, @var1
  push    edx
  push    004E7460
  mov     ecx, [eax]
  push    eax
  mov     byte ptr [ebp-4], 1
  call    [ecx+1C]
  test    eax, eax
  jnz     lable1
  mov     eax, @var1
  lea     edx, @var2
  push    edx
  push    004E8940
  mov     ecx, [eax]
  push    eax
  call    [ecx+14]
  test    eax, eax
  je      lable2
lable1:
  mov     eax, _arg3
  mov     dword ptr [eax], 2
  jmp     lable3
lable2:
  mov     eax, _arg2
  push    edi
  mov     edx, @var1
  push    1
  mov     ecx, [eax-8]
  pop     esi
  mov     edi, [edx]
  push    esi
  push    eax
  push    ecx
  push    ebx
  push    dword ptr _arg1
  push    edx
  call    [edi+1C]
  test    eax, eax
  pop     edi
  je      lable4
  cmp     _arg4, esi
  je      lable5
  mov     eax, _arg3
  mov     [eax], ebx
  jmp     lable3
lable5:
  lea     ecx, _arg4
  call    <jmp.&MFC42.#540_CString::CStrin>
  lea     ecx, _arg1
  mov     byte ptr [ebp-4], 2
  call    <jmp.&MFC42.#540_CString::CStrin>
  mov     esi, [<&BasicCtrlDll.BasicLoadSt>;  BasicCtr.BasicLoadStr
  lea     eax, _arg4
  push    281
  push    eax
  mov     byte ptr [ebp-4], 3
  call    esi                              ;  <&BasicCtrlDll.BasicLoadStr>
  lea     eax, _arg1
  push    28D
  push    eax
  call    esi
  add     esp, 10
  lea     ecx, @var3
  call    <jmp.&MFC42.#567_CWnd::CWnd>
  push    114
  lea     ecx, @var3
  push    dword ptr _arg1
  mov     byte ptr [ebp-4], 4
  push    dword ptr _arg4
  call    <jmp.&MFC42.#4224_CWnd::MessageB>
  cmp     eax, 6
  mov     eax, _arg3
  jnz     label6
  mov     dword ptr [eax], 2
  jmp     lable7
lable6:
  mov     [eax], ebx
lable7:
  lea     ecx, @var3
  mov     byte ptr [ebp-4], 3
  call    <jmp.&MFC42.#818_CWnd::~CWnd>
  lea     ecx, _arg1
  mov     byte ptr [ebp-4], 2
  call    <jmp.&MFC42.#800_CString::~CStri>
  lea     ecx, _arg4
  mov     byte ptr [ebp-4], 1
  call    <jmp.&MFC42.#800_CString::~CStri>
  jmp     lable3
lable4:
  mov     eax, _arg3
  mov     [eax], esi
lable3:
  mov     eax, _arg3
  mov     [ebp-4], bl
  cmp     eax, ebx
  je      lable8
  mov     ecx, [eax]
  push    eax
  call    [ecx+8]
lable8:
  or      dword ptr [ebp-4], FFFFFFFF
  lea     ecx, _arg2
  call    <jmp.&MFC42.#800_CString::~CStri>
  pop     esi
  pop     ebx

讓函數光著(zhù)身子不好,現在給它穿上衣服吧
我先給它穿上win32asm 這套衣服,以后再給她穿c++這套衣服,給這個(gè)過(guò)程起個(gè)名字:叫 _TempName 吧,現在還不知道她是做什么用的,知道了,再換
寄存器參數我用 _regArg1,_regArg2,...表示

_TempName  Proc  _regArg1,_arg1,_arg2,_arg3,_arg?,_arg4  (因為不知道倒數第二個(gè)為什么沒(méi)有在函數中引用過(guò),所以先用?表示)
  push    ebx
  push    esi
  xor     ebx, ebx
  mov     [ebp-4], ebx
  mov     @var1, ebx
  mov     eax, [ecx+84]
  lea     edx, @var1
  push    edx
  push    004E7460
  mov     ecx, [eax]
  push    eax
  mov     byte ptr [ebp-4], 1
  call    [ecx+1C]
  test    eax, eax
  jnz     lable1
  mov     eax, @var1
  lea     edx, @var2
  push    edx
  push    004E8940
  mov     ecx, [eax]
  push    eax
  call    [ecx+14]
  test    eax, eax
  je      lable2
lable1:
  mov     eax, _arg3
  mov     dword ptr [eax], 2
  jmp     lable3
lable2:
  mov     eax, _arg2
  push    edi
  mov     edx, @var1
  push    1
  mov     ecx, [eax-8]
  pop     esi
  mov     edi, [edx]
  push    esi
  push    eax
  push    ecx
  push    ebx
  push    dword ptr _arg1
  push    edx
  call    [edi+1C]
  test    eax, eax
  pop     edi
  je      lable4
  cmp     _arg4, esi
  je      lable5
  mov     eax, _arg3
  mov     [eax], ebx
  jmp     lable3
lable5:
  lea     ecx, _arg4
  call    <jmp.&MFC42.#540_CString::CStrin>
  lea     ecx, _arg1
  mov     byte ptr [ebp-4], 2
  call    <jmp.&MFC42.#540_CString::CStrin>
  mov     esi, [<&BasicCtrlDll.BasicLoadSt>;  BasicCtr.BasicLoadStr
  lea     eax, _arg4
  push    281
  push    eax
  mov     byte ptr [ebp-4], 3
  call    esi                              ;  <&BasicCtrlDll.BasicLoadStr>
  lea     eax, _arg1
  push    28D
  push    eax
  call    esi
  add     esp, 10
  lea     ecx, @var3
  call    <jmp.&MFC42.#567_CWnd::CWnd>
  push    114
  lea     ecx, @var3
  push    dword ptr _arg1
  mov     byte ptr [ebp-4], 4
  push    dword ptr _arg4
  call    <jmp.&MFC42.#4224_CWnd::MessageB>
  cmp     eax, 6
  mov     eax, _arg3
  jnz     label6
  mov     dword ptr [eax], 2
  jmp     lable7
lable6:
  mov     [eax], ebx
lable7:
  lea     ecx, @var3
  mov     byte ptr [ebp-4], 3
  call    <jmp.&MFC42.#818_CWnd::~CWnd>
  lea     ecx, _arg1
  mov     byte ptr [ebp-4], 2
  call    <jmp.&MFC42.#800_CString::~CStri>
  lea     ecx, _arg4
  mov     byte ptr [ebp-4], 1
  call    <jmp.&MFC42.#800_CString::~CStri>
  jmp     lable3
lable4:
  mov     eax, _arg3
  mov     [eax], esi
lable3:
  mov     eax, _arg3
  mov     [ebp-4], bl
  cmp     eax, ebx
  je      lable8
  mov     ecx, [eax]
  push    eax
  call    [ecx+8]
lable8:
  or      dword ptr [ebp-4], FFFFFFFF
  lea     ecx, _arg2
  call    <jmp.&MFC42.#800_CString::~CStri>
  pop     esi
  pop     ebx
  ret
_TempName  endp

下一步分析qq00415b55 調用的函數

第一個(gè)  call    [ecx+1C] oo 是個(gè)間接調用指令,那來(lái)動(dòng)態(tài)跟蹤以下調用的是什么?00410ee2

00410EE2   .  B8 CCC84C00   mov     eax, 004CC8CC
00410EE7   .  E8 B4ED0500   call    0046FCA0
00410EEC   .  51            push    ecx
00410EED   .  51            push    ecx
00410EEE   .  8B45 08       mov     eax, [ebp+8]
00410EF1   .  56            push    esi
00410EF2   .  8D4D EC       lea     ecx, [ebp-14]
00410EF5   .  FF70 D8       push    dword ptr [eax-28]
00410EF8   .  8D70 BC       lea     esi, [eax-44]
00410EFB   .  E8 94E80500   call    <jmp.&MFC42.#6467_AFX_MAINTAIN_S>
00410F00   .  FF75 10       push    dword ptr [ebp+10]               ; /Arg2
00410F03   .  8365 FC 00    and     dword ptr [ebp-4], 0             ; |
00410F07   .  8BCE          mov     ecx, esi                         ; |
00410F09   .  FF75 0C       push    dword ptr [ebp+C]                ; |Arg1
00410F0C   .  E8 71040000   call    00411382                         ; \QQ.00411382
00410F11   .  8B4D F0       mov     ecx, [ebp-10]
00410F14   .  8B55 EC       mov     edx, [ebp-14]
00410F17   .  834D FC FF    or      dword ptr [ebp-4], FFFFFFFF
00410F1B   .  5E            pop     esi
00410F1C   .  8951 04       mov     [ecx+4], edx
00410F1F   .  8B4D F4       mov     ecx, [ebp-C]
00410F22   .  64:890D 00000>mov     fs:[0], ecx
00410F29   .  C9            leave
00410F2A   .  C2 0C00       retn    0C

分析過(guò)程和 分析qq00415b55 一樣
經(jīng)分析可知 函數沒(méi)有寄存器參數,c/4=3個(gè)堆棧參數,這里要注意的是
00410EEC   .  51            push    ecx
00410EED   .  51            push    ecx
這兩條指令是分配局部變量空間的,因為函數中有兩個(gè)局部變量,這是編譯器快速分配局部變量而使得花招
00410ee2 的函數原型為:

00410ee2  proto  _arg1,_arg2,_arg3

下一個(gè)qq00415b55調用的函數是 call [ecx+14] = 0044c62b
0044C62B   .  B8 84424D00   mov     eax, 004D4284
0044C630   .  E8 6B360200   call    0046FCA0
0044C635   .  51            push    ecx
0044C636   .  51            push    ecx
0044C637   .  8B45 08       mov     eax, [ebp+8]
0044C63A   .  56            push    esi
0044C63B   .  8D4D EC       lea     ecx, [ebp-14]
0044C63E   .  FF70 FC       push    dword ptr [eax-4]
0044C641   .  8D70 E0       lea     esi, [eax-20]
0044C644   .  E8 4B310200   call    <jmp.&MFC42.#6467_AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2>
0044C649   .  FF75 10       push    dword ptr [ebp+10]
0044C64C   .  8B06          mov     eax, [esi]
0044C64E   .  8365 FC 00    and     dword ptr [ebp-4], 0
0044C652   .  FF75 0C       push    dword ptr [ebp+C]
0044C655   .  56            push    esi
0044C656   .  FF50 64       call    [eax+64]
0044C659   .  8B4D F0       mov     ecx, [ebp-10]
0044C65C   .  8B55 EC       mov     edx, [ebp-14]
0044C65F   .  834D FC FF    or      dword ptr [ebp-4], FFFFFFFF
0044C663   .  5E            pop     esi
0044C664   .  8951 04       mov     [ecx+4], edx
0044C667   .  8B4D F4       mov     ecx, [ebp-C]
0044C66A   .  64:890D 00000>mov     fs:[0], ecx
0044C671   .  C9            leave
0044C672   .  C2 0C00       retn    0C
看起來(lái)好像和上個(gè)函數長(cháng)得很像

函數原型為:

0044c62b  proto  _arg1,_arg2,_arg3

next function: 0044c6c5
函數原型為:
0044c6c5  proto  _arg1,_arg2,_arg3,_arg4,_arg5,_arg6
下一個(gè)函數是 BasicCtr.BasicLoadStr
60092057 >/$  55            push    ebp
60092058  |.  8BEC          mov     ebp, esp
6009205A  |.  56            push    esi
6009205B  |.  57            push    edi
6009205C  |.  E8 5FCD0000   call    <jmp.&MFC42.#1168_AfxGetModuleState>
60092061  |.  8B70 0C       mov     esi, [eax+C]
60092064  |.  8B3D BC8B0B60 mov     edi, [600B8BBC]                                                 ;  BasicCtr.60090000
6009206A  |.  E8 51CD0000   call    <jmp.&MFC42.#1168_AfxGetModuleState>
6009206F  |.  FF75 0C       push    dword ptr [ebp+C]
60092072  |.  8B4D 08       mov     ecx, [ebp+8]
60092075  |.  8978 0C       mov     [eax+C], edi
60092078  |.  E8 91CD0000   call    <jmp.&MFC42.#4160_CString::LoadStringA>
6009207D  |.  E8 3ECD0000   call    <jmp.&MFC42.#1168_AfxGetModuleState>
60092082  |.  8970 0C       mov     [eax+C], esi
60092085  |.  5F            pop     edi
60092086  |.  5E            pop     esi
60092087  |.  5D            pop     ebp
60092088  \.  C3            retn

可算見(jiàn)到一個(gè)正常函數,函數有兩個(gè)堆棧參數參數,沒(méi)有寄存器參數,這個(gè)函數調用方式屬于_cdel方式,平很堆棧交給了
qq00415b55,qq00415b55調用完這個(gè)函數后并沒(méi)有做平衡堆棧,而是在第二次調用完這個(gè)函數后一起做了堆棧平衡,這可能是
優(yōu)化編譯的結果,這樣節省一條指令
我們從basicCtr.BasicLoadStr中也可以找出參數,[ebp+8],[ebp+c]這兩個(gè)

在qq00415b55中平衡堆棧代碼
00415C06  |.  FFD6          call    esi                                                             ;  BasicCtr.BasicLoadStr; <&BasicCtrlDll.BasicLoadStr>
00415C08  |.  8D45 08       lea     eax, [ebp+8]                                                    ;  _arg2
00415C0B  |.  68 8D020000   push    28D
00415C10  |.  50            push    eax
00415C11  |.  FFD6          call    esi
00415C13  |.  83C4 10       add     esp, 10 ---------------------平衡了兩次調用,一個(gè)函數的參數個(gè)數=10h/2/4=2個(gè)

所以這個(gè)函數的原型應為:
BasicCtr.BasicLoadStr  proto  _arg1,_arg2

下一個(gè),也是qq00415b55調用qq自定義函數中的最后一個(gè) 0044cf97 函數只有一個(gè)堆棧參數,沒(méi)有寄存器參數,函數原型為:
0044cf97  proc  _arg1

經(jīng)過(guò)上面的分析,qq00415b55 的win32asm 源代碼應為:
BasicCtr.BasicLoadStr  proto  _arg1,_arg2
0044cf97  proto  _arg1

_TempName  Proc  _regArg1,_arg1,_arg2,_arg3,_arg?,_arg4  (因為不知道倒數第二個(gè)為什么沒(méi)有在函數中引用過(guò),所以先用?表示)
  local  @dwVar1,@dwVar2
  local  @wnd:CWnd  (這個(gè)以后再解釋)
  push    ebx
  push    esi
  xor     ebx, ebx
  mov     [ebp-4], ebx
  mov     @var1, ebx
  mov     eax, [ecx+84]
  mov     ecx, [eax]
  mov     byte ptr [ebp-4], 1
  invoke  [ecx+1c],eax,004e7460,addr @var1  (這里不管 addr 會(huì )覆蓋掉 eax的值)
  test    eax, eax
  jnz     lable1
  mov     eax, @var1
  mov     ecx, [eax]
  invoke  [ecx+14],eax,004e8940,addr @var2(這里不管 addr 會(huì )覆蓋掉 eax的值)
  test    eax, eax
  je      lable2
lable1:
  mov     eax, _arg3
  mov     dword ptr [eax], 2
  jmp     lable3
lable2:
  mov     eax, _arg2
  push    edi
  mov     edx, @var1
  push    1
  mov     ecx, [eax-8]
  pop     esi
  mov     edi, [edx]
  invoke  [edi+1c],edx,_arg1,ebx,ecx,eax,esi
  test    eax, eax
  pop     edi
  je      lable4
  cmp     _arg4, esi
  je      lable5
  mov     eax, _arg3
  mov     [eax], ebx
  jmp     lable3
lable5:
  invoke  CString::CString,_arg4
  mov     byte ptr [ebp-4], 2
  invoke  CString::CString>,_arg1
  mov     byte ptr [ebp-4], 3
  invoke  BasicCtrlDll.BasicLoadStr,addr _arg4,281h
  invoke  BasicCtrlDll.BasicLoadStr,addr _arg1,28dh
  invoke  CWnd::CWnd,addr @wnd
  mov     byte ptr [ebp-4], 4
  invoke  CWnd::MessageBox,addr @wnd,_arg4,_arg1,MB_YESNO or MB_DEFBUTTON2 or MB_ICONHAND (114h)  ;這個(gè)就是登錄失敗的時(shí)候的標題和信息
  cmp     eax, 6
  mov     eax, _arg3
  jnz     label6
  mov     dword ptr [eax], 2
  jmp     lable7
lable6:
  mov     [eax], ebx
lable7:
  mov     byte ptr [ebp-4], 3
  invoke  CWnd::~CWnd,addr @wnd
  mov     byte ptr [ebp-4], 2
  invoke  CString::~CString,addr _arg1
  mov     byte ptr [ebp-4], 1
  invoke  CString::~CString,_arg4
  jmp     lable3
lable4:
  mov     eax, _arg3
  mov     [eax], esi
lable3:
  mov     eax, _arg3
  mov     [ebp-4], bl
  cmp     eax, ebx
  je      lable8
  mov     ecx, [eax]
  invoke  [ecx+8],eax
lable8:
  or      dword ptr [ebp-4], FFFFFFFF
  invoke  CString::~CString,_arg2
  pop     esi
  pop     ebx
  ret
_TempName  endp
2006-6-18 8:28
識別參數類(lèi)型和局部變量類(lèi)型
  xor     ebx, ebx
  mov     [ebp-4], ebx
  mov     @var1, ebx
由這三天指令中的上下兩條指令:@var1 應該是個(gè)整數類(lèi)型的 改名為@intVar1
  mov  ecx,_regArg1
  mov     eax, [ecx+84]
  mov     ecx, [eax]
  mov     byte ptr [ebp-4], 1
  invoke  [ecx+1c],eax,004e7460,addr @var1  (這里不管 addr 會(huì )覆蓋掉 eax的值)
第一次反匯編,最少面那條指令在日至2中漏掉了
由上面可知:[ecx+1c]=[[eax]+1c]=[[[_regArg1+1c]]]=***(_regArg1+1c) 可知 _regArg1 是函數指針的指針的指針

@var2的類(lèi)型現在還不能判斷,80% 他和@intVar1類(lèi)型一樣,只有跟進(jìn)[ecx+14]函數中才知道

0044C62B   .  B8 84424D00   mov     eax, 004D4284
0044C630   .  E8 6B360200   call    0046FCA0
0044C635   .  51            push    ecx
0044C636   .  51            push    ecx
0044C637   .  8B45 08       mov     eax, [ebp+8]
0044C63A   .  56            push    esi
0044C63B   .  8D4D EC       lea     ecx, [ebp-14]
0044C63E   .  FF70 FC       push    dword ptr [eax-4]
0044C641   .  8D70 E0       lea     esi, [eax-20]
0044C644   .  E8 4B310200   call    <jmp.&MFC42.#6467_AFX_MAINTAIN_S>
0044C649   .  FF75 10       push    dword ptr [ebp+10]
0044C64C   .  8B06          mov     eax, [esi]
0044C64E   .  8365 FC 00    and     dword ptr [ebp-4], 0
0044C652   .  FF75 0C       push    dword ptr [ebp+C]
0044C655   .  56            push    esi
0044C656   .  FF50 64       call    [eax+64]
0044C659   .  8B4D F0       mov     ecx, [ebp-10]
0044C65C   .  8B55 EC       mov     edx, [ebp-14]
0044C65F   .  834D FC FF    or      dword ptr [ebp-4], FFFFFFFF
0044C663   .  5E            pop     esi
0044C664   .  8951 04       mov     [ecx+4], edx
0044C667   .  8B4D F4       mov     ecx, [ebp-C]
0044C66A   .  64:890D 00000>mov     fs:[0], ecx
0044C671   .  C9            leave
0044C672   .  C2 0C00       retn    0C

@var2 對應著(zhù)第三個(gè)參數即[ebp+10] 
0044C649   .  FF75 10       push    dword ptr [ebp+10]
0044C64C   .  8B06          mov     eax, [esi]
0044C64E   .  8365 FC 00    and     dword ptr [ebp-4], 0
0044C652   .  FF75 0C       push    dword ptr [ebp+C]
0044C655   .  56            push    esi
0044C656   .  FF50 64       call    [eax+64]
看來(lái)還要再跟進(jìn)去
0044D23C   .  B8 B4454D00   mov     eax, 004D45B4
0044D241   .  E8 5A2A0200   call    0046FCA0
0044D246   .  83EC 10       sub     esp, 10
0044D249   .  8B45 10       mov     eax, [ebp+10]
0044D24C   .  53            push    ebx
0044D24D   .  56            push    esi
0044D24E   .  57            push    edi
0044D24F   .  C700 01000000 mov     dword ptr [eax], 1
0044D255   .  E8 32240200   call    <jmp.&MFC42.#1154_AfxGetAppModul>
0044D25A   .  8B40 04       mov     eax, [eax+4]
0044D25D   .  33DB          xor     ebx, ebx
0044D25F   .  8B80 D4000000 mov     eax, [eax+D4]
0044D265   .  3BC3          cmp     eax, ebx
0044D267   .  0F84 4C010000 je      0044D3B9
0044D26D   .  895D EC       mov     [ebp-14], ebx
0044D270   .  8B08          mov     ecx, [eax]
0044D272   .  8D55 EC       lea     edx, [ebp-14]
0044D275   .  52            push    edx
0044D276   .  68 E06F4E00   push    004E6FE0
0044D27B   .  50            push    eax
0044D27C   .  895D FC       mov     [ebp-4], ebx
0044D27F   .  FF51 1C       call    [ecx+1C]
0044D282   .  85C0          test    eax, eax
0044D284   .  0F85 1E010000 jnz     0044D3A8
0044D28A   .  895D F0       mov     [ebp-10], ebx
0044D28D   .  8B45 EC       mov     eax, [ebp-14]
0044D290   .  8D55 F0       lea     edx, [ebp-10]
0044D293   .  52            push    edx
0044D294   .  53            push    ebx
0044D295   .  FF75 0C       push    dword ptr [ebp+C]
0044D298   .  8B08          mov     ecx, [eax]
0044D29A   .  C645 FC 01    mov     byte ptr [ebp-4], 1
0044D29E   .  50            push    eax
0044D29F   .  FF51 20       call    [ecx+20]
0044D2A2   .  85C0          test    eax, eax
0044D2A4   .  0F85 EE000000 jnz     0044D398
0044D2AA   .  8B45 F0       mov     eax, [ebp-10]
0044D2AD   .  8D55 E8       lea     edx, [ebp-18]
0044D2B0   .  895D E8       mov     [ebp-18], ebx
0044D2B3   .  52            push    edx
0044D2B4   .  8B08          mov     ecx, [eax]
0044D2B6   .  50            push    eax
0044D2B7   .  FF51 1C       call    [ecx+1C]
0044D2BA   .  85C0          test    eax, eax
0044D2BC   .  0F85 D6000000 jnz     0044D398
0044D2C2   .  8B45 E8       mov     eax, [ebp-18]
0044D2C5   .  40            inc     eax
0044D2C6   .  50            push    eax
0044D2C7   .  E8 5C240200   call    <jmp.&MFC42.#823_operator new>
0044D2CC   .  8BF0          mov     esi, eax
0044D2CE   .  8B45 E8       mov     eax, [ebp-18]
0044D2D1   .  40            inc     eax
0044D2D2   .  8975 0C       mov     [ebp+C], esi
0044D2D5   .  50            push    eax                              ; /n
0044D2D6   .  53            push    ebx                              ; |c
0044D2D7   .  56            push    esi                              ; |s
0044D2D8   .  E8 B5290200   call    <jmp.&MSVCRT.memset>             ; \memset
0044D2DD   .  8B45 F0       mov     eax, [ebp-10]
0044D2E0   .  83C4 10       add     esp, 10
0044D2E3   .  8D55 E4       lea     edx, [ebp-1C]
0044D2E6   .  8B08          mov     ecx, [eax]
0044D2E8   .  52            push    edx
0044D2E9   .  56            push    esi
0044D2EA   .  FF75 E8       push    dword ptr [ebp-18]
0044D2ED   .  50            push    eax
0044D2EE   .  FF51 0C       call    [ecx+C]
0044D2F1   .  85C0          test    eax, eax
0044D2F3   .  74 0C         je      short 0044D301
0044D2F5   .  56            push    esi
0044D2F6   .  E8 8B230200   call    <jmp.&MFC42.#825_operator delete>
0044D2FB   .  59            pop     ecx
0044D2FC   .  E9 97000000   jmp     0044D398
0044D301   >  8B7D 08       mov     edi, [ebp+8]
0044D304   .  53            push    ebx                              ; /Arg1
0044D305   .  8D77 70       lea     esi, [edi+70]                    ; |
0044D308   .  8BCE          mov     ecx, esi                         ; |
0044D30A   .  E8 A49C0500   call    004A6FB3                         ; \QQ.004A6FB3
0044D30F   .  8B06          mov     eax, [esi]
0044D311   .  3BC3          cmp     eax, ebx
0044D313   .  74 08         je      short 0044D31D
0044D315   .  8B08          mov     ecx, [eax]
0044D317   .  50            push    eax
0044D318   .  FF51 08       call    [ecx+8]
0044D31B   .  891E          mov     [esi], ebx
0044D31D   >  56            push    esi
0044D31E   .  E8 136F0700   call    004C4236
0044D323   .  8B06          mov     eax, [esi]
0044D325   .  59            pop     ecx
0044D326   .  FF75 0C       push    dword ptr [ebp+C]
0044D329   .  8B08          mov     ecx, [eax]
0044D32B   .  FF75 E4       push    dword ptr [ebp-1C]
0044D32E   .  50            push    eax
0044D32F   .  FF51 78       call    [ecx+78]
0044D332   .  85C0          test    eax, eax
0044D334   .  74 10         je      short 0044D346
0044D336   .  395D 0C       cmp     [ebp+C], ebx
0044D339   .  74 58         je      short 0044D393
0044D33B   .  FF75 0C       push    dword ptr [ebp+C]
0044D33E   .  E8 43230200   call    <jmp.&MFC42.#825_operator delete>
0044D343   .  59            pop     ecx
0044D344   .  EB 4D         jmp     short 0044D393
0044D346   >  395D 0C       cmp     [ebp+C], ebx
0044D349   .  74 09         je      short 0044D354
0044D34B   .  FF75 0C       push    dword ptr [ebp+C]
0044D34E   .  E8 33230200   call    <jmp.&MFC42.#825_operator delete>
0044D353   .  59            pop     ecx
0044D354   >  8B06          mov     eax, [esi]
0044D356   .  8D57 58       lea     edx, [edi+58]
0044D359   .  52            push    edx
0044D35A   .  68 9CD75200   push    0052D79C                         ;  ASCII "AST"
0044D35F   .  8B08          mov     ecx, [eax]
0044D361   .  50            push    eax
0044D362   .  FF51 34       call    [ecx+34]
0044D365   .  85C0          test    eax, eax
0044D367   .  75 2A         jnz     short 0044D393
0044D369   .  8B06          mov     eax, [esi]
0044D36B   .  8D57 5C       lea     edx, [edi+5C]
0044D36E   .  52            push    edx
0044D36F   .  68 98D75200   push    0052D798                         ;  ASCII "EMH"
0044D374   .  8B08          mov     ecx, [eax]
0044D376   .  50            push    eax
0044D377   .  FF51 44       call    [ecx+44]
0044D37A   .  85C0          test    eax, eax
0044D37C   .  75 15         jnz     short 0044D393
0044D37E   .  8B36          mov     esi, [esi]
0044D380   .  83C7 6C       add     edi, 6C
0044D383   .  57            push    edi
0044D384   .  68 94D75200   push    0052D794                         ;  ASCII "UIN"
0044D389   .  8B06          mov     eax, [esi]
0044D38B   .  56            push    esi
0044D38C   .  FF50 34       call    [eax+34]
0044D38F   .  85C0          test    eax, eax
0044D391   .  74 2D         je      short 0044D3C0
0044D393   >  8B45 10       mov     eax, [ebp+10]
0044D396   .  8918          mov     [eax], ebx
0044D398   >  8B45 F0       mov     eax, [ebp-10]
0044D39B   .  885D FC       mov     [ebp-4], bl
0044D39E   .  3BC3          cmp     eax, ebx
0044D3A0   .  74 06         je      short 0044D3A8
0044D3A2   .  8B08          mov     ecx, [eax]
0044D3A4   .  50            push    eax
0044D3A5   .  FF51 08       call    [ecx+8]
0044D3A8   >  8B45 EC       mov     eax, [ebp-14]
0044D3AB   .  834D FC FF    or      dword ptr [ebp-4], FFFFFFFF
0044D3AF   .  3BC3          cmp     eax, ebx
0044D3B1   .  74 06         je      short 0044D3B9
0044D3B3   .  8B08          mov     ecx, [eax]
0044D3B5   .  50            push    eax
0044D3B6   .  FF51 08       call    [ecx+8]
0044D3B9   >  B8 05400080   mov     eax, 80004005
0044D3BE   .  EB 23         jmp     short 0044D3E3
0044D3C0   >  8B45 F0       mov     eax, [ebp-10]
0044D3C3   .  885D FC       mov     [ebp-4], bl
0044D3C6   .  3BC3          cmp     eax, ebx
0044D3C8   .  74 06         je      short 0044D3D0
0044D3CA   .  8B08          mov     ecx, [eax]
0044D3CC   .  50            push    eax
0044D3CD   .  FF51 08       call    [ecx+8]
0044D3D0   >  8B45 EC       mov     eax, [ebp-14]
0044D3D3   .  834D FC FF    or      dword ptr [ebp-4], FFFFFFFF
0044D3D7   .  3BC3          cmp     eax, ebx
0044D3D9   .  74 06         je      short 0044D3E1
0044D3DB   .  8B08          mov     ecx, [eax]
0044D3DD   .  50            push    eax
0044D3DE   .  FF51 08       call    [ecx+8]
0044D3E1   >  33C0          xor     eax, eax
0044D3E3   >  8B4D F4       mov     ecx, [ebp-C]
0044D3E6   .  5F            pop     edi
0044D3E7   .  5E            pop     esi
0044D3E8   .  5B            pop     ebx
0044D3E9   .  64:890D 00000>mov     fs:[0], ecx
0044D3F0   .  C9            leave
0044D3F1   .  C2 0C00       retn    0C

函數有3個(gè)堆棧參數,沒(méi)有寄存器參數
我們要找的是第三個(gè)參數即[ebp+10]

0044D249   .  8B45 10       mov     eax, [ebp+10]
0044D24C   .  53            push    ebx
0044D24D   .  56            push    esi
0044D24E   .  57            push    edi
0044D24F   .  C700 01000000 mov     dword ptr [eax], 1

由上面的指令可知: [ebp+10] 是一個(gè)整形數的地址,即 我們要確定的@var2是個(gè)整形類(lèi)型,改名為@intVar2
返回_TempName繼續分析
lable1:
  mov     eax, _arg3
  mov     dword ptr [eax], 2
可知:_arg3 是個(gè)整形指針  改名為_(kāi)pIntArg3
  mov     eax, _arg2
  push    edi
  mov     edx, @var1
  push    1
  mov     ecx, [eax-8]
可知:_arg2 是一個(gè)指針    改名為_(kāi)pArg2
  invoke  CString::CString,_arg4  => _arg4 是個(gè)字符串指針  改名為 _lpszArg4
  invoke  CString::CString,_arg1 => _arg1 是個(gè)字符串指針 改名為 _lpszArg1
  invoke  CWnd::CWnd,addr @var3
可知:@var3 是個(gè)隱含的this指針,函數中原來(lái)的指令為
00415C16  |.  8D4D AC       lea     ecx, [ebp-54]
00415C19  |.  E8 569A0500   call    <jmp.&MFC42.#567_CWnd::CWnd>
visual c++ 編譯器使用ecx用作this指針 
所以 @var3 是個(gè)CWnd 的實(shí)例 改名為 @wnd

invoke  CWnd::MessageBox,addr @wnd,_arg4,_arg1,MB_YESNO or MB_DEFBUTTON2 or MB_ICONHAND (114h)  ;這個(gè)就是登錄失敗的時(shí)候的標題和信息
由上面可知:_arg4 為:內容 "輸入密碼與上次成功登陸的密碼不一致,(回車(chē)符)是否到服務(wù)器驗證?"
      _arg1 為:標題 "錯誤"
invoke  CString::~CString,_arg2 => _arg2 是個(gè)字符串指針 改名為_(kāi)lpszArg2
看看現在都確定了那些
_regArg1 是個(gè)函數指針的指針的指針  改名為:_lpRegArg1 吧 ,他終歸是個(gè)指針
_arg1 是個(gè)字符串指針       改名為:_lpszArg1
_arg2 是個(gè)字符串指針       改名為_(kāi)lpszArg2
_arg3 是個(gè)整形指針      改名為_(kāi)pIntArg3
_arg4 是個(gè)字符串指針      改名為 _lpszArg4

@var1 是個(gè)整形數      改名為 @intVar1
@var2 是個(gè)整形數      改名為 @intVar2
@var3 是個(gè)CWnd對象      改名為 @wndVar3

函數現在可以寫(xiě)成:

_TempName  Proc  _lpRegArg1,_lpszArg1,_lpszArg2,_pIntArg3,_arg?,_lpszArg4  (因為不知道倒數第二個(gè)為什么沒(méi)有在函數中引用過(guò),所以先用?表示)
  local  @intVar1,@intVar2
  local  @wndVar3:CWnd
  push    ebx
  push    esi
  xor     ebx, ebx
  mov     [ebp-4], ebx
  mov     @intVar1, ebx
  mov  ecx,_lpRegArg1
  mov     eax, [ecx+84]
  mov     ecx, [eax]
  mov     byte ptr [ebp-4], 1
  invoke  [ecx+1c],eax,004e7460,addr @intVar1  (這里不管 addr 會(huì )覆蓋掉 eax的值)
  test    eax, eax
  jnz     lable1
  mov     eax, @intVar1
  mov     ecx, [eax]
  invoke  [ecx+14],eax,004e8940,addr @intVar2(這里不管 addr 會(huì )覆蓋掉 eax的值)
  test    eax, eax
  je      lable2
lable1:
  mov     eax, _lpIntArg3
  mov     dword ptr [eax], 2
  jmp     lable3
lable2:
  mov     eax, _arg2
  push    edi
  mov     edx, @intVar1
  push    1
  mov     ecx, [eax-8]
  pop     esi
  mov     edi, [edx]
  invoke  [edi+1c],edx,_arg1,ebx,ecx,eax,esi
  test    eax, eax
  pop     edi
  je      lable4
  cmp     _lpszArg4, esi
  je      lable5
  mov     eax, _lpIntArg3
  mov     [eax], ebx
  jmp     lable3
lable5:
  invoke  CString::CString,_lpszArg4
  mov     byte ptr [ebp-4], 2
  invoke  CString::CString>,_lpszArg1
  mov     byte ptr [ebp-4], 3
  invoke  BasicCtrlDll.BasicLoadStr,addr _lpszArg4,281h
  invoke  BasicCtrlDll.BasicLoadStr,addr _lpszArg1,28dh
  invoke  CWnd::CWnd,addr @wnd
  mov     byte ptr [ebp-4], 4
  invoke  CWnd::MessageBox,addr @wnd,_lpszArg4,_lpszArg1,MB_YESNO or MB_DEFBUTTON2 or MB_ICONHAND (114h)  ;這個(gè)就是登錄失敗的時(shí)候的標題和信息
  cmp     eax, 6
  mov     eax, _lpIntArg3
  jnz     label6
  mov     dword ptr [eax], 2
  jmp     lable7
lable6:
  mov     [eax], ebx
lable7:
  mov     byte ptr [ebp-4], 3
  invoke  CWnd::~CWnd,addr @wndVar3
  mov     byte ptr [ebp-4], 2
  invoke  CString::~CString,addr _lpszArg1
  mov     byte ptr [ebp-4], 1
  invoke  CString::~CString,_lpszArg4
  jmp     lable3
lable4:
  mov     eax, _lpIntArg3
  mov     [eax], esi
lable3:
  mov     eax, _lpIntArg3
  mov     [ebp-4], bl
  cmp     eax, ebx
  je      lable8
  mov     ecx, [eax]
  invoke  [ecx+8],eax
lable8:
  or      dword ptr [ebp-4], FFFFFFFF
  invoke  CString::~CString,_lpszArg2
  pop     esi
  pop     ebx
  ret
_TempName  endp

2006-06-21 7:10
找出_TempName 函數的返回值,這里的返回值,只考慮高級語(yǔ)言中的return 語(yǔ)句中的值,不考慮其他引用返回值、等等情況
_TempName 函數在結尾時(shí),沒(méi)有顯示對eax,edx進(jìn)行賦值,可以判斷_TempName 函數的返回值為空,但也有可能_TempName返回她調用函數的值
比如:return func(arg1,..),為了進(jìn)一步確定,看看調用_TempName函數的函數有沒(méi)有在call 00415b55 指令后緊跟著(zhù)使用eax、edx的值
00414FE8  |.  E8 680B0000   call    00415B55                         
00414FED  |.  FFD6          call    esi                              ;  Kernel32.GetTickCount

結果表明:沒(méi)有使用eax,edx ,所以_TempName 的返回值應為void

c++表示的函數圓形應為:
void  TempName(void* regArg1,char* lpszArg1,char* lpszArg2,int* lpIntArg3,?,char* lpszArg4);

下面將匯編語(yǔ)言指令還原成高級語(yǔ)言的表達式

從函數調用語(yǔ)句或比較指令向上倒序還原,例如:
  push    ebx
  push    esi
  xor     ebx, ebx
  mov     [ebp-4], ebx
  mov     @intVar1, ebx
  mov  ecx,_lpRegArg1
  mov     eax, [ecx+84]
  mov     ecx, [eax]
  mov     byte ptr [ebp-4], 1
  invoke  [ecx+1c],eax,004e7460,addr @intVar1  (這里不管 addr 會(huì )覆蓋掉 eax的值)
  test    eax, eax
就從invoke [ecx+1c],eax,004e7460,addr @intVar1 開(kāi)始,用局部變量,和參數替換掉寄存器,這樣我們就去掉了臨時(shí)的寄存器
變量得到了高級語(yǔ)言表達式。(在高級語(yǔ)言中,我把局部變量名前面的@去掉,參數名前面的_去掉)
ecx=[eax]=[[ecx+84]]=[[lpRegArg1+84h]]=*(*(lpRegArg1+84h))
eax=[ecx+84]=[lpRegArg1+84]=*(lpRegArg1+0x84)
invoke [ecx+1c],eax,004e7460,addr @intVar1 用c++ 表示為:
*(*(*(lpRegArg1+0x84))+0x1c)(*(lpRegArg1+0x84),0x004e7460,&intVar1);
刪掉
  mov  ecx,_lpRegArg1
  mov     eax, [ecx+84]
  mov     ecx, [eax]
  這幾個(gè)臨時(shí)的寄存器變量
上面還剩的指令有:
  push    ebx
  push    esi
  ;這是保存寄存器值,與高級語(yǔ)言沒(méi)什么關(guān)系刪掉
  xor     ebx, ebx
  mov     [ebp-4], ebx
  mov     @intVar1, ebx
  mov     byte ptr [ebp-4], 1
可以寫(xiě)成:
  [ebp-4]=0;
  intVar1=0;
        byte ptr[ebp-4]=1;

  以上的指令還原為:

  [ebp-4]=0;
  intVar1=0;
        byte ptr[ebp-4]=1;
  *(*(*(lpRegArg1+0x84))+0x1c)(*(lpRegArg1+0x84),0x004e7460,&intVar1);

  跳轉指令使用條件表達式和goto替換

依次類(lèi)推函數可寫(xiě)為
void TempName(void* lpRegArg1,char* lpszArg1,char* lpszArg2,int* lpIntArg3,?,lpszArg4)
{
  int intVar1,intVar2;
  CWnd wndVar3;
  mov  [ebp-4],0
  intVar1=0;
  *(*(*(lpRegArg1+0x84))+0x1c)(*(lpRegArg1+0x84),0x004e7460,&intVar1);
  if(eax) goto lable1
  *(*(intVar1)+0x14)(intVar1,0x004e8940,&intVar2);
  // 看來(lái)var1 不是個(gè)整形變量,而是個(gè)指針 改名為 lpVar1,函數要改寫(xiě)了
  intVar1=0;這條語(yǔ)句可能是空指針初始化  
}

void TempName(void* lpRegArg1,char* lpszArg1,char* lpszArg2,int* lpIntArg3,?,lpszArg4)
{
  void* lpVar1=NULL;
  int intVar2;
  CWnd wndVar3;
  mov  [ebp-4],0
  *(*(*(lpRegArg1+0x84))+0x1c)(*(lpRegArg1+0x84),0x004e7460,&lpVar1);
  if(eax) goto lable1
  *(*(lpVar1)+0x14)(intVar1,0x004e8940,&intVar2);
  if(!eax) goto lable2;
lable1:
  *lpIntArg3=2;
  goto lable3;
lable2:
  *(*lpVar1+0x1c)(lpVar1,0,*(lpszArg2-8),lpszArg2,1);
  if(!eax) goto lable4;
  if(lpszArg4==1) goto lable5;
  *lpIntArg3=0;
  goto lable3;
lable5:
  CString(lpszArg4);
  mov  byte ptr[ebp-4],2;
  CString(lpszArg1);
  mov  byte ptr[ebp-4],3;
  BasicCrtDll.BasicLoadStr(lpszArg4,0x281);
  BasicCrtDll.BasicLoadStr(lpszArg1,0x28d);
  wndVar3.MessageBox(lpszArg4,lpszArg1,MB_YESNO or MB_DEFBUTTON2 or MB_ICONHAND);
  if (eax!=6) goto lable6
  *lpIntArg3=2;
  goto lable7;
lable6:
  *lpIntArg3=0;
lable7:
  mov  byte ptr[ebp-4],3
  wndVar3.~CWnd();
  mov  byte ptr[ebp-4],2
  ~CString(lpszArg1);
  mov  byte ptr[ebp-4],1
  ~CString(lpszArg4);
  goto lable3;
lable4:
  *lpIntArg3=1;
lable3:
  mov  byte prt[ebp-4],0
  if(lpIntArg3==0) goto lable8;
  *(*lpIntArg3+8)(lpIntArg3);
lable8:
  or  dword ptr[ebp-4],-1
  ~CString(lpszArg2);  
}

下一步還原控制語(yǔ)句:將控制語(yǔ)句,從函數中看到只有向下跳轉的,沒(méi)有向上跳轉的,可知函數中只有循環(huán)結構
給if ... 條件編號:
給代碼快標號
void TempName(void* lpRegArg1,char* lpszArg1,char* lpszArg2,int* lpIntArg3,?,lpszArg4)
{
  void* lpVar1=NULL;
  int intVar2;
  CWnd wndVar3;
  mov  [ebp-4],0
  *(*(*(lpRegArg1+0x84))+0x1c)(*(lpRegArg1+0x84),0x004e7460,&lpVar1);
  if(eax) goto lable1---------------------------------------------------------------------------c1
  *(*(lpVar1)+0x14)(intVar1,0x004e8940,&intVar2);
  if(!eax) goto lable2;-------------------------------------------------------------------------c2
lable1:
  *lpIntArg3=2;-------------------------------code1
  goto lable3;
lable2:
  *(*lpVar1+0x1c)(lpVar1,0,*(lpszArg2-8),lpszArg2,1);
  if(!eax) goto lable4;-------------------------------------------------------------------------c3
  if(*lpszArg4==1) goto lable5;------------------------------------------------------------------c4
  *lpIntArg3=0;-------------------------------code2
  goto lable3;
lable5:
  CString(lpszArg4);---------------------------------------------------code3
  mov  byte ptr[ebp-4],2;
  CString(lpszArg1);
  mov  byte ptr[ebp-4],3;
  BasicCrtDll.BasicLoadStr(lpszArg4,0x281);
  BasicCrtDll.BasicLoadStr(lpszArg1,0x28d);
  wndVar3.MessageBox(lpszArg4,lpszArg1,MB_YESNO or MB_DEFBUTTON2 or MB_ICONHAND);
  if (eax!=6) goto lable6------------------------------------------------------------------------c5
  *lpIntArg3=2;-------------------------------------------------------code4
  goto lable7;
lable6:
  *lpIntArg3=0;-------------------------------------------------------code5
lable7:
  mov  byte ptr[ebp-4],3-------------------------------------------code6
  wndVar3.~CWnd();
  mov  byte ptr[ebp-4],2
  ~CString(lpszArg1);
  mov  byte ptr[ebp-4],1
  ~CString(lpszArg4);
  goto lable3;
lable4:
  *lpIntArg3=1;--------------------------------------------------------code7
lable3:
  mov  byte prt[ebp-4],0---------------------------------------------code8
  if(lpIntArg3==0) goto lable8;-----------------------------------------------------------------c6
  *(*lpIntArg3+8)(lpIntArg3);-------------------------------------------code9
lable8:
  or  dword ptr[ebp-4],-1-------------------------------------------code10
  ~CString(lpszArg2);  
}

第二步:構造邏輯二叉樹(shù),當條件為假時(shí),執行二叉樹(shù)的左邊,當條件為真時(shí),執行二叉樹(shù)的右邊,無(wú)條件跳轉和順序執行的用直線(xiàn)表示
如過(guò)用原來(lái)的條件畫(huà)數不好畫(huà),有交叉線(xiàn),就對原來(lái)的條件取反,可得到如下所示的二叉樹(shù):

if(c1 || !c2) 
{
  code1
}
elseif( c3 )
{
  code7;
}
elseif (c4)
{
  code3;
  if(c5)
  {
    code5;
  }
  else
  {
    code4;
  }
  code6;
}
else
{
  code2;
}

code8;
if(!c6)
{
  code9;
}
code10;

將條件編號和代碼快編號用相應的語(yǔ)句替換可得:
c1 的條件為 測試eax!=0 ,而eax就是上面函數調用的返回值
所以TempName函數可寫(xiě)為:
void TempName(void* lpRegArg1,char* lpszArg1,char* lpszArg2,int* lpIntArg3,?,lpszArg4)
{
  void* lpVar1=NULL;
  int intVar2;
  CWnd wndVar3;
  mov  [ebp-4],0
  if(*(*(*(lpRegArg1+0x84))+0x1c)(*(lpRegArg1+0x84),0x004e7460,&lpVar1) || !*(*(lpVar1)+0x14)(intVar1,0x004e8940,&intVar2))
  {
    *pIntArg3=2;--------------------------------------------------------code1
  }
  elseif (!*(*lpVar1+0x1c)(lpVar1,0,*(lpszArg2-8),lpszArg2,1))
  {
    *lpIntArg3=1;--------------------------------------------------------code7
  }
  elseif (*lpszArg4==1)
  {
    CString(lpszArg4);---------------------------------------------------code3
    mov  byte ptr[ebp-4],2;
    CString(lpszArg1);
    mov  byte ptr[ebp-4],3;
    BasicCrtDll.BasicLoadStr(lpszArg4,0x281);
    BasicCrtDll.BasicLoadStr(lpszArg1,0x28d);
    wndVar3.MessageBox(lpszArg4,lpszArg1,MB_YESNO or MB_DEFBUTTON2 or MB_ICONHAND);
    if(wndVar3.MessageBox(lpszArg4,lpszArg1,MB_YESNO or MB_DEFBUTTON2 or MB_ICONHAND)!=6)
    {
    *lpIntArg3=0
    }
    else
    {
    *lpIntArg3=2
          }
    mov  byte ptr[ebp-4],3-------------------------------------------code6
    wndVar3.~CWnd();
    mov  byte ptr[ebp-4],2
    ~CString(lpszArg1);
    mov  byte ptr[ebp-4],1
    ~CString(lpszArg4);
  }
  else
  {
    *lpIntArg3=0--------------------------------code2
  }
  mov  byte prt[ebp-4],0---------------------------code8
  if(!(lpIntArg3==0))
  {
    *(*lpIntArg3+8)(lpIntArg3);-------------------------------------------code9
  }
  or  dword ptr[ebp-4],-1-------------------------------------------code10
  ~CString(lpszArg2);
}

今天就到這里,這里可能會(huì )出好多錯誤,希望大家能不吝賜教,我對c++,mfc 不熟,只對匯編比較熟,所以上面有些代碼,也不知道什么樣的源程序可以編譯成這個(gè)
樣子,上面的代碼中帶有匯編指令,不過(guò)程序大致思路是這樣的,還有如果誰(shuí)有還原分支語(yǔ)句的好方法,講出來(lái),大家分享一下。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
去除天狼星視頻加密系統的各種限制
【原創(chuàng )】OllyDBG分析報告系列(1)
怎樣查看lib文件中的函數名和函數參數啊
Sentinel驅動(dòng)模擬源碼
C++中的成員函數調用原理及this指針的傳遞方式
通達信修改技術(shù):暴力初步(直接免費登錄高級行情)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久