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
00401