【作者】 stephentj
【使用工具】 OllyDbg1.10
【平台】 WinXP、Visual studio.NET 2003
【编写语言】 VB.NET
最近装了.net,首先想到将来这种开发工具开发的软件怎么破解。看了WinHack[CCG]大侠的《Net环境下的程序破解》,初步认识了ILasm、ILDasm这两个工具。发现好像只能静态分析,“如何动态调试.net下的程序”在google上没找到。也许已经有了成熟的技术,所以想抛砖引玉,请各位大侠指教。下面通过分析一个简单的VB.NET程序(自己编的)在OD中的调试过程,汇报一下学习成果。各位大侠不要用鸡蛋扔我噢~~~
1.源程序:
自己动手,便一个简单的VB.NET程序,在源程序中,画了两个文本框(textBox1、textBox2)、一个命令按钮,类似一个Crackme,主要处理代码如下:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Key1%, a1%, a2%, a3%, Key2%
If Len(TextBox1.Text) <> 6 Then
MsgBox("6 Charactor Please.")
Exit Sub
Else
a1 = Val(Mid(TextBox1.Text, 1, 2))
a2 = Val(Mid(TextBox1.Text, 3, 2))
a3 = Val(Mid(TextBox1.Text, 5, 2))
Key1 = a1 Or a2 + a1 And a3 - a2 Xor a3
End If
If Len(TextBox2.Text) < 5 Then
MsgBox("5 Charactor least")
Exit Sub
Else
Key2 = Asc(Mid(TextBox2.Text, 1)) + Asc(Mid(TextBox2.Text, 2)) - Asc(Mid(TextBox2.Text, 3)) * Asc(Mid(TextBox2.Text, 4)) \ Asc(Mid(TextBox2.Text, 5))
End If
If Key1 <> Key2 Then
MsgBox("Wrong!", , "OutCome")
Else
MsgBox("Right!", , "Outcome")
End If
End Sub
2.用ILDasm反汇编结果:
.method private instance void Button1_Click(object sender,
class [mscorlib]System.EventArgs e) cil managed
{
// 代码大小 326 (0x146)
.maxstack 4
.locals init (int32 V_0,
int32 V_1,
int32 V_2,
int32 V_3,
int32 V_4)
IL_0000: ldarg.0
IL_0001: callvirt instance class [System.Windows.Forms]System.Windows.Forms.TextBox WindowsApplication2.Form1::get_TextBox1()
IL_0006: callvirt instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()
IL_000b: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Len(string)
IL_0010: ldc.i4.6
IL_0011: beq.s IL_0021 ;选择的分支
IL_0013: ldstr "6 Charactor Please."
IL_0018: ldc.i4.0
IL_0019: ldnull
IL_001a: call valuetype [Microsoft.VisualBasic]Microsoft.VisualBasic.MsgBoxResult [Microsoft.VisualBasic]Microsoft.VisualBasic.Interaction::MsgBox(object,
valuetype [Microsoft.VisualBasic]Microsoft.VisualBasic.MsgBoxStyle,
object)
IL_001f: pop
IL_0020: ret
;判断Len(textBox1)=6?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IL_0021: ldarg.0
IL_0022: callvirt instance class [System.Windows.Forms]System.Windows.Forms.TextBox WindowsApplication2.Form1::get_TextBox1()
IL_0027: callvirt instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()
IL_002c: ldc.i4.1
IL_002d: ldc.i4.2
IL_002e: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Mid(string,
int32,
int32)
IL_0033: call float64 [Microsoft.VisualBasic]Microsoft.VisualBasic.Conversion::Val(string)
IL_0038: call float64 [mscorlib]System.Math::Round(float64)
IL_003d: conv.ovf.i4
IL_003e: stloc.0
IL_003f: ldarg.0
IL_0040: callvirt instance class [System.Windows.Forms]System.Windows.Forms.TextBox WindowsApplication2.Form1::get_TextBox1()
IL_0045: callvirt instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()
IL_004a: ldc.i4.3
IL_004b: ldc.i4.2
IL_004c: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Mid(string,
int32,
int32)
IL_0051: call float64 [Microsoft.VisualBasic]Microsoft.VisualBasic.Conversion::Val(string)
IL_0056: call float64 [mscorlib]System.Math::Round(float64)
IL_005b: conv.ovf.i4
IL_005c: stloc.1
IL_005d: ldarg.0
IL_005e: callvirt instance class [System.Windows.Forms]System.Windows.Forms.TextBox WindowsApplication2.Form1::get_TextBox1()
IL_0063: callvirt instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()
IL_0068: ldc.i4.5
IL_0069: ldc.i4.2
IL_006a: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Mid(string,
int32,
int32)
IL_006f: call float64 [Microsoft.VisualBasic]Microsoft.VisualBasic.Conversion::Val(string)
IL_0074: call float64 [mscorlib]System.Math::Round(float64)
IL_0079: conv.ovf.i4
IL_007a: stloc.2
IL_007b: ldloc.0
IL_007c: ldloc.1
IL_007d: ldloc.0
IL_007e: add.ovf
IL_007f: ldloc.2
IL_0080: ldloc.1
IL_0081: sub.ovf
IL_0082: and
IL_0083: or
IL_0084: ldloc.2
IL_0085: xor
IL_0086: stloc.3
IL_0087: ldarg.0
;计算Key1过程
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IL_0088: callvirt instance class [System.Windows.Forms]System.Windows.Forms.TextBox WindowsApplication2.Form1::get_TextBox2()
IL_008d: callvirt instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()
IL_0092: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Len(string)
IL_0097: ldc.i4.5
IL_0098: bge.s IL_00a8
IL_009a: ldstr "5 Charactor least"
IL_009f: ldc.i4.0
IL_00a0: ldnull
IL_00a1: call valuetype [Microsoft.VisualBasic]Microsoft.VisualBasic.MsgBoxResult [Microsoft.VisualBasic]Microsoft.VisualBasic.Interaction::MsgBox(object,
valuetype [Microsoft.VisualBasic]Microsoft.VisualBasic.MsgBoxStyle,
object)
IL_00a6: pop
IL_00a7: ret
;判断Len(textBox2)>5?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IL_00a8: ldarg.0
IL_00a9: callvirt instance class [System.Windows.Forms]System.Windows.Forms.TextBox WindowsApplication2.Form1::get_TextBox2()
IL_00ae: callvirt instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()
IL_00b3: ldc.i4.1
IL_00b4: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Mid(string,
int32)
IL_00b9: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Asc(string)
IL_00be: ldarg.0
IL_00bf: callvirt instance class [System.Windows.Forms]System.Windows.Forms.TextBox WindowsApplication2.Form1::get_TextBox2()
IL_00c4: callvirt instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()
IL_00c9: ldc.i4.2
IL_00ca: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Mid(string,
int32)
IL_00cf: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Asc(string)
IL_00d4: add.ovf
IL_00d5: ldarg.0
IL_00d6: callvirt instance class [System.Windows.Forms]System.Windows.Forms.TextBox WindowsApplication2.Form1::get_TextBox2()
IL_00db: callvirt instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()
IL_00e0: ldc.i4.3
IL_00e1: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Mid(string,
int32)
IL_00e6: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Asc(string)
IL_00eb: ldarg.0
IL_00ec: callvirt instance class [System.Windows.Forms]System.Windows.Forms.TextBox WindowsApplication2.Form1::get_TextBox2()
IL_00f1: callvirt instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()
IL_00f6: ldc.i4.4
IL_00f7: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Mid(string,
int32)
IL_00fc: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Asc(string)
IL_0101: mul.ovf
IL_0102: ldarg.0
IL_0103: callvirt instance class [System.Windows.Forms]System.Windows.Forms.TextBox WindowsApplication2.Form1::get_TextBox2()
IL_0108: callvirt instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()
IL_010d: ldc.i4.5
IL_010e: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Mid(string,
int32)
IL_0113: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Asc(string)
IL_0118: div
IL_0119: sub.ovf
IL_011a: stloc.s V_4
;计算Key2过程
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IL_011c: ldloc.3
IL_011d: ldloc.s V_4
IL_011f: beq.s IL_0134
IL_0121: ldstr "Wrong!"
IL_0126: ldc.i4.0
IL_0127: ldstr "OutCome"
IL_012c: call valuetype [Microsoft.VisualBasic]Microsoft.VisualBasic.MsgBoxResult [Microsoft.VisualBasic]Microsoft.VisualBasic.Interaction::MsgBox(object,
valuetype [Microsoft.VisualBasic]Microsoft.VisualBasic.MsgBoxStyle,
object)
IL_0131: pop
IL_0132: br.s IL_0145
IL_0134: ldstr "Right!"
IL_0139: ldc.i4.0
IL_013a: ldstr "Outcome"
IL_013f: call valuetype [Microsoft.VisualBasic]Microsoft.VisualBasic.MsgBoxResult [Microsoft.VisualBasic]Microsoft.VisualBasic.Interaction::MsgBox(object,
valuetype [Microsoft.VisualBasic]Microsoft.VisualBasic.MsgBoxStyle,
object)
IL_0144: pop
IL_0145: ret
;给出Key1是否与Key2相等的结果
} // end of method Form1::Button1_Click
3.用OD调试的探索:
1)载入程序
将该代码发布为Release版本的EXE,再用OD载入,发现竟然自动运行了。可见在代码入口处自动加断点失败。
看一下都加载了哪些模块:
程序:VBNETP.exe
.NET 框架有关的模块:
c:\windows\assembly\gac\system.drawing\1.0.5000.0__b03f5f7f11d50a3a\system.drawing.dll
c:\windows\assembly\gac\system.windows.forms\1.0.5000.0__b77a5c561934e089\system.windows.forms.dll
c:\windows\assembly\gac\system\1.0.5000.0__b77a5c561934e089\system.dll
c:\windows\assembly\nativeimages1_v1.1.4322\mscorlib\1.0.5000.0__b77a5c561934e089_1632d567\mscorlib.dll
c:\windows\assembly\nativeimages1_v1.1.4322\system.drawing\1.0.5000.0__b03f5f7f11d50a3a_a385384c\system.drawing.dll
c:\windows\assembly\nativeimages1_v1.1.4322\system.windows.forms\1.0.5000.0__b77a5c561934e089_d4ca4918\system.windows.forms.dll
c:\windows\assembly\nativeimages1_v1.1.4322\system\1.0.5000.0__b77a5c561934e089_e82d0b10\system.dll
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\fusion.dll
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\MSCORJIT.DLL
c:\windows\microsoft.net\framework\v1.1.4322\mscorlib.dll
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\mscorsn.dll
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\mscorwks.dll
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\MSVCR71.dll
C:\WINDOWS\system32\mscoree.dll
其他模块:
C:\WINDOWS\system32\ADVAPI32.dll
C:\WINDOWS\system32\comctl32.dll
C:\WINDOWS\system32\GDI32.dll
C:\WINDOWS\system32\IMM32.DLL
C:\WINDOWS\system32\KERNEL32.dll
C:\WINDOWS\system32\LPK.DLL
C:\WINDOWS\system32\MSCTF.dll
C:\WINDOWS\system32\msctfime.ime
C:\WINDOWS\system32\msvcrt.dll
C:\WINDOWS\system32\ntdll.dll
C:\WINDOWS\system32\ole32.dll
C:\WINDOWS\system32\RPCRT4.dll
C:\WINDOWS\system32\SHELL32.dll
C:\WINDOWS\system32\SHLWAPI.dll
C:\WINDOWS\system32\USER32.dll
C:\WINDOWS\system32\USP10.dll
C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2180_x-ww_a84f1ff9\comctl32.dll
C:\WINDOWS\WinSxS\x86_Microsoft.Windows.GdiPlus_6595b64144ccf1df_1.0.2600.2180_x-ww_522f9f82\gdiplus.dll
首先查看VBNETP.exe的代码,分析一下,好像没什么有用的信息,但有一条命令值得关注:
11004A5E > $- FF25 00200011 JMP DWORD PTR DS:[<&mscoree._CorExeMain>>; mscoree._CorExeMain
这大概就是入口了。mscoree可能是解释器或虚拟机之类的模块,类似于VB6的MSVBVM60.dll。
进去看看,得却挺像的,以后在调试.NET程序时在这里下断点,载入后就不会自动运行了。
79011B2B > $ 55 PUSH EBP
79011B2C . 8BEC MOV EBP,ESP
79011B2E . 51 PUSH ECX
79011B2F . 56 PUSH ESI
79011B30 . 6A 00 PUSH 0
79011B32 . 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4]
79011B35 . 50 PUSH EAX
79011B36 . 6A 01 PUSH 1
79011B38 . E8 051DFFFF CALL mscoree.79003842
79011B3D . 8BF0 MOV ESI,EAX
79011B3F . 85F6 TEST ESI,ESI
79011B41 . 0F8C 06800000 JL mscoree.79019B4D
79011B47 . 68 641B0179 PUSH mscoree.79011B64 ; /ProcNameOrOrdinal = "_CorExeMain"
79011B4C . FF75 FC PUSH DWORD PTR SS:[EBP-4] ; |hModule
79011B4F . FF15 20100079 CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; \GetProcAddress
79011B55 . 85C0 TEST EAX,EAX
79011B57 . 0F84 E97F0000 JE mscoree.79019B46
79011B5D . FFD0 CALL EAX
79011B5F > 5E POP ESI
79011B60 . C9 LEAVE
79011B61 . C3 RETN
2)下断分析
由于在源程序中有对话框,在一些user32.dll中敏感的地方设置断点。不输入任何信息直接按按钮,程序被中断。
77D50559 >/$ 8BFF MOV EDI,EDI ;断在此处
77D5055B |. 55 PUSH EBP
77D5055C |. 8BEC MOV EBP,ESP
77D5055E |. 6A FF PUSH -1 ; /Arg6 = FFFFFFFF
77D50560 |. FF75 18 PUSH DWORD PTR SS:[EBP+18] ; |Arg5
77D50563 |. FF75 14 PUSH DWORD PTR SS:[EBP+14] ; |Arg4
77D50566 |. FF75 10 PUSH DWORD PTR SS:[EBP+10] ; |Arg3
77D50569 |. FF75 0C PUSH DWORD PTR SS:[EBP+C] ; |Arg2
77D5056C |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |Arg1
77D5056F |. E8 F1590100 CALL USER32.MessageBoxTimeoutW ; \MessageBoxTimeoutW
77D50574 |. 5D POP EBP
77D50575 \. C2 1400 RETN 14
堆栈的内容:
0012F18C 77D6615B /CALL 到 MessageBoxExW 来自 USER32.77D66156
0012F190 000B01D6 |hOwner = 000B01D6 ('Form1',class='WindowsForms10.Window.8.app3')
0012F194 05173A08 |Text = "6 Charactor Please."
0012F198 051746F0 |Title = "WindowsApplication2"
0012F19C 00000000 |Style = MB_OK|MB_APPLMODAL
0012F1A0 00000000 \LanguageID = 0 (LANG_NEUTRAL)
0012F1A4 /0012F240
0012F1A8 |01060F5F 返回到 01060F5F
0012F1AC |000B01D6
0012F1B0 |05173A08 UNICODE "6 Charactor Please." <--这个地方可以跟进看看
0012F1B4 |051746F0 UNICODE "WindowsApplication2"
0012F1B8 |00000000
0012F1BC |051746E4
0012F1C0 |051739FC
0012F1C4 |001597D8 ASCII " `"
0012F1C8 |000B01D6
0012F1CC |00000000
然后在第一个框内输入123456,第二个框空着,点按钮,程序又被断下来了,看到堆栈:
0012F18C 77D6615B /CALL 到 MessageBoxExW 来自 USER32.77D66156
0012F190 000B01D6 |hOwner = 000B01D6 ('Form1',class='WindowsForms10.Window.8.app3')
0012F194 05173A40 |Text = "5 Charactor least"
0012F198 0517AE8C |Title = "WindowsApplication2"
0012F19C 00000000 |Style = MB_OK|MB_APPLMODAL
0012F1A0 00000000 \LanguageID = 0 (LANG_NEUTRAL)
0012F1A4 /0012F240
0012F1A8 |01060F5F 返回到 01060F5F
0012F1AC |000B01D6
0012F1B0 |05173A40 UNICODE "5 Charactor least" <--在内存中跟入
0012F1B4 |0517AE8C UNICODE "WindowsApplication2"
0012F1B8 |00000000
跟入到05打头的内存中,搜索UNICODE形式的"123456",发现有三处可疑之处:
0517A790 31 00 32 00 33 00 34 00 35 00 36 00 00 00 00 00 123456..
0517A7A0 00 00 00 00 F4 F4 B7 79 B8 A7 17 05 00 00 00 00 ..夺Ꞹԗ..
0517A7B0 FF FF FF 7F 00 00 00 00 F8 DA B7 79 08 00 00 00 .乱..夺.
0517A7C0 06 00 00 00 31 00 32 00 33 00 34 00 35 00 36 00 .123456
0517A7D0 00 00 00 00 00 00 00 80 F8 DA B7 79 11 00 00 00 ...耀夺.
0517A8B4 31 00 32 00 33 00 34 00 35 00 36 00 00 00 00 00 123456..
0517A8C4 00 00 00 00 F8 DA B7 79 03 00 00 00 02 00 00 00 ..夺..
0517A8D4 33 00 34 00 00 00 00 00 00 00 00 00 F4 F4 B7 79 34....夺
0517A8E4 F4 A8 17 05 00 00 00 00 FF FF FF 7F 00 00 00 00 ꣴԗ...乱..
0517A8F4 F8 DA B7 79 08 00 00 00 06 00 00 00 31 00 32 00 夺..12
0517A904 33 00 34 00 35 00 36 00 00 00 00 00 00 00 00 00 3456....
0517A914 F8 DA B7 79 03 00 00 00 02 00 00 00 35 00 36 00 夺..56
设置内存断点,没有一处能断,太失败了。只有一句一句跟了,来到这里,发现了有趣的代码:
00E60A90 99 CDQ
00E60A91 8B4D EC MOV ECX,DWORD PTR SS:[EBP-14]
00E60A94 F7F9 IDIV ECX ;竟然有个除法
00E60A96 8B55 F0 MOV EDX,DWORD PTR SS:[EBP-10]
00E60A99 2BD0 SUB EDX,EAX
00E60A9B 70 36 JO SHORT 00E60AD3
00E60A9D 3955 F4 CMP DWORD PTR SS:[EBP-C],EDX
00E60AA0 74 16 JE SHORT 00E60AB8
往上翻几页,又看到了这段:
00E6086F FF90 E4000000 CALL DWORD PTR DS:[EAX+E4]
00E60875 8BC8 MOV ECX,EAX
00E60877 FF15 5073A000 CALL DWORD PTR DS:[A07350]
00E6087D 83F8 06 CMP EAX,6 ;textBox1要求的长度
00E60880 74 17 JE SHORT 00E60899
00E60882 6A 00 PUSH 0
00E60884 8B0D 04171506 MOV ECX,DWORD PTR DS:[6151704]
00E6088A 33D2 XOR EDX,EDX
00E6088C FF15 AC79A000 CALL DWORD PTR DS:[A079AC]
00E60892 5E POP ESI
00E60893 8BE5 MOV ESP,EBP
00E60895 5D POP EBP
00E60896 C2 0400 RETN 4
3)找到关键代码
因此可以断定这就是程序汇编代码所在,但是,OD却提示在代码范围之外,最终确定相关的程序代码如下:
00E60854 68 54A00055 PUSH 5500A054
00E60859 8BEC MOV EBP,ESP ;这里可以下断点,上一句下断点会出异常
00E6085B 83EC 18 SUB ESP,18
00E6085E 56 PUSH ESI
00E6085F 8BF1 MOV ESI,ECX
00E60861 8BCE MOV ECX,ESI
00E60863 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E60865 FF90 98050000 CALL DWORD PTR DS:[EAX+598]
00E6086B 8BC8 MOV ECX,EAX
00E6086D 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E6086F FF90 E4000000 CALL DWORD PTR DS:[EAX+E4]
00E60875 8BC8 MOV ECX,EAX
00E60877 FF15 5073A000 CALL DWORD PTR DS:[A07350]
00E6087D 83F8 06 CMP EAX,6
00E60880 74 17 JE SHORT 00E60899
00E60882 6A 00 PUSH 0
00E60884 8B0D 04171506 MOV ECX,DWORD PTR DS:[6151704]
00E6088A 33D2 XOR EDX,EDX
00E6088C FF15 AC79A000 CALL DWORD PTR DS:[A079AC]
00E60892 5E POP ESI
00E60893 8BE5 MOV ESP,EBP
00E60895 5D POP EBP
00E60896 C2 0400 RETN 4
;;判断Len(textBox1)=6?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00E60899 8BCE MOV ECX,ESI
00E6089B 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E6089D FF90 98050000 CALL DWORD PTR DS:[EAX+598]
00E608A3 8BC8 MOV ECX,EAX
00E608A5 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E608A7 FF90 E4000000 CALL DWORD PTR DS:[EAX+E4]
00E608AD 6A 02 PUSH 2
00E608AF 8BC8 MOV ECX,EAX
00E608B1 BA 01000000 MOV EDX,1
00E608B6 FF15 EC73A000 CALL DWORD PTR DS:[A073EC]
00E608BC 8BC8 MOV ECX,EAX
00E608BE FF15 4C77A000 CALL DWORD PTR DS:[A0774C]
00E608C4 D9FC FRNDINT
00E608C6 83EC 08 SUB ESP,8
00E608C9 DD1C24 FSTP QWORD PTR SS:[ESP]
00E608CC E8 FA143578 CALL mscorwks.791B1DCB
00E608D1 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
;a1 = Val(Mid(TextBox1.Text, 1, 2))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00E608D4 8BCE MOV ECX,ESI
00E608D6 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E608D8 FF90 98050000 CALL DWORD PTR DS:[EAX+598]
00E608DE 8BC8 MOV ECX,EAX
00E608E0 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E608E2 FF90 E4000000 CALL DWORD PTR DS:[EAX+E4]
00E608E8 6A 02 PUSH 2
00E608EA 8BC8 MOV ECX,EAX
00E608EC BA 03000000 MOV EDX,3
00E608F1 FF15 EC73A000 CALL DWORD PTR DS:[A073EC]
00E608F7 8BC8 MOV ECX,EAX
00E608F9 FF15 4C77A000 CALL DWORD PTR DS:[A0774C]
00E608FF D9FC FRNDINT
00E60901 83EC 08 SUB ESP,8
00E60904 DD1C24 FSTP QWORD PTR SS:[ESP]
00E60907 E8 BF143578 CALL mscorwks.791B1DCB
00E6090C 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
;a2 = Val(Mid(TextBox1.Text, 3, 2))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00E6090F 8BCE MOV ECX,ESI
00E60911 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E60913 FF90 98050000 CALL DWORD PTR DS:[EAX+598]
00E60919 8BC8 MOV ECX,EAX
00E6091B 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E6091D FF90 E4000000 CALL DWORD PTR DS:[EAX+E4]
00E60923 6A 02 PUSH 2
00E60925 8BC8 MOV ECX,EAX
00E60927 BA 05000000 MOV EDX,5
00E6092C FF15 EC73A000 CALL DWORD PTR DS:[A073EC]
00E60932 8BC8 MOV ECX,EAX
00E60934 FF15 4C77A000 CALL DWORD PTR DS:[A0774C]
00E6093A D9FC FRNDINT
00E6093C 83EC 08 SUB ESP,8
00E6093F DD1C24 FSTP QWORD PTR SS:[ESP]
00E60942 E8 84143578 CALL mscorwks.791B1DCB
00E60947 8BC8 MOV ECX,EAX
;a3 = Val(Mid(TextBox1.Text, 5, 2))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00E60949 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
00E6094C 0345 FC ADD EAX,DWORD PTR SS:[EBP-4]
00E6094F 0F80 7E010000 JO 00E60AD3
00E60955 8BD1 MOV EDX,ECX
00E60957 2B55 F8 SUB EDX,DWORD PTR SS:[EBP-8]
00E6095A 0F80 73010000 JO 00E60AD3
00E60960 23C2 AND EAX,EDX
00E60962 0B45 FC OR EAX,DWORD PTR SS:[EBP-4]
00E60965 33C1 XOR EAX,ECX
00E60967 8945 F4 MOV DWORD PTR SS:[EBP-C],EAX
;计算Key1 = a1 Or a2 + a1 And a3 - a2 Xor a3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00E6096A 8BCE MOV ECX,ESI
00E6096C 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E6096E FF90 AC050000 CALL DWORD PTR DS:[EAX+5AC]
00E60974 8BC8 MOV ECX,EAX
00E60976 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E60978 FF90 E4000000 CALL DWORD PTR DS:[EAX+E4]
00E6097E 8BC8 MOV ECX,EAX
00E60980 FF15 5073A000 CALL DWORD PTR DS:[A07350]
00E60986 83F8 05 CMP EAX,5
00E60989 7D 17 JGE SHORT 00E609A2
00E6098B 6A 00 PUSH 0
00E6098D 8B0D 08171506 MOV ECX,DWORD PTR DS:[6151708]
00E60993 33D2 XOR EDX,EDX
00E60995 FF15 AC79A000 CALL DWORD PTR DS:[A079AC]
00E6099B 5E POP ESI
00E6099C 8BE5 MOV ESP,EBP
00E6099E 5D POP EBP
00E6099F C2 0400 RETN 4
;判断Len(textBox2)>5?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00E609A2 8BCE MOV ECX,ESI
00E609A4 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E609A6 FF90 AC050000 CALL DWORD PTR DS:[EAX+5AC]
00E609AC 8BC8 MOV ECX,EAX
00E609AE 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E609B0 FF90 E4000000 CALL DWORD PTR DS:[EAX+E4]
00E609B6 8BC8 MOV ECX,EAX
00E609B8 BA 01000000 MOV EDX,1
00E609BD FF15 E873A000 CALL DWORD PTR DS:[A073E8]
00E609C3 8BC8 MOV ECX,EAX
00E609C5 FF15 0C73A000 CALL DWORD PTR DS:[A0730C]
;Asc(Mid(TextBox2.Text, 1))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00E609CB 8BCE MOV ECX,ESI
00E609CD 8945 F0 MOV DWORD PTR SS:[EBP-10],EAX
00E609D0 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E609D2 FF90 AC050000 CALL DWORD PTR DS:[EAX+5AC]
00E609D8 8BC8 MOV ECX,EAX
00E609DA 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E609DC FF90 E4000000 CALL DWORD PTR DS:[EAX+E4]
00E609E2 8BC8 MOV ECX,EAX
00E609E4 BA 02000000 MOV EDX,2
00E609E9 FF15 E873A000 CALL DWORD PTR DS:[A073E8]
00E609EF 8BC8 MOV ECX,EAX
00E609F1 FF15 0C73A000 CALL DWORD PTR DS:[A0730C]
;Asc(Mid(TextBox2.Text, 2))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00E609F7 0345 F0 ADD EAX,DWORD PTR SS:[EBP-10]
;v1=Asc(Mid(TextBox2.Text, 1))+Asc(Mid(TextBox2.Text, 2))
00E609FA 0F80 D3000000 JO 00E60AD3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00E60A00 8BCE MOV ECX,ESI
00E60A02 8945 F0 MOV DWORD PTR SS:[EBP-10],EAX
00E60A05 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E60A07 FF90 AC050000 CALL DWORD PTR DS:[EAX+5AC]
00E60A0D 8BC8 MOV ECX,EAX
00E60A0F 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E60A11 FF90 E4000000 CALL DWORD PTR DS:[EAX+E4]
00E60A17 8BC8 MOV ECX,EAX
00E60A19 BA 03000000 MOV EDX,3
00E60A1E FF15 E873A000 CALL DWORD PTR DS:[A073E8]
00E60A24 8BC8 MOV ECX,EAX
00E60A26 FF15 0C73A000 CALL DWORD PTR DS:[A0730C]
;Asc(Mid(TextBox2.Text, 3))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00E60A2C 8BCE MOV ECX,ESI
00E60A2E 8945 E8 MOV DWORD PTR SS:[EBP-18],EAX
00E60A31 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E60A33 FF90 AC050000 CALL DWORD PTR DS:[EAX+5AC]
00E60A39 8BC8 MOV ECX,EAX
00E60A3B 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E60A3D FF90 E4000000 CALL DWORD PTR DS:[EAX+E4]
00E60A43 8BC8 MOV ECX,EAX
00E60A45 BA 04000000 MOV EDX,4
00E60A4A FF15 E873A000 CALL DWORD PTR DS:[A073E8]
00E60A50 8BC8 MOV ECX,EAX
00E60A52 FF15 0C73A000 CALL DWORD PTR DS:[A0730C]
;Asc(Mid(TextBox2.Text, 4))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00E60A58 0FAF45 E8 IMUL EAX,DWORD PTR SS:[EBP-18]
00E60A5C 70 75 JO SHORT 00E60AD3
;v2=Asc(Mid(TextBox2.Text, 3))*Asc(Mid(TextBox2.Text, 4))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00E60A5E 8BCE MOV ECX,ESI
00E60A60 8945 E8 MOV DWORD PTR SS:[EBP-18],EAX
00E60A63 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E60A65 FF90 AC050000 CALL DWORD PTR DS:[EAX+5AC]
00E60A6B 8BC8 MOV ECX,EAX
00E60A6D 8B01 MOV EAX,DWORD PTR DS:[ECX]
00E60A6F FF90 E4000000 CALL DWORD PTR DS:[EAX+E4]
00E60A75 8BC8 MOV ECX,EAX
00E60A77 BA 05000000 MOV EDX,5
00E60A7C FF15 E873A000 CALL DWORD PTR DS:[A073E8]
00E60A82 8BC8 MOV ECX,EAX
00E60A84 FF15 0C73A000 CALL DWORD PTR DS:[A0730C]
;Asc(Mid(TextBox2.Text, 5))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00E60A8A 8945 EC MOV DWORD PTR SS:[EBP-14],EAX
00E60A8D 8B45 E8 MOV EAX,DWORD PTR SS:[EBP-18]
00E60A90 99 CDQ
00E60A91 8B4D EC MOV ECX,DWORD PTR SS:[EBP-14]
00E60A94 F7F9 IDIV ECX
;v3=v2\Asc(Mid(TextBox2.Text, 5))
00E60A96 8B55 F0 MOV EDX,DWORD PTR SS:[EBP-10]
00E60A99 2BD0 SUB EDX,EAX
;Key2=v1-v3
00E60A9B 70 36 JO SHORT 00E60AD3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00E60A9D 3955 F4 CMP DWORD PTR SS:[EBP-C],EDX ;比较Key1与Key2是否相等
00E60AA0 74 16 JE SHORT 00E60AB8
;不相等处理
00E60AA2 FF35 10171506 PUSH DWORD PTR DS:[6151710]
00E60AA8 8B0D 0C171506 MOV ECX,DWORD PTR DS:[615170C]
00E60AAE 33D2 XOR EDX,EDX
00E60AB0 FF15 AC79A000 CALL DWORD PTR DS:[A079AC]
00E60AB6 EB 14 JMP SHORT 00E60ACC
;相等处理
00E60AB8 FF35 18171506 PUSH DWORD PTR DS:[6151718]
00E60ABE 8B0D 14171506 MOV ECX,DWORD PTR DS:[6151714]
00E60AC4 33D2 XOR EDX,EDX
00E60AC6 FF15 AC79A000 CALL DWORD PTR DS:[A079AC]
00E60ACC 5E POP ESI
00E60ACD 8BE5 MOV ESP,EBP
00E60ACF 5D POP EBP
00E60AD0 C2 0400 RETN 4
4.总结与评价
通过上面例子的调试分析,发现OllyDBG在.NET程序面前显得不太适合,.NET的程序类似于加壳程序,动态解释代码,而且关键部分代码无法用OD分析,还是要靠人的能力。
在动态调试时,可在虚拟机的入口处设断,以帮助分析程序启动流程。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)