淺談VB6逆向工程(3)

看雪資料發表於2004-12-25

3. VB6的控制結構
                                 
    下面要提到的vb的控制結構語句有:if語句,select case語句,while語句,do語句,
for語句。

    1)if語句
    
    if語句的典型語法是: 

        If 條件1 Then
            語句塊1 
        ElseIf 條件2 Then
            語句塊2 
        Else
            語句塊3 
        End If
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    
    程式碼:
    Dim a   //注意:這裡定義的是變體變數。
            //如果不用變體變數,編譯器將最佳化掉太多的程式碼。:(
            //當你熟悉變體型別後,其他的將很容易分析 ^_^
    a = 5
    
    If a < 5 Then
        MsgBox ("a < 5")
    ElseIf a = 5 Then
        MsgBox ("a = 5")
    Else
        MsgBox ("a > 5")
    End If
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    反彙編程式碼:
00401A72  XOR ESI,ESI
00401A74  MOV EDI,5
00401A79  MOV DWORD PTR SS:[EBP-74],ESI
00401A7C  LEA EDX,DWORD PTR SS:[EBP-74]
00401A7F  LEA ECX,DWORD PTR SS:[EBP-24]
00401A82  MOV DWORD PTR SS:[EBP-24],ESI
00401A85  MOV DWORD PTR SS:[EBP-34],ESI ----> 這些變數是為 MsgBox 使用的
00401A88  MOV DWORD PTR SS:[EBP-44],ESI   |
00401A8B  MOV DWORD PTR SS:[EBP-54],ESI   |
00401A8E  MOV DWORD PTR SS:[EBP-64],ESI ---
00401A91  MOV DWORD PTR SS:[EBP-6C],EDI  // 5
00401A94  MOV DWORD PTR SS:[EBP-74],2    //整數型別
00401A9B  CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarMove>]//賦值
                                         //到這裡  a = 5  //[ebp-24]
00401AA1  LEA EAX,DWORD PTR SS:[EBP-24]
00401AA4  LEA ECX,DWORD PTR SS:[EBP-74]  
00401AA7  MOV EBX,8002
00401AAC  PUSH EAX
00401AAD  PUSH ECX
00401AAE  MOV DWORD PTR SS:[EBP-6C],EDI  // 5
00401AB1  MOV DWORD PTR SS:[EBP-74],EBX  // 8002 
00401AB4  CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarTstLt>] // a < 5 ?
00401ABA  TEST AX,AX
00401ABD  JE SHORT 工程2.00401AE4   //不小於則跳走

00401ABF  MOV ECX,80020004
00401AC4  MOV EAX,0A
00401AC9  MOV DWORD PTR SS:[EBP-5C],ECX
00401ACC  MOV DWORD PTR SS:[EBP-64],EAX
00401ACF  MOV DWORD PTR SS:[EBP-4C],ECX
00401AD2  MOV DWORD PTR SS:[EBP-54],EAX
00401AD5  MOV DWORD PTR SS:[EBP-3C],ECX
00401AD8  MOV DWORD PTR SS:[EBP-44],EAX
00401ADB  MOV DWORD PTR SS:[EBP-6C],工程2.004016C4;  UNICODE "a < 5"
00401AE2  JMP SHORT 工程2.00401B63

00401AE4  LEA ECX,DWORD PTR SS:[EBP-24]
00401AE7  LEA EDX,DWORD PTR SS:[EBP-74]
00401AEA  PUSH ECX
00401AEB  PUSH EDX
00401AEC  MOV DWORD PTR SS:[EBP-6C],EDI  // 5
00401AEF  MOV DWORD PTR SS:[EBP-74],EBX  // 8002
00401AF2  CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarTstEq>]// a = 5 ?
00401AF8  TEST AX,AX
00401AFB  MOV ECX,80020004
00401B00  MOV EAX,0A
00401B05  MOV DWORD PTR SS:[EBP-5C],ECX
00401B08  MOV DWORD PTR SS:[EBP-64],EAX
00401B0B  MOV DWORD PTR SS:[EBP-4C],ECX
00401B0E  MOV DWORD PTR SS:[EBP-54],EAX
00401B11  MOV DWORD PTR SS:[EBP-3C],ECX
00401B14  MOV DWORD PTR SS:[EBP-44],EAX
00401B17  JE SHORT 工程2.00401B5C         //不相等則跳走

00401B19  LEA EDX,DWORD PTR SS:[EBP-74]
00401B1C  LEA ECX,DWORD PTR SS:[EBP-34]
00401B1F  MOV DWORD PTR SS:[EBP-6C],工程2.004016D4;  UNICODE "a = 5"
00401B26  MOV DWORD PTR SS:[EBP-74],8
00401B2D  CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarDup>]
00401B33  LEA EAX,DWORD PTR SS:[EBP-64]
00401B36  LEA ECX,DWORD PTR SS:[EBP-54]
00401B39  PUSH EAX
00401B3A  LEA EDX,DWORD PTR SS:[EBP-44]
00401B3D  PUSH ECX
00401B3E  PUSH EDX
00401B3F  LEA EAX,DWORD PTR SS:[EBP-34]
00401B42  PUSH ESI
00401B43  PUSH EAX
00401B44  CALL DWORD PTR DS:[<&MSVBVM60.#595>];  MSVBVM60.rtcMsgBox
00401B4A  LEA ECX,DWORD PTR SS:[EBP-64]
00401B4D  LEA EDX,DWORD PTR SS:[EBP-54]
00401B50  PUSH ECX
00401B51  LEA EAX,DWORD PTR SS:[EBP-44]
00401B54  PUSH EDX
00401B55  LEA ECX,DWORD PTR SS:[EBP-34]
00401B58  PUSH EAX
00401B59  PUSH ECX
00401B5A  JMP SHORT 工程2.00401B9D
                                        // 其他條件滿足則執行這裡
00401B5C  MOV DWORD PTR SS:[EBP-6C],工程2.004016E4;  UNICODE "a > 5"
00401B63  LEA EDX,DWORD PTR SS:[EBP-74]
00401B66  LEA ECX,DWORD PTR SS:[EBP-34]
00401B69  MOV DWORD PTR SS:[EBP-74],8
00401B70  CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarDup>]
00401B76  LEA EDX,DWORD PTR SS:[EBP-64]
00401B79  LEA EAX,DWORD PTR SS:[EBP-54]
00401B7C  PUSH EDX
00401B7D  LEA ECX,DWORD PTR SS:[EBP-44]
00401B80  PUSH EAX
00401B81  PUSH ECX
00401B82  LEA EDX,DWORD PTR SS:[EBP-34]
00401B85  PUSH ESI
00401B86  PUSH EDX
00401B87  CALL DWORD PTR DS:[<&MSVBVM60.#595>];  MSVBVM60.rtcMsgBox
    
    流程大概如此。上面出現了一些VB內部函式,如果你不太熟悉那些函式的意義,可以
到DFCG上下載一份我整理的vb內部函式。:)
===========================================================
    2)select case 語句

    select case 語句的語法如下:

    Select Case 測試表示式
           Case 表示式列表1
                語句塊1
           Case 表示式列表2
                語句塊2
           ......
           Case Else
                語句塊n
    End Select
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    程式碼:
    Dim a, b
    a = 5    
    Select Case a
      Case 3
        b = "3"
      Case 5
        b = "5"
      Case Else
        b = "0"
    End Select
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    反彙編程式碼(速度最佳化編譯)
00401A2F  XOR ESI,ESI                     // 用來初始化變數
00401A31  LEA EDX,DWORD PTR SS:[EBP-44]
00401A34  MOV DWORD PTR SS:[EBP-44],ESI
00401A37  LEA ECX,DWORD PTR SS:[EBP-24]
00401A3A  MOV DWORD PTR SS:[EBP-24],ESI
00401A3D  MOV DWORD PTR SS:[EBP-34],ESI
00401A40  MOV DWORD PTR SS:[EBP-54],ESI
00401A43  MOV DWORD PTR SS:[EBP-3C],5      // 5
00401A4A  MOV DWORD PTR SS:[EBP-44],2      // 型別
00401A51  CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarMove>]
                                           // a = 5   //[ebp-24]
  
00401A57  MOV EBX,DWORD PTR DS:[<&MSVBVM60.__vbaVarCopy>]
00401A5D  LEA EDX,DWORD PTR SS:[EBP-24]
00401A60  LEA ECX,DWORD PTR SS:[EBP-54]
00401A63  CALL EBX                         // 生成一個臨時變數 //[ebp-54]
                                           // Select Case a
                                           
                                                  
00401A65  MOV EDI,DWORD PTR DS:[<&MSVBVM60.__vbaVarTstEq>
00401A6B  LEA EAX,DWORD PTR SS:[EBP-54]
00401A6E  LEA ECX,DWORD PTR SS:[EBP-44]
00401A71  PUSH EAX
00401A72  PUSH ECX
00401A73  MOV DWORD PTR SS:[EBP-3C],3      // 3
00401A7A  MOV DWORD PTR SS:[EBP-44],8002
00401A81  CALL EDI                                       
00401A83  TEST AX,AX
00401A86  JE SHORT 工程2.00401A91          // 不等於3則跳
                                           //  Case 3
00401A88  MOV DWORD PTR SS:[EBP-3C],工程2.004016B4 // '3'
00401A8F  JMP SHORT 工程2.00401ABC

00401A91  LEA EDX,DWORD PTR SS:[EBP-54]
00401A94  LEA EAX,DWORD PTR SS:[EBP-44]
00401A97  PUSH EDX
00401A98  PUSH EAX
00401A99  MOV DWORD PTR SS:[EBP-3C],5      // 5
00401AA0  MOV DWORD PTR SS:[EBP-44],8002
00401AA7  CALL EDI
00401AA9  TEST AX,AX
00401AAC  MOV DWORD PTR SS:[EBP-3C],工程2.004016BC // '5'
00401AB3  JNZ SHORT 工程2.00401ABC         // 不等於5則跳
                                           // Case 5

00401AB5  MOV DWORD PTR SS:[EBP-3C],工程2.004016C4 // '0'
00401ABC  LEA EDX,DWORD PTR SS:[EBP-44]
00401ABF  LEA ECX,DWORD PTR SS:[EBP-34]
00401AC2  MOV DWORD PTR SS:[EBP-44],8      // String型別
00401AC9  CALL EBX                         // 為變數 b 賦值
                                           // Case Else
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    當然這段程式碼在逆向時也可以用if語句來表達。逆向出來的不如select case
語句那樣直觀。在我看來用if語句表達應該是這樣的:
    dim a,b
    if a = 3 then
       b = "3"
    else if a = 5 then
       b = "5"
    else
       b = "0"
    end if
===========================================================    
    3)while語句
    
    while語句的典型語法是:
    
    While 條件
      語句塊
    Wend
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    程式碼:
    Dim a, b
    a = 3
    b = 0
    While a > 0
      b = b + a
      a = a - 1
    Wend
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    反彙編程式碼(速度最佳化編譯)
00401A1F   MOV ESI,DWORD PTR DS:[<&MSVBVM60.__vbaVarMove>]
00401A25   XOR EDI,EDI                       // 初始化變數 
00401A27   MOV EBX,2
00401A2C   MOV DWORD PTR SS:[EBP-54],EDI
00401A2F   LEA EDX,DWORD PTR SS:[EBP-54]
00401A32   LEA ECX,DWORD PTR SS:[EBP-24]
00401A35   MOV DWORD PTR SS:[EBP-24],EDI
00401A38   MOV DWORD PTR SS:[EBP-34],EDI
00401A3B   MOV DWORD PTR SS:[EBP-44],EDI
00401A3E   MOV DWORD PTR SS:[EBP-4C],3       // 3
00401A45   MOV DWORD PTR SS:[EBP-54],EBX     // integer型別
00401A48   CALL ESI         
                                             // a = 3 //[ebp-24]
                                                                           
00401A4A   LEA EDX,DWORD PTR SS:[EBP-54]
00401A4D   LEA ECX,DWORD PTR SS:[EBP-34]
00401A50   MOV DWORD PTR SS:[EBP-4C],EDI     // 0
00401A53   MOV DWORD PTR SS:[EBP-54],EBX     // integer型別
00401A56   CALL ESI
                                             // b = 0 //[ebp-34]
                                             
00401A58   MOV EDI,DWORD PTR DS:[<&MSVBVM60.__vbaVarAdd>] 
00401A5E   MOV EBX,DWORD PTR DS:[<&MSVBVM60.__vbaVarSub>] 

00401A64   LEA EAX,DWORD PTR SS:[EBP-24]
00401A67   LEA ECX,DWORD PTR SS:[EBP-54]     // 0
00401A6A   PUSH EAX
00401A6B   PUSH ECX
00401A6C   MOV DWORD PTR SS:[EBP-4C],0
00401A73   MOV DWORD PTR SS:[EBP-54],8002
00401A7A   CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarTstGt>]  
00401A80   TEST AX,AX
00401A83   JE SHORT 工程2.00401ABF            // a 不大於0則退出迴圈
                                             // while a > 0
                                             
00401A85   LEA EDX,DWORD PTR SS:[EBP-34]     
00401A88   LEA EAX,DWORD PTR SS:[EBP-24]
00401A8B   PUSH EDX                          // b
00401A8C   LEA ECX,DWORD PTR SS:[EBP-44]     
00401A8F   PUSH EAX                          // a
00401A90   PUSH ECX
00401A91   CALL EDI                  
00401A93   MOV EDX,EAX                       // b + a
00401A95   LEA ECX,DWORD PTR SS:[EBP-34]     // b  
00401A98   CALL ESI                         
                                             // b = b + a
                                             
00401A9A   LEA EDX,DWORD PTR SS:[EBP-24]     // a
00401A9D   LEA EAX,DWORD PTR SS:[EBP-54]
00401AA0   PUSH EDX
00401AA1   LEA ECX,DWORD PTR SS:[EBP-44]
00401AA4   PUSH EAX
00401AA5   PUSH ECX
00401AA6   MOV DWORD PTR SS:[EBP-4C],1       // 1
00401AAD   MOV DWORD PTR SS:[EBP-54],2       // integer型別
00401AB4   CALL EBX
00401AB6   MOV EDX,EAX                       // a - 1
00401AB8   LEA ECX,DWORD PTR SS:[EBP-24]
00401ABB   CALL ESI
                                             // a = a - 1
                                             
00401ABD   JMP SHORT 工程2.00401A64          //注意:這裡往回跳
                                            // Wend
===========================================================    
    4)do語句     
    
    這個語句的格式比較多,典型的格式如下:
    
    Do 
      語句塊
    Loop Until 迴圈條件
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    Dim a, b
    a = 3
    b = 0
    Do
      b = a + b
      a = a - 1
    Loop Until a <= 0  
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    反彙編程式碼(速度最佳化)
00401A1F   MOV ESI,DWORD PTR DS:[<&MSVBVM60.__vbaVarMove>]
00401A25   XOR EDI,EDI
00401A27   MOV EBX,2
00401A2C   MOV DWORD PTR SS:[EBP-54],EDI
00401A2F   LEA EDX,DWORD PTR SS:[EBP-54]
00401A32   LEA ECX,DWORD PTR SS:[EBP-24]
00401A35   MOV DWORD PTR SS:[EBP-24],EDI
00401A38   MOV DWORD PTR SS:[EBP-34],EDI
00401A3B   MOV DWORD PTR SS:[EBP-44],EDI
00401A3E   MOV DWORD PTR SS:[EBP-4C],3     //3
00401A45   MOV DWORD PTR SS:[EBP-54],EBX   //integer
00401A48   CALL ESI     
                                           // a = 3 //[ebp-24]
                                           
00401A4A   LEA EDX,DWORD PTR SS:[EBP-54]
00401A4D   LEA ECX,DWORD PTR SS:[EBP-34]
00401A50   MOV DWORD PTR SS:[EBP-4C],EDI   //0
00401A53   MOV DWORD PTR SS:[EBP-54],EBX   //integer
00401A56   CALL ESI
                                           // b = 0 //[ebp-34]
                                           
00401A58   MOV EBX,DWORD PTR DS:[<&MSVBVM60.__vbaVarAdd>] 
00401A5E   LEA EAX,DWORD PTR SS:[EBP-24]   // a
00401A61   LEA ECX,DWORD PTR SS:[EBP-34]   // b
00401A64   PUSH EAX
00401A65   LEA EDX,DWORD PTR SS:[EBP-44]
00401A68   PUSH ECX
00401A69   PUSH EDX
00401A6A   CALL EBX
00401A6C   MOV EDX,EAX
00401A6E   LEA ECX,DWORD PTR SS:[EBP-34]
00401A71   CALL ESI
                                            // b = a + b
                                            
00401A73   LEA EAX,DWORD PTR SS:[EBP-24]    // a
00401A76   LEA ECX,DWORD PTR SS:[EBP-54]    
00401A79   PUSH EAX
00401A7A   LEA EDX,DWORD PTR SS:[EBP-44]
00401A7D   PUSH ECX
00401A7E   PUSH EDX
00401A7F   MOV DWORD PTR SS:[EBP-4C],1      // 1
00401A86   MOV DWORD PTR SS:[EBP-54],2      // integer
00401A8D   CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarSub>]    
00401A93   MOV EDX,EAX
00401A95   LEA ECX,DWORD PTR SS:[EBP-24]    // a
00401A98   CALL ESI
                                            // a = a - 1
00401A9A   LEA EAX,DWORD PTR SS:[EBP-24]
00401A9D   LEA ECX,DWORD PTR SS:[EBP-54]
00401AA0   PUSH EAX
00401AA1   PUSH ECX
00401AA2   MOV DWORD PTR SS:[EBP-4C],EDI    // 0
00401AA5   MOV DWORD PTR SS:[EBP-54],8002
00401AAC   CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarTstLe>]  
00401AB2   TEST AX,AX
00401AB5   JE SHORT 工程2.00401A5E
                                            loop until a <= 0                                     
===========================================================
    5)for語句
    
    for語句的典型語法如下:
    
    for 迴圈變數 = 初值 to 終值 [step 步長]
      迴圈體
    next 迴圈變數
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    程式碼:
    a = 0
    For i = 0 To 100 Step 2
      a = a + i
    Next i
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    反彙編程式碼(速度最佳化)
00401A42   MOV EBX,DWORD PTR DS:[<&MSVBVM60.__vbaVarMove>] 
00401A48   XOR ESI,ESI
00401A4A   MOV EDI,2
00401A4F   MOV DWORD PTR SS:[EBP-54],ESI
00401A52   LEA EDX,DWORD PTR SS:[EBP-54]
00401A55   LEA ECX,DWORD PTR SS:[EBP-34]
00401A58   MOV DWORD PTR SS:[EBP-24],ESI
00401A5B   MOV DWORD PTR SS:[EBP-34],ESI
00401A5E   MOV DWORD PTR SS:[EBP-44],ESI
00401A61   MOV DWORD PTR SS:[EBP-64],ESI
00401A64   MOV DWORD PTR SS:[EBP-74],ESI
00401A67   MOV DWORD PTR SS:[EBP-84],ESI
00401A6D   MOV DWORD PTR SS:[EBP-94],ESI
00401A73   MOV DWORD PTR SS:[EBP-4C],ESI  //0
00401A76   MOV DWORD PTR SS:[EBP-54],EDI  //integer
00401A79   CALL EBX        
                                          // a = 0  //[ebp-34]
                                          
00401A7B   LEA EAX,DWORD PTR SS:[EBP-54]
00401A7E   LEA ECX,DWORD PTR SS:[EBP-64]  
00401A81   PUSH EAX                       // 增量
00401A82   LEA EDX,DWORD PTR SS:[EBP-74]
00401A85   PUSH ECX                       // 終值
00401A86   LEA EAX,DWORD PTR SS:[EBP-94]
00401A8C   PUSH EDX                       // 初值
00401A8D   LEA ECX,DWORD PTR SS:[EBP-84]
00401A93   PUSH EAX                       //臨時終值
00401A94   LEA EDX,DWORD PTR SS:[EBP-24]
00401A97   PUSH ECX                       //臨時增量
00401A98   PUSH EDX                       // 迴圈變數
00401A99   MOV DWORD PTR SS:[EBP-4C],EDI  // 2
00401A9C   MOV DWORD PTR SS:[EBP-54],EDI  // integer
00401A9F   MOV DWORD PTR SS:[EBP-5C],64   // 100
00401AA6   MOV DWORD PTR SS:[EBP-64],EDI  // integer
00401AA9   MOV DWORD PTR SS:[EBP-6C],ESI  // 0
00401AAC   MOV DWORD PTR SS:[EBP-74],EDI  // integer
00401AAF   CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarForInit>] 
                            //For i = 0 To 100 Step 2

00401AB5   MOV EDI,DWORD PTR DS:[<&MSVBVM60.__vbaVarAdd>]  
00401ABB   CMP EAX,ESI
00401ABD   JE SHORT 工程2.00401AEE

00401ABF   LEA EAX,DWORD PTR SS:[EBP-34] //a
00401AC2   LEA ECX,DWORD PTR SS:[EBP-24] //i
00401AC5   PUSH EAX
00401AC6   LEA EDX,DWORD PTR SS:[EBP-44]
00401AC9   PUSH ECX
00401ACA   PUSH EDX
00401ACB   CALL EDI
00401ACD   MOV EDX,EAX
00401ACF   LEA ECX,DWORD PTR SS:[EBP-34]
00401AD2   CALL EBX
                                         // a = a + i
                                         
00401AD4   LEA EAX,DWORD PTR SS:[EBP-94] //臨時終值
00401ADA   LEA ECX,DWORD PTR SS:[EBP-84] //臨時增量
00401AE0   PUSH EAX
00401AE1   LEA EDX,DWORD PTR SS:[EBP-24] // 迴圈變數
00401AE4   PUSH ECX
00401AE5   PUSH EDX
00401AE6   CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarForNext>] 
00401AEC   JMP SHORT 工程2.00401ABB
                                         // next i
===========================================================
    上面出現了我定義的兩個名詞:臨時終值和臨時增量,這兩個值什麼意思呢?
也就是當__vbaVarForInit函式執行完後這兩個值將分別被賦予終值和增量的值。
從上面可以看出,__vbaVarForInit只是執行一次,以後再執行就是__vbaVarForNext
了。因此程式必須知道迴圈變數到那裡結束,每次步長多少。這兩個值就是儲存這些
資訊的。
    當滿足迴圈條件時,這兩個函式都返回1,不滿足時返回0。
    
===========================================================
    到現在為止分析基本的程式結構應該沒問題了。在這裡把前面沒完成的工作
補一下:看看 Array函式和 For Each ... Next 語句。

    程式碼:
    Dim a
    a = Array(5, 6, 7)
    For Each x In a
    Print x
    Next x    
    
    編譯後的彙編程式碼:
00401AC3   XOR ESI,ESI
00401AC5   LEA EDX,DWORD PTR SS:[EBP-48]
00401AC8   PUSH ESI
00401AC9   PUSH 2
00401ACB   PUSH 1
00401ACD   PUSH ESI
00401ACE   PUSH EDX
00401ACF   PUSH 10
00401AD1   PUSH 880
00401AD6   MOV DWORD PTR SS:[EBP-24],ESI
00401AD9   MOV DWORD PTR SS:[EBP-34],ESI
00401ADC   MOV DWORD PTR SS:[EBP-44],ESI
00401ADF   MOV DWORD PTR SS:[EBP-48],ESI
00401AE2   MOV DWORD PTR SS:[EBP-58],ESI
00401AE5   MOV DWORD PTR SS:[EBP-68],ESI
00401AE8   MOV DWORD PTR SS:[EBP-78],ESI
00401AEB   MOV DWORD PTR SS:[EBP-7C],ESI
00401AEE   MOV DWORD PTR SS:[EBP-80],ESI
00401AF1   MOV DWORD PTR SS:[EBP-84],ESI
00401AF7   MOV DWORD PTR SS:[EBP-88],ESI
00401AFD   CALL DWORD PTR DS:[<&MSVBVM60.__vbaRedim>] //定義一個變體型別的動態陣列
     
00401B03   MOV EAX,DWORD PTR SS:[EBP-48]
00401B06   MOV DWORD PTR SS:[EBP-50],5   //5
00401B0D   MOV DWORD PTR SS:[EBP-58],2   //integer
00401B14   ADD ESP,1C
00401B17   MOV ECX,DWORD PTR DS:[EAX+14]
00401B1A   LEA EDX,DWORD PTR SS:[EBP-58]
00401B1D   SHL ECX,4                     //變體型別所佔儲存空間位元組數
00401B20   MOV EDI,ECX
00401B22   MOV ECX,DWORD PTR DS:[EAX+C]
00401B25   SUB ECX,EDI
00401B27   MOV EDI,DWORD PTR DS:[<&MSVBVM60.__vbaVarMove>]  
00401B2D   CALL EDI                       
                                         //第一個元素賦值5                  
00401B2F   MOV EAX,DWORD PTR SS:[EBP-48]
00401B32   MOV DWORD PTR SS:[EBP-60],6   //6
00401B39   MOV DWORD PTR SS:[EBP-68],2   //integer
00401B40   LEA EDX,DWORD PTR SS:[EBP-68]
00401B43   MOV ECX,DWORD PTR DS:[EAX+14]
00401B46   SHL ECX,4
00401B49   MOV DWORD PTR SS:[EBP-98],ECX
00401B4F   MOV ECX,DWORD PTR DS:[EAX+C]
00401B52   MOV EAX,DWORD PTR SS:[EBP-98]
00401B58   SUB ECX,EAX
00401B5A   ADD ECX,10                    //指向下個元素
00401B5D   CALL EDI
                                         //第二個元素賦值6
00401B5F   MOV EAX,DWORD PTR SS:[EBP-48]
00401B62   MOV ECX,2
00401B67   MOV DWORD PTR SS:[EBP-70],7   //7
00401B6E   MOV DWORD PTR SS:[EBP-78],ECX //integer
00401B71   SUB ECX,DWORD PTR DS:[EAX+14]
00401B74   LEA EDX,DWORD PTR SS:[EBP-78]
00401B77   SHL ECX,4
00401B7A   ADD ECX,DWORD PTR DS:[EAX+C]  //指向下個元素
00401B7D   CALL EDI
                                         //第三個元素賦值7
00401B7F   LEA ECX,DWORD PTR SS:[EBP-48]
00401B82   LEA EDX,DWORD PTR SS:[EBP-44]
00401B85   PUSH ECX
00401B86   PUSH EDX
00401B87   CALL DWORD PTR DS:[<&MSVBVM60.#601>] //函式rtcArray
            
00401B8D   LEA EAX,DWORD PTR SS:[EBP-48]
00401B90   PUSH EAX
00401B91   PUSH ESI
00401B92   CALL DWORD PTR DS:[<&MSVBVM60.__vbaErase>] //釋放動態陣列
      
00401B98   LEA EDX,DWORD PTR SS:[EBP-44]
00401B9B   LEA ECX,DWORD PTR SS:[EBP-24]
00401B9E   CALL EDI
                                           //a = Array(5, 6, 7)
---------------------------------------------------------------                                              
00401BA0   LEA ECX,DWORD PTR SS:[EBP-24]   //a
00401BA3   LEA EDX,DWORD PTR SS:[EBP-34]   //x
00401BA6   PUSH ECX
00401BA7   LEA EAX,DWORD PTR SS:[EBP-7C]
00401BAA   PUSH EDX
00401BAB   LEA ECX,DWORD PTR SS:[EBP-84]
00401BB1   PUSH EAX
00401BB2   LEA EDX,DWORD PTR SS:[EBP-88]
00401BB8   PUSH ECX
00401BB9   LEA EAX,DWORD PTR SS:[EBP-80]
00401BBC   PUSH EDX
00401BBD   PUSH EAX
00401BBE   CALL DWORD PTR DS:[<&MSVBVM60.__vbaForEachVar>]  
00401BC4   MOV EDI,DWORD PTR DS:[<&MSVBVM60.__vbaPrintObj>] 
00401BCA   CMP EAX,ESI
00401BCC   JE SHORT 工程1.00401BFF
00401BCE   LEA ECX,DWORD PTR SS:[EBP-34]  //x
00401BD1   PUSH ECX
00401BD2   PUSH EBX
00401BD3   PUSH 工程1.0040192C
00401BD8   CALL EDI
                                          //print x
00401BDA   ADD ESP,0C
00401BDD   LEA EDX,DWORD PTR SS:[EBP-34]  //x
00401BE0   LEA EAX,DWORD PTR SS:[EBP-7C]  //0,意義還不清楚 :(
00401BE3   LEA ECX,DWORD PTR SS:[EBP-84]  //變體陣列型別 &HC
00401BE9   PUSH EDX
00401BEA   PUSH EAX
00401BEB   LEA EDX,DWORD PTR SS:[EBP-88]  //這裡可能是一個計數器
00401BF1   PUSH ECX
00401BF2   LEA EAX,DWORD PTR SS:[EBP-80]  //陣列a的值的地址
00401BF5   PUSH EDX
00401BF6   PUSH EAX
00401BF7   CALL DWORD PTR DS:[<&MSVBVM60.__vbaNextEachVar>] 
00401BFD   JMP SHORT 工程1.00401BCA
-------------------------------------------------------------
    希望看到上面這一段時能讓你想到這是個 For Each ... Next 語句,這個
語句和for迴圈很象,對嗎? ^_^

相關文章