【文章标题】: 海狼三人组CrackMe分析过程
【文章作者】: 书呆彭
【下载地址】: http://bbs.pediy.com/showthread.php?t=78925
【编写语言】: VB
【使用工具】: OD
【操作平台】: Windows XP x64 SP2
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
----------------------8<-----------------------------------------------------------------------
【详细过程】
通常,对于VB编译器生成的东西,我称之为“又臭又长”,不喜欢动它。
幸好,有个VB Decompiler,能省去不少麻烦事。
不过这个工具对于有些VB的程序不认识,比如这个CrackMe。所以,不得已,只能硬着头皮去看这“又臭又长”的代码了。
这句是写完后补上的:写完后才发现实在是太长了,不知道有没有人愿意把它看完。
书归正文,直入主题。
整个分析过程有这么几个步骤
------------------------8<------------------------------------------------------------------------
1.由于程序通过创建子进程来脱离调试的管辖,要先过了这一关。
VB是UNICODE的,所以下W版本的API断点:
bp CreateProcessW
断下来,看堆栈:
0013F584 660CCEBF /CALL 到 CreateProcessW 来自 MSVBVM60.660CCEB9
0013F588 00000000 |ModuleFileName = NULL
0013F58C 0023BE74 |CommandLine = "F:\Debugee\Crack Me\021.exe"
0013F590 00000000 |pProcessSecurity = NULL
0013F594 00000000 |pThreadSecurity = NULL
0013F598 00000000 |InheritHandles = FALSE
0013F59C 00000000 |CreationFlags = 0
0013F5A0 00000000 |pEnvironment = NULL
0013F5A4 00000000 |CurrentDir = NULL
0013F5A8 0013F5BC |pStartupInfo = 0013F5BC
0013F5AC 0013F600 \pProcessInfo = 0013F600
0013F5B0 660FEA4C MSVBVM60.__vbaFreeVar
0013F5B4 00000008
0013F5B8 660DC1FB MSVBVM60.rtcRandomize
0013F5BC 00000044
0013F5C0 00000000
0013F5C4 00000000
0013F5C8 00000000
0013F5CC 00000000
0013F5D0 00000000
0013F5D4 00000000
0013F5D8 00000000
0013F5DC 00000000
0013F5E0 00000000
0013F5E4 00000000
0013F5E8 00000001
0013F5EC 00000001
0013F5F0 00000000
0013F5F4 00000000
0013F5F8 00000000
0013F5FC 00000000
0013F600 00000007
0013F604 00FACFA9
0013F608 00000000
0013F60C 0013F6FC
0013F610 /0013F6FC
0013F614 |0040FC1F 返回到 021.0040FC1F 来自 MSVBVM60.rtcShell -> 鼠标点一下这里,按回车
0040FBF6 > \>FLD QWORD PTR SS:[EBP-44]
0040FBF9 . >FCOMP QWORD PTR DS:[401328]
0040FBFF . >FSTSW AX
0040FC01 . >TEST AH, 41
0040FC04 . />JNZ SHORT 021.0040FC29
0040FC06 . |>LEA ECX, DWORD PTR SS:[EBP-48]
0040FC09 . |>MOV DWORD PTR SS:[EBP-78], ECX
0040FC0C . |>MOV DWORD PTR SS:[EBP-80], 4008
0040FC13 . |>PUSH 1
0040FC15 . |>LEA EDX, DWORD PTR SS:[EBP-80]
0040FC18 . |>PUSH EDX
0040FC19 . |>CALL DWORD PTR DS:[<&MSVBVM60.#600>] ; MSVBVM60.rtcShell
0040FC1F . |>FSTP ST ; 这里就是堆栈中看到的返回地址
0040FC21 . |>JMP SHORT 021.0040FC23
0040FC23 > |>CALL DWORD PTR DS:[<&MSVBVM60.__vbaEnd>] ; MSVBVM60.__vbaEnd
0040FC29 > \>CALL DWORD PTR DS:[<&MSVBVM60.__vbaExitProc>] ; MSVBVM60.__vbaExitProc
0040FC2F . >WAIT
0040FC30 . >PUSH 021.0040FC8E
0040FC35 . >JMP SHORT 021.0040FC6C
...
7D96A753 ClipCursor >MOV EAX, 122C
7D96A758 >LEA EDX, DWORD PTR SS:[ESP+4]
7D96A75C >MOV ECX, 4
7D96A761 >CALL DWORD PTR FS:[C0]
7D96A768 >RETN 4
66106554 ENGINE 输出 __vbaExitEachAry
66106576 ENGINE 输出 __vbaExitEachColl
66106534 ENGINE 输出 __vbaExitEachVar
660E3F0D .text 输出 __vbaExitProc
0013F19C 00409D55 返回到 021.00409D55 来自 MSVBVM60.__vbaExitProc
004092E2 . 8>LEA EDX, DWORD PTR SS:[EBP-38]
004092E5 . >PUSH EDX
004092E6 . >PUSH EDI
004092E7 . >CALL DWORD PTR DS:[ECX+A0]
004092ED . >FCLEX
004092EF . >CMP EAX, EBX
004092F1 . />JGE SHORT 021.00409305
004092F3 . |>PUSH 0A0
004092F8 . |>PUSH 021.00407DCC
004092FD . |>PUSH EDI
004092FE . |>PUSH EAX
004092FF . |>CALL DWORD PTR DS:[<&MSVBVM60.__vbaHr>; MSVBVM60.__vbaHresultCheckObj
00409305 > \>MOV EAX, DWORD PTR SS:[EBP-38]
00409308 . >PUSH EAX ; eax=UNICODE "code"。哈,正是我们的注册码。我们也知道了上面004092E7的call是取得输入,放入[EBP-0x38]
00409309 . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaLe>; MSVBVM60.__vbaLenBstr
0040930F . >XOR ECX, ECX
00409311 . >CMP EAX, 10
00409314 . >SETL CL ; 注册码长度小于0x10(==16)吗?
00409317 . >NEG ECX
00409319 . >MOV EDI, ECX
0040931B . >LEA ECX, DWORD PTR SS:[EBP-38]
0040931E . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaFr>; MSVBVM60.__vbaFreeStr
00409324 . >LEA ECX, DWORD PTR SS:[EBP-40]
00409327 . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaFr>; MSVBVM60.__vbaFreeObj
0040932D . >CMP DI, BX
00409330 . >JE SHORT 021.00409375 ; 小于16,这里不跳,出错。
...
00409330 . />JE SHORT 021.00409375 ; 这回跳了
00409332 . |>MOV EDX, DWORD PTR DS:[ESI]
... | ; 这里省略几行
0040936A . |>CALL DWORD PTR DS:[<&MSVBVM60.__vbaFr>; MSVBVM60.__vbaFreeObj
00409370 . |>JMP 021.00409D4F
00409375 > \>MOV EAX, DWORD PTR DS:[ESI] ; 跳到这里
00409377 . >PUSH ESI ; 继续往下走,略去
004093D0 . >MOV ECX, DWORD PTR SS:[EBP-20]
004093D3 . >PUSH ECX ; ECX = UNICODE "104E0295",是机器码,看到[EBP-20]是机器码
004093D4 . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaLe>; MSVBVM60.__vbaLenBstr
004093DA . >MOV ECX, EAX
004093DC . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaI2>; MSVBVM60.__vbaI2I4
004093E2 . >MOV DWORD PTR SS:[EBP-2A0], EAX ; [epb-0x2a0] = 8,机器码的长度
004093E8 . >MOV EDI, 1 ; for i = 0 to len(machine) step 1 --> 本人对BASIC语法不通,不知道是不是这么写。
004093ED > />CMP DI, WORD PTR SS:[EBP-2A0] ; di为循环变量
004093F4 . |>JG 021.004094A9 ; 循环出口
004093FA . |>MOV DWORD PTR SS:[EBP-48], 1 ; VB“又臭又长”的原因在于,它不是编译期强类型,所以必须在运行时做各种类型相关的处理
00409401 . |>MOV DWORD PTR SS:[EBP-50], 2 ; [ebp-0x50]处的Variable对象的类型是整数型,值即为1
00409408 . |>LEA EDX, DWORD PTR SS:[EBP-20]
0040940B . |>MOV DWORD PTR SS:[EBP-1F8], EDX ; 这是[ebp-200]处的Variable对象的值域,是[EBP-20],即机器码
00409411 . |>MOV DWORD PTR SS:[EBP-200], 4008 ; 4008是Variable中的类型识别域(表示值域部分是指针)
0040941B . |>LEA EAX, DWORD PTR SS:[EBP-50] ; 以后关于Variable对象构造的代码不再解释了
0040941E . |>PUSH EAX ; Arg4 = ebp-50,即立即数1
0040941F . |>MOVSX ECX, DI
00409422 . |>PUSH ECX ; Arg3 = i,循环变量
00409423 . |>LEA EDX, DWORD PTR SS:[EBP-200]
00409429 . |>PUSH EDX ; Arg2 = ebp-200,机器码
0040942A . |>LEA EAX, DWORD PTR SS:[EBP-60]
0040942D . |>PUSH EAX ; Arg1 = ebp-60,注意这个参数是out参数
0040942E . |>CALL DWORD PTR DS:[<&MSVBVM60.#632>] ; MSVBVM60.rtcMidCharVar
00409434 . |>MOV ECX, DWORD PTR SS:[EBP-34] ; 以上“又臭又长”的代码完成的只是个machinecode[i]的功能,C++编译器生成的代码用三五条指令就完成
00409437 . |>PUSH ECX ; 这个变量需要注意一下,记住它的偏移是0x34
00409438 . |>LEA EDX, DWORD PTR SS:[EBP-60] ; machinecode[i]
0040943B . |>PUSH EDX
0040943C . |>LEA EAX, DWORD PTR SS:[EBP-38] ; 注意ebp-38实际是个临时变量,这里用来接收结果,已经不再指向输入的注册码,释放对象的代码省略了。
0040943F . |>PUSH EAX
00409440 . |>CALL DWORD PTR DS:[<&MSVBVM60.__vbaSt>; MSVBVM60.__vbaStrVarVal
00409446 . |>PUSH EAX
00409447 . |>CALL DWORD PTR DS:[<&MSVBVM60.#516>] ; MSVBVM60.rtcAnsiValueBstr
0040944D . |>PUSH EAX
0040944E . |>CALL DWORD PTR DS:[<&MSVBVM60.__vbaSt>; MSVBVM60.__vbaStrI2
00409454 . |>MOV EDX, EAX ; 这里eax指向UNICODE“49”,这是??? 其实就是code[0]的ASCII值的10进制。
00409456 . |>LEA ECX, DWORD PTR SS:[EBP-3C]
00409459 . |>CALL DWORD PTR DS:[<&MSVBVM60.__vbaSt>; MSVBVM60.__vbaStrMove
0040945F . |>PUSH EAX ; 和谁strcat??? 注意上面我说的ebp-0x34。
00409460 . |>CALL DWORD PTR DS:[<&MSVBVM60.__vbaSt>; MSVBVM60.__vbaStrCat
00409466 . |>MOV EDX, EAX
00409468 . |>LEA ECX, DWORD PTR SS:[EBP-34] ; cat后再存回ebp-0x34
0040946B . |>CALL DWORD PTR DS:[<&MSVBVM60.__vbaSt>; MSVBVM60.__vbaStrMove
00409471 . |>LEA ECX, DWORD PTR SS:[EBP-3C] ; 下面几条指令不用看了。这也是VB“又臭又长”的表现。
00409474 . |>PUSH ECX ; 我们已经弄清了这个循环的过程是把机器码的每一个字符转换成它的ASCII码十进制形式
00409475 . |>LEA EDX, DWORD PTR SS:[EBP-38] ; 结果存放在ebp-0x34这个变量。
00409478 . |>PUSH EDX
00409479 . |>PUSH 2
0040947B . |>CALL DWORD PTR DS:[<&MSVBVM60.__vbaFr>; MSVBVM60.__vbaFreeStrList
00409481 . |>LEA EAX, DWORD PTR SS:[EBP-60]
00409484 . |>PUSH EAX
00409485 . |>LEA ECX, DWORD PTR SS:[EBP-50]
00409488 . |>PUSH ECX
00409489 . |>PUSH 2
0040948B . |>CALL DWORD PTR DS:[<&MSVBVM60.__vbaFr>; MSVBVM60.__vbaFreeVarList
00409491 . |>ADD ESP, 18
00409494 . |>MOV EAX, 1
00409499 . |>ADD AX, DI
0040949C . |>JO 021.00409E73
004094A2 . |>MOV EDI, EAX
004094A4 .^\>JMP 021.004093ED ; 循环
004094A9 > >LEA EDX, DWORD PTR SS:[EBP-34] ; 循环结束后来到这里。
0013F44C 002501BC UNICODE "4948526948505753"
0013F450 00000018
0013F454 00000018
0013F458 00000000
0013F45C 00010000 UNICODE "=::=::\"
0013F460 00292684 UNICODE "104E0295"
0013F464 0013F9BC 指向下一个 SEH 记录的指针
0013F468 00401496 SE处理程序
0013F46C 0013F1A0
0013F470 00401210 021.00401210
004094A9 > \>LEA EDX, DWORD PTR SS:[EBP-34] ; 循环结束
004094AC . >MOV DWORD PTR SS:[EBP-1F8], EDX
004094B2 . >MOV DWORD PTR SS:[EBP-200], 4008
004094BC . >PUSH 8 ; arg3 = 8
004094BE . >LEA EAX, DWORD PTR SS:[EBP-200] ; +8偏移处的指针指向 UNICODE "4948526948505753"
004094C4 . >PUSH EAX ; arg2 = ASCII_machinecode
004094C5 . >LEA ECX, DWORD PTR SS:[EBP-50]
004094C8 . >PUSH ECX ; arg1 = ebp-50,out参数
004094C9 . >CALL DWORD PTR DS:[<&MSVBVM60.#617>] ; MSVBVM60.rtcLeftCharVar
004094CF . >LEA EDX, DWORD PTR SS:[EBP-50] ; [ebp-50] = ASCII_machine的前8位
004094D2 . >PUSH EDX
004094D3 . >LEA EAX, DWORD PTR SS:[EBP-38]
004094D6 . >PUSH EAX
004094D7 . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrVarVal>] ; MSVBVM60.__vbaStrVarVal
004094DD . >PUSH EAX
004094DE . >CALL DWORD PTR DS:[<&MSVBVM60.#581>] ; MSVBVM60.rtcR8ValFromBstr
004094E4 . >FSTP QWORD PTR SS:[EBP-30] ; 看一下浮点寄存器窗口,返回值是49485269.00000
004094E7 . >LEA ECX, DWORD PTR SS:[EBP-38] ; 返回的浮点数存放于ebp-30处,注意是qword
004094EA . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeStr>] ; MSVBVM60.__vbaFreeStr
...
004094A9 > \>LEA EDX, DWORD PTR SS:[EBP-34] ; 循环结束
004094AC . >MOV DWORD PTR SS:[EBP-1F8], EDX
004094B2 . >MOV DWORD PTR SS:[EBP-200], 4008
004094BC . >PUSH 8 ; arg3 = 8
004094BE . >LEA EAX, DWORD PTR SS:[EBP-200] ; +8偏移处的指针指向 UNICODE "4948526948505753"
004094C4 . >PUSH EAX ; arg2 = ASCII_machinecode
004094C5 . >LEA ECX, DWORD PTR SS:[EBP-50]
004094C8 . >PUSH ECX ; arg1 = ebp-50,out参数
004094C9 . >CALL DWORD PTR DS:[<&MSVBVM60.#617>] ; MSVBVM60.rtcLeftCharVar
004094CF . >LEA EDX, DWORD PTR SS:[EBP-50] ; [ebp-50] = ASCII_machine的前8位
004094D2 . >PUSH EDX
004094D3 . >LEA EAX, DWORD PTR SS:[EBP-38]
004094D6 . >PUSH EAX
004094D7 . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrVarVal>] ; MSVBVM60.__vbaStrVarVal
004094DD . >PUSH EAX
004094DE . >CALL DWORD PTR DS:[<&MSVBVM60.#581>] ; MSVBVM60.rtcR8ValFromBstr
004094E4 . >FSTP QWORD PTR SS:[EBP-30] ; 看一下浮点寄存器窗口,返回值是49485269.00000
004094E7 . >LEA ECX, DWORD PTR SS:[EBP-38] ; 返回的浮点数存放于ebp-30处,注意是qword
004094EA . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeStr>] ; MSVBVM60.__vbaFreeStr
004094F0 . >LEA ECX, DWORD PTR SS:[EBP-50]
004094F3 . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeVar>] ; MSVBVM60.__vbaFreeVar
004094F9 . >MOV ECX, DWORD PTR DS:[ESI]
004094FB . >PUSH ESI
004094FC . >CALL DWORD PTR DS:[ECX+304]
00409502 . >PUSH EAX
00409503 . >LEA EDX, DWORD PTR SS:[EBP-40]
00409506 . >PUSH EDX
00409507 . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaObjSet>] ; MSVBVM60.__vbaObjSet
0040950D . >MOV EDI, EAX
0040950F . >MOV EAX, DWORD PTR DS:[EDI]
00409511 . >LEA ECX, DWORD PTR SS:[EBP-38] ; 前面说了,ebp-38充当临时变量
00409514 . >PUSH ECX
00409515 . >PUSH EDI
00409516 . >CALL DWORD PTR DS:[EAX+A0] ; 这次用来接收输入的注册码的值
0040951C . >FCLEX
0040951E . >CMP EAX, EBX
00409520 . />JGE SHORT 021.00409534
00409522 . |>PUSH 0A0
00409527 . |>PUSH 021.00407DCC
0040952C . |>PUSH EDI
0040952D . |>PUSH EAX
0040952E . |>CALL DWORD PTR DS:[<&MSVBVM60.__vbaHresultCheck>; MSVBVM60.__vbaHresultCheckObj
00409534 > \>MOV EAX, DWORD PTR SS:[EBP-38]
00409537 . >MOV DWORD PTR SS:[EBP-38], EBX
0040953A . >MOV DWORD PTR SS:[EBP-48], EAX
0040953D . >MOV DWORD PTR SS:[EBP-50], 8
00409544 . >PUSH 8
00409546 . >LEA EDX, DWORD PTR SS:[EBP-50]
00409549 . >PUSH EDX
0040954A . >LEA EAX, DWORD PTR SS:[EBP-60]
0040954D . >PUSH EAX ; 也取输入注册码的前8位
0040954E . >CALL DWORD PTR DS:[<&MSVBVM60.#617>] ; MSVBVM60.rtcLeftCharVar
00409554 . >LEA ECX, DWORD PTR SS:[EBP-60]
00409557 . >PUSH ECX
00409558 . >LEA EDX, DWORD PTR SS:[EBP-3C]
0040955B . >PUSH EDX
0040955C . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrVarVal>] ; MSVBVM60.__vbaStrVarVal
00409562 . >PUSH EAX ; 前8位由字符串直接转化为浮点数
00409563 . >CALL DWORD PTR DS:[<&MSVBVM60.#581>] ; MSVBVM60.rtcR8ValFromBstr
00409569 . >MOV EDI, DWORD PTR DS:[<&MSVBVM60.__vbaFpI4>] ; 返回值在浮点寄存器中
0040956F . >CALL EDI ; <&MSVBVM60.__vbaFpI4>
00409571 . >MOV EDX, EAX ; __vbaFpI4是把浮点数转化成4字节(即32位)整数,返回值在EAX
00409573 . >FLD QWORD PTR SS:[EBP-30] ; 由机器码前8位转化而来的浮点数
00409576 . >MOV DWORD PTR SS:[EBP-2C8], EDX
0040957C . >CALL EDI ; 也转化成32位整数
0040957E . >MOV ECX, DWORD PTR SS:[EBP-2C8]
00409584 . >XOR ECX, EAX ; 这两个整数(由机器码前8位和由注册码前8位分别转化过来的)进行异或
00409586 . >MOV DWORD PTR SS:[EBP-2CC], ECX ; 结果暂存于ebp-0x2cc
0040958C . >FILD DWORD PTR SS:[EBP-2CC]
00409592 . >FSTP QWORD PTR SS:[EBP-30] ; 这两条指令是再将整型转换为双精度浮点型,还存于ebp-0x30
00409595 . >LEA ECX, DWORD PTR SS:[EBP-3C]
00409598 . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeStr>] ; MSVBVM60.__vbaFreeStr
0040959E . >LEA ECX, DWORD PTR SS:[EBP-40]
004095A1 . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeObj>] ; MSVBVM60.__vbaFreeObj
004095A7 . >LEA EDX, DWORD PTR SS:[EBP-60]
004095AA . >PUSH EDX
004095AB . >LEA EAX, DWORD PTR SS:[EBP-50]
004095AE . >PUSH EAX
004095AF . >PUSH 2
004095B1 . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeVarList>>; MSVBVM60.__vbaFreeVarList
004095B7 . >ADD ESP, 0C
004095BA . >MOV EDI, DWORD PTR SS:[EBP-2C]
004095BD . >PUSH EDI
004095BE . >MOV ECX, DWORD PTR SS:[EBP-30]
004095C1 . >PUSH ECX ; 这两条push实际是压入一个双精度浮点数。
004095C2 . >CALL DWORD PTR DS:[<&MSVBVM60.#587>] ; MSVBVM60.rtcLog
004095C8 . >FSTP QWORD PTR SS:[EBP-28C] ; 取对数,结果存放于[ebp-0x28c],注意也是qword
004095CE . >PUSH EDI
004095CF . >MOV EDX, DWORD PTR SS:[EBP-30]
004095D2 . >PUSH EDX
004095D3 . >CALL DWORD PTR DS:[<&MSVBVM60.#587>] ; MSVBVM60.rtcLog
004095D9 . >FSTP QWORD PTR SS:[EBP-2D4] ; 还是同一个值,存入[ebp-0x2d4]
004095DF . >FLD QWORD PTR SS:[EBP-28C] ; 这是第一次存入的对数值
004095E5 . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaFPFix>] ; 舍入到整数
004095EB . >FSUBR QWORD PTR SS:[EBP-2D4] ; 再减第二次存入的对数值,注意是fsubr,所以是减数,而不是被减数
004095F1 . >FSTP QWORD PTR SS:[EBP-30] ; 剩下的差是小数部分,存入ebp-30
004095F4 . >FSTSW AX
004095F6 . >TEST AL, 0D
004095F8 . >JNZ 021.00409E6E ; 异常检查。注意VB没有使用80x87的硬件异常,而是是软件判断状态位来实现的“软异常”
004095FE . >FLD QWORD PTR SS:[EBP-30] ; 取刚才计算出的小数部分
00409601 . >FMUL QWORD PTR DS:[401238] ; 乘以程序内置的常数,值为1000000000.0000,即10的9次方
00409607 . >FSTP QWORD PTR SS:[EBP-48] ; 结果存放[ebp-0x48]
0040960A . >FSTSW AX
0040960C . >TEST AL, 0D
0040960E . >JNZ 021.00409E6E ; 同上,“软异常”
0040960E . />JNZ 021.00409E6E ; 同上,软异常
00409614 . |>MOV DWORD PTR SS:[EBP-50], 5 ; [ebp-0x50]这个变量的类型域,5表示双精度浮点。
0040961B . |>PUSH 8 ; 取左边8位
0040961D . |>LEA EAX, DWORD PTR SS:[EBP-50] ; 请注意,[ebp-0x50]的值域恰是ebp-0x48
00409620 . |>PUSH EAX ; 现在它的值是 7.1718556708082199100e+16
00409621 . |>LEA ECX, DWORD PTR SS:[EBP-60] ; [ebp-0x60]用来接收结果
00409624 . |>PUSH ECX
00409625 . |>CALL DWORD PTR DS:[<&MSVBVM60.#617>] ; MSVBVM60.rtcLeftCharVar
0040962B . |>LEA EDX, DWORD PTR SS:[EBP-60]
0040962E . |>PUSH EDX
0040962F . |>CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrVarMove>] ; MSVBVM60.__vbaStrVarMove
00409635 . |>MOV EDX, EAX
00409637 . |>LEA ECX, DWORD PTR SS:[EBP-20] ; 最后把高8位转化成的字符串"71718556"存放于[ebp-20]处的变量
0040963A . |>CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrMove>] ; MSVBVM60.__vbaStrMove
00409640 . |>LEA EAX, DWORD PTR SS:[EBP-60]
00409643 . |>PUSH EAX
00409644 . |>LEA ECX, DWORD PTR SS:[EBP-50]
00409647 . |>PUSH ECX
00409648 . |>PUSH 2
0040964A . |>CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeVarList>>; MSVBVM60.__vbaFreeVarList
00409669 . >MOV ECX, DWORD PTR DS:[EDI]
0040966B . >LEA EDX, DWORD PTR SS:[EBP-38] ; 临时变量ebp-0x38再次上场,这次还是用来接收输入的注册码
0040966E . >PUSH EDX
0040966F . >PUSH EDI
00409670 . >CALL DWORD PTR DS:[ECX+A0] ; 取输入的注册码
00409676 . >FCLEX
00409678 . >CMP EAX, EBX
0040967A . >JGE SHORT 021.0040968E
0040967C . >PUSH 0A0
00409681 . >PUSH 021.00407DCC
00409686 . >PUSH EDI
00409687 . >PUSH EAX
00409688 . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaHresultCheck>; MSVBVM60.__vbaHresultCheckObj
0040968E > >MOV EAX, DWORD PTR SS:[EBP-38]
00409691 . >MOV DWORD PTR SS:[EBP-38], EBX
00409694 . >MOV DWORD PTR SS:[EBP-48], EAX ; 如上所说,这里反汇编显示的是[ebp-0x48],而实际变量使用时是ebp-0x50
00409697 . >MOV DWORD PTR SS:[EBP-50], 8
0040969E . >PUSH 8
004096A0 . >LEA EAX, DWORD PTR SS:[EBP-50]
004096A3 . >PUSH EAX
004096A4 . >LEA ECX, DWORD PTR SS:[EBP-60] ; 这次[ebp-0x60]这个变量用来存放输入注册码的最右8位
004096A7 . >PUSH ECX
004096A8 . >CALL DWORD PTR DS:[<&MSVBVM60.#619>] ; MSVBVM60.rtcRightCharVar
004096AE . >MOV EDX, DWORD PTR SS:[EBP-20] ; [ebp-0x20]是什么变量,还记得吧
004096B1 . >MOV DWORD PTR SS:[EBP-1F8], EDX ; 把它放入[ebp-0x200]这个变量的值域
004096B7 . >MOV DWORD PTR SS:[EBP-200], 8008 ; 类型域是8008,不用管它具体是什么意思,只要记住到偏移08处找它真正的值就行了
004096C1 . >LEA EAX, DWORD PTR SS:[EBP-60]
004096C4 . >PUSH EAX
004096C5 . >LEA ECX, DWORD PTR SS:[EBP-200]
004096CB . >PUSH ECX
004096CC . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarTstEq>] ; 比较[ebp-0x200]和[ebp-0x60]是不是相等
004096D2 . >MOV EDI, EAX ; 不相等,返回值为false,即0。结果暂存于edi
004096D4 . >LEA ECX, DWORD PTR SS:[EBP-40]
004096D7 . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeObj>] ; MSVBVM60.__vbaFreeObj
004096DD . >LEA EDX, DWORD PTR SS:[EBP-60]
004096E0 . >PUSH EDX
004096E1 . >LEA EAX, DWORD PTR SS:[EBP-50]
004096E4 . >PUSH EAX
004096E5 . >PUSH 2
004096E7 . >CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeVarList>>; MSVBVM60.__vbaFreeVarList
004096ED . >ADD ESP, 0C
004096F0 . >CMP DI, BX ; 记得di中是什么值吧
004096F3 . >JE SHORT 021.00409724 ; di为0,跳走。
004096F5 . >MOV ECX, DWORD PTR DS:[ESI]
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!