前面曾发过一次,但版主说不怎么简明。加上有些问题没有彻底解决,需要作以补充,所以对原文整理一下,重发上来。没别的意思,纯粹为了交流。
注:大家提到的功能限制的问题已经解决。由于过程比较复杂,所以会紧接着发一个补遗。
Advanced Query Tool V8 的注册分析
平时忙于工作,经常在看雪论坛潜行。现发文一篇,与大家共勉。
Advanced Query Tool(AQT) 是一款专门用于数据库查询设计以及数据查询的工具软件,对于数据分析和数据库程序的编制是十分有用的。某日在www.download.com下载到此软件,便利用业余时间分析之。
该软件的主程序为aqt.exe。用OllyICE加载,发现程序是VB编写的。按F9运行之,首先映入眼帘的就是AQT的欢迎窗口。
该窗口提示着评估版的限制等信息。单击"输入注册码(Enter Registration Key)"按钮,就会看到产品注册窗口。
在注册名(Name)文本框中输入注册名,在注册码(Key)文本框中随便输入一些字符。当输入的注册码有20个及以上的字符时,装入注册码(Load Key)按钮就会被激活。此时单击之,便立即出现注册码错误(Registration key incorrect)的提示。
执行查找参考字符串功能,便会在4CAE64处找到错误提示字符串。不过,OllyICE中显示不出正确的字符串引用地址,只好对错误提示字符串设置内存访问断点。再次单击Load Key按钮,程序就会中断在OLEAUT32的代码空间中。逐级返回,先是MSVBVM60,然后是AQT的9AD078处。向上查看,得知其所在过程开始于9AB447。把原来的内存访问断点去掉,在9AB447处设置断点,就可以正常跟踪、分析了。下面就依据反汇编代码逐步分析之:
009AB447 ... ... ; 做一些准备工作 009AB5C4 ... ... ; 取得RegKey和RegName 009AB6FD and dword ptr [ebp-17C], 0 009AB704 push 0 009AB706 push -1 009AB708 push 1 009AB70A push 004998F0 ; vbNull 009AB70F push 00499674 ; Space 009AB714 push dword ptr [ebp-7C] 009AB717 call <jmp.&MSVBVM60.rtcReplace> ; 去掉RegName中的空格得NewRegName 009AB71C mov edx, eax 009AB71E lea ecx, dword ptr [ebp-80] 009AB721 call <jmp.&MSVBVM60.__vbaStrMove> 009AB726 push eax 009AB727 call <jmp.&MSVBVM60.rtcUpperCaseBstr> ; NewRegName转成大写 009AB72C mov dword ptr [ebp-90], eax 009AB732 mov dword ptr [ebp-98], 8 009AB73C lea eax, dword ptr [ebp-98] 009AB742 push eax 009AB743 lea eax, dword ptr [ebp-A8] 009AB749 push eax 009AB74A call <jmp.&MSVBVM60.rtcTrimVar> ; NewRegName=Trim(NewRegName) 009AB74F lea eax, dword ptr [ebp-A8] 009AB755 push eax 009AB756 call <jmp.&MSVBVM60.__vbaStrVarMove> 009AB75B mov edx, eax 009AB75D lea ecx, dword ptr [ebp-74] 009AB760 call <jmp.&MSVBVM60.__vbaStrMove> ... ... 009AB79A mov dword ptr [ebp-4], 0F 009AB7A1 push dword ptr [ebp-74] 009AB7A4 call <jmp.&MSVBVM60.__vbaLenBstr> ; 取NewRegName的长度 009AB7A9 cmp eax, 3 009AB7AC jge short 009AB7B3 ; 不能小于3 009AB7AE jmp 009AD3D4 009AB7B3 mov dword ptr [ebp-4], 12 009AB7BA mov eax, dword ptr [ebp+8] 009AB7BD mov eax, dword ptr [eax] ; 取得RegKey ... ... ; BCE816始的函数用以将一个字符串去掉连字符后的内容分成字母部分和数字部分 009AB849 lea eax, dword ptr [ebp-30] ; 用以存放RegKey的字母部分(AlphaOfKey) 009AB84C push eax 009AB84D lea eax, dword ptr [ebp-24] ; 用以存放RegKey的数字部分(NumOfKey) 009AB850 push eax 009AB851 lea eax, dword ptr [ebp-80] ; RegKey 009AB854 push eax 009AB855 call 00BCE816 009AB85A lea ecx, dword ptr [ebp-80] 009AB85D call <jmp.&MSVBVM60.__vbaFreeStr> 009AB862 lea ecx, dword ptr [ebp-88] 009AB868 call <jmp.&MSVBVM60.__vbaFreeObj> 009AB86D mov dword ptr [ebp-4], 13 009AB874 push dword ptr [ebp-74] 009AB877 push dword ptr [ebp-30] 009AB87A call <jmp.&MSVBVM60.rtcUpperCaseBstr> ; UCAlphaOfKey=UCase(AlphaOfKey) 009AB87F mov edx, eax 009AB881 lea ecx, dword ptr [ebp-7C] 009AB884 call <jmp.&MSVBVM60.__vbaStrMove> 009AB889 push eax 009AB88A call <jmp.&MSVBVM60.__vbaStrCat> ; NewRegName=NewRegName & UCAlphaOfKey 009AB88F mov edx, eax 009AB891 lea ecx, dword ptr [ebp-74] 009AB894 call <jmp.&MSVBVM60.__vbaStrMove> 009AB899 lea ecx, dword ptr [ebp-7C] 009AB89C call <jmp.&MSVBVM60.__vbaFreeStr> 009AB8A1 mov dword ptr [ebp-4], 14 009AB8A8 push dword ptr [ebp-74] 009AB8AB call <jmp.&MSVBVM60.__vbaLenBstr> 009AB8B0 cmp eax, 14 009AB8B3 jle short 009AB8D0 009AB8B5 mov dword ptr [ebp-4], 15 009AB8BC push 14 009AB8BE push dword ptr [ebp-74] 009AB8C1 call <jmp.&MSVBVM60.rtcRightCharBstr> ; NewRegName长度大于20则从右边取20个字符 009AB8C6 mov edx, eax 009AB8C8 lea ecx, dword ptr [ebp-74] 009AB8CB call <jmp.&MSVBVM60.__vbaStrMove> ; 三个NewRegName连接 009AB8D0 mov dword ptr [ebp-4], 17 009AB8D7 push dword ptr [ebp-74] 009AB8DA push dword ptr [ebp-74] 009AB8DD call <jmp.&MSVBVM60.__vbaStrCat> 009AB8E2 mov edx, eax 009AB8E4 lea ecx, dword ptr [ebp-7C] 009AB8E7 call <jmp.&MSVBVM60.__vbaStrMove> 009AB8EC push eax 009AB8ED push dword ptr [ebp-74] 009AB8F0 call <jmp.&MSVBVM60.__vbaStrCat> 009AB8F5 mov edx, eax 009AB8F7 lea ecx, dword ptr [ebp-80] 009AB8FA call <jmp.&MSVBVM60.__vbaStrMove> 009AB8FF push eax 009AB900 push dword ptr [ebp-74] 009AB903 call <jmp.&MSVBVM60.__vbaStrCat> 009AB908 mov edx, eax 009AB90A lea ecx, dword ptr [ebp-74] 009AB90D call <jmp.&MSVBVM60.__vbaStrMove> 009AB912 lea eax, dword ptr [ebp-80] 009AB915 push eax 009AB916 lea eax, dword ptr [ebp-7C] 009AB919 push eax 009AB91A push 2 009AB91C call <jmp.&MSVBVM60.__vbaFreeStrList> 009AB921 add esp, 0C 009AB924 mov dword ptr [ebp-4], 18 ; 下面这个循环计算NewRegName前20个字符的ASCII值与其序号乘积的累加和 009AB92B mov dword ptr [ebp-13C], 14 ; 循环20次 009AB935 mov dword ptr [ebp-138], 1 009AB93F mov dword ptr [C7D304], 1 009AB949 jmp short 009AB961 009AB94B mov eax, dword ptr [C7D304] 009AB950 add eax, dword ptr [ebp-138] 009AB956 jo 009AD49E 009AB95C mov dword ptr [C7D304], eax 009AB961 mov eax, dword ptr [C7D304] 009AB966 cmp eax, dword ptr [ebp-13C] 009AB96C jg 009ABA4B 009AB972 mov dword ptr [ebp-4], 19 009AB979 mov dword ptr [ebp-90], 1 009AB983 mov dword ptr [ebp-98], 2 009AB98D lea eax, dword ptr [ebp-74] 009AB990 mov dword ptr [ebp-D0], eax 009AB996 mov dword ptr [ebp-D8], 4008 009AB9A0 lea eax, dword ptr [ebp-98] 009AB9A6 push eax 009AB9A7 push dword ptr [C7D304] 009AB9AD lea eax, dword ptr [ebp-D8] 009AB9B3 push eax 009AB9B4 lea eax, dword ptr [ebp-A8] 009AB9BA push eax 009AB9BB call <jmp.&MSVBVM60.rtcMidCharVar> ; 取NewRegName的一个字符 009AB9C0 lea eax, dword ptr [ebp-A8] 009AB9C6 push eax 009AB9C7 lea eax, dword ptr [ebp-7C] 009AB9CA push eax 009AB9CB call <jmp.&MSVBVM60.__vbaStrVarVal> 009AB9D0 push eax 009AB9D1 call <jmp.&MSVBVM60.rtcAnsiValueBstr> ; 取所取字符的ASCII值 009AB9D6 mov word ptr [ebp-10C], ax 009AB9DD mov eax, dword ptr [ebp+8] 009AB9E0 movsx ecx, word ptr [ebp-10C] 009AB9E7 imul ecx, dword ptr [C7D304] ; 与字符序号相乘 009AB9EE jo 009AD49E 009AB9F4 mov dword ptr [ebp-184], ecx 009AB9FA fild dword ptr [ebp-184] 009ABA00 fstp qword ptr [ebp-18C] 009ABA06 fld qword ptr [ebp-18C] 009ABA0C fadd qword ptr [eax+38] 009ABA0F mov ecx, dword ptr [ebp+8] 009ABA12 fstp qword ptr [ecx+38] ; 累加 009ABA15 fstsw ax 009ABA17 test al, 0D 009ABA19 jnz 009AD499 009ABA1F lea ecx, dword ptr [ebp-7C] 009ABA22 call <jmp.&MSVBVM60.__vbaFreeStr> 009ABA27 lea eax, dword ptr [ebp-A8] 009ABA2D push eax 009ABA2E lea eax, dword ptr [ebp-98] 009ABA34 push eax 009ABA35 push 2 009ABA37 call <jmp.&MSVBVM60.__vbaFreeVarList> 009ABA3C add esp, 0C 009ABA3F mov dword ptr [ebp-4], 1A 009ABA46 jmp 009AB94B ; 取得RegName ... ... ; 调用855D81,若AlphaOfKey的后三位字符是"nnn",则返回-1 ; 或者,将RegName去掉空格后转成小写,计算前面最多20个字符与其序号乘积的累加和, ; 用该累加和除以26所得余数为索引,从串"NTKMLQGUZBORYHFCXASPJEVDIW"中取出一个字符, ; 该字符的小写形式与AlphaOfKey的第八个字符的小写形式进行比较,相等则返回-1。 ; 其他情况返回零值。 009ABAED lea eax, dword ptr [ebp-30] ; AlphaOfKey 009ABAF0 push eax 009ABAF1 lea eax, dword ptr [ebp-80] ; RegName 009ABAF4 push eax 009ABAF5 call 00855D81 009ABAFA not ax 009ABAFD mov word ptr [ebp-128], ax ; 返回值取反后保存 009ABB04 lea ecx, dword ptr [ebp-80] 009ABB07 call <jmp.&MSVBVM60.__vbaFreeStr> 009ABB0C lea ecx, dword ptr [ebp-88] 009ABB12 call <jmp.&MSVBVM60.__vbaFreeObj> 009ABB17 movsx eax, word ptr [ebp-128] 009ABB1E test eax, eax 009ABB20 je short 009ABB27 ; 若调用855D81后返回-1则转9ABB27 009ABB22 jmp 009ACEDB ; 否则转9ACEDB(错误提示) 009ABB27 mov dword ptr [ebp-4], 1F 009ABB2E mov dword ptr [ebp-90], 1 009ABB38 mov dword ptr [ebp-98], 2 009ABB42 lea eax, dword ptr [ebp-98] 009ABB48 push eax 009ABB49 push 4 009ABB4B push dword ptr [ebp-30] 009ABB4E call <jmp.&MSVBVM60.rtcMidCharBstr> ; C4OfAlphaOfKey=Mid(AlphaOfKey,4,1) 009ABB53 mov edx, eax 009ABB55 lea ecx, dword ptr [ebp-7C] 009ABB58 call <jmp.&MSVBVM60.__vbaStrMove> 009ABB5D push eax 009ABB5E call <jmp.&MSVBVM60.rtcLowerCaseBstr> ; C4OfAlphaOfKey=LCase(C4OfAlphaOfKey) 009ABB63 mov edx, eax 009ABB65 lea ecx, dword ptr [ebp-70] 009ABB68 call <jmp.&MSVBVM60.__vbaStrMove> 009ABB6D lea ecx, dword ptr [ebp-7C] 009ABB70 call <jmp.&MSVBVM60.__vbaFreeStr> 009ABB75 lea ecx, dword ptr [ebp-98] 009ABB7B call <jmp.&MSVBVM60.__vbaFreeVar> 009ABB80 mov dword ptr [ebp-4], 20 009ABB87 mov edx, dword ptr [ebp-70] 009ABB8A lea ecx, dword ptr [ebp-130] 009ABB90 call <jmp.&MSVBVM60.__vbaStrCopy> ; CopyC4OfAlphaOfKey=C4OfAlphaOfKey 009ABB95 mov dword ptr [ebp-4], 21 009ABB9C push dword ptr [ebp-130] 009ABBA2 push 004AF690 ; "s" 009ABBA7 call <jmp.&MSVBVM60.__vbaStrCmp> ; 与"s"比较 009ABBAC test eax, eax 009ABBAE je short 009ABBC4 ; 是则转到9ABC0A 009ABBB0 push dword ptr [ebp-130] 009ABBB6 push 004AE8E0 ; "x" 009ABBBB call <jmp.&MSVBVM60.__vbaStrCmp> ; 若非"s"则与"x"比较 009ABBC0 test eax, eax 009ABBC2 jnz short 009ABBC8 009ABBC4 jmp short 009ABC0A ; 是则转到9ABC0A 009ABBC6 jmp short 009ABC0A 009ABBC8 mov dword ptr [ebp-4], 23 009ABBCF push dword ptr [ebp-130] 009ABBD5 push 004B02CC ; "u" 009ABBDA call <jmp.&MSVBVM60.__vbaStrCmp> ; 若非"s"、"x"则与"u"比较 009ABBDF test eax, eax 009ABBE1 jnz short 009ABBEA 009ABBE3 jmp 009AC2DA ; 是则转9AC2DA 009ABBE8 jmp short 009ABC0A 009ABBEA mov dword ptr [ebp-4], 25 009ABBF1 push dword ptr [ebp-130] 009ABBF7 push 004AF958 ; "v" 009ABBFC call <jmp.&MSVBVM60.__vbaStrCmp> ; 若非"s"、"x"、"u"则与"v"比较 009ABC01 test eax, eax 009ABC03 jnz short 009ABC0A 009ABC05 jmp 009AC901 ; 是则转9AC901 009ABC0A mov dword ptr [ebp-4], 2B ; 调用9A908B,其中: ; 1、传入的NumOfKey去掉"-",长度不小于20,且必须都是数字 ; 2、去掉"-"的NumOfKey的前10位转成整数VF10,紧接着的10位转成整数VS10 ; 3、VF10除以CheckSumOfName的商,即NumOfKey除以CheckSumOfName的商的高位存入第三个压入堆栈的参数,余数设为R1 ; 4、VT=10000000000*R1+VS10 ; 5、VT除以CheckSumOfName的商,即NumOfKey除以CheckSumOfName的商的低位存入第二个压入堆栈的参数,余数存入第一个压入堆栈的参数 009ABC11 lea eax, dword ptr [ebp-11C] 009ABC17 push eax ; 存放NumOfKey除以CheckSumOfName的余数 009ABC18 push 00C7D3EC ; 存放NumOfKey除以CheckSumOfName的商的低位 009ABC1D push 00C7D3E4 ; 存放NumOfKey除以CheckSumOfName的商的高位 009ABC22 mov eax, dword ptr [ebp+8] 009ABC25 add eax, 38 009ABC28 push eax ; 指向CheckSumOfName 009ABC29 lea eax, dword ptr [ebp-24] ; NumOfKey 009ABC2C push eax 009ABC2D mov eax, dword ptr [ebp+8] 009ABC30 mov eax, dword ptr [eax] 009ABC32 push dword ptr [ebp+8] 009ABC35 call dword ptr [eax+6FC] ; 调用9A908B 009ABC3B mov dword ptr [ebp-120], eax 009ABC41 cmp dword ptr [ebp-120], 0 009ABC48 jge short 009ABC6A 009ABC4A push 6FC 009ABC4F push 004BB72C 009ABC54 push dword ptr [ebp+8] 009ABC57 push dword ptr [ebp-120] 009ABC5D call <jmp.&MSVBVM60.__vbaHresultCheck> 009ABC62 mov dword ptr [ebp-194], eax 009ABC68 jmp short 009ABC71 009ABC6A and dword ptr [ebp-194], 0 009ABC71 fld qword ptr [ebp-11C] 009ABC77 fstp qword ptr [ebp-3C] 009ABC7A mov dword ptr [ebp-4], 2C 009ABC81 fld qword ptr [ebp-3C] 009ABC84 fcomp qword ptr [401CA8] ; 前面调用返回的余数与0比较 009ABC8A fstsw ax 009ABC8C sahf 009ABC8D je short 009ABC9B 009ABC8F mov dword ptr [ebp-198], 1 ; 非零则[ebp-198]w=1 009ABC99 jmp short 009ABCA2 009ABC9B and dword ptr [ebp-198], 0 ; 为零则[ebp-198]w=0 009ABCA2 push dword ptr [ebp-70] 009ABCA5 push 004AF690 009ABCAA call <jmp.&MSVBVM60.__vbaStrCmp> ; C4OfAlphaOfKey与"s"比较 009ABCAF mov esi, eax 009ABCB1 neg esi 009ABCB3 sbb esi, esi 009ABCB5 neg esi 009ABCB7 push dword ptr [ebp-70] 009ABCBA push 004998F0 009ABCBF call <jmp.&MSVBVM60.__vbaStrCmp> ; C4OfAlphaOfKey与空串比较 009ABCC4 neg eax 009ABCC6 sbb eax, eax 009ABCC8 neg eax 009ABCCA and esi, eax 009ABCCC neg esi 009ABCCE sbb esi, esi 009ABCD0 neg esi 009ABCD2 mov eax, dword ptr [ebp-198] 009ABCD8 or eax, esi 009ABCDA test eax, eax 009ABCDC jnz short 009ABD03 ; 若C4OfAlphaOfKey为"s"或空串,且前面调用返回的余数为零则 009ABCDE mov dword ptr [ebp-4], 2D 009ABCE5 push 004A9C84 ; "R" 009ABCEA push 00C7E4CC ; "F" 009ABCEF push 1 009ABCF1 call <jmp.&MSVBVM60.__vbaLsetFixstr> 009ABCF6 mov dword ptr [ebp-4], 2E 009ABCFD mov word ptr [ebp-60], 1 009ABD03 mov dword ptr [ebp-4], 30 009ABD0A fld qword ptr [ebp-3C] 009ABD0D fcomp qword ptr [405B30] ; 前面调用返回的余数与19比较 009ABD13 fstsw ax 009ABD15 sahf 009ABD16 je short 009ABD24 009ABD18 mov dword ptr [ebp-19C], 1 ; 不等于19则[ebp-19C]w=1 009ABD22 jmp short 009ABD2B 009ABD24 and dword ptr [ebp-19C], 0 ; 等于19则[ebp-19C]w=0 009ABD2B push dword ptr [ebp-70] 009ABD2E push 004AE8E0 ; "x" 009ABD33 call <jmp.&MSVBVM60.__vbaStrCmp> ; C4OfAlphaOfKey与"x"比较 009ABD38 mov esi, eax 009ABD3A neg esi 009ABD3C sbb esi, esi 009ABD3E neg esi 009ABD40 push dword ptr [ebp-70] 009ABD43 push 004998F0 009ABD48 call <jmp.&MSVBVM60.__vbaStrCmp> ; C4OfAlphaOfKey与空串比较 009ABD4D neg eax 009ABD4F sbb eax, eax 009ABD51 neg eax 009ABD53 and esi, eax 009ABD55 neg esi 009ABD57 sbb esi, esi 009ABD59 neg esi 009ABD5B mov eax, dword ptr [ebp-19C] 009ABD61 or eax, esi 009ABD63 test eax, eax 009ABD65 jnz short 009ABD9A ; 若C4OfAlphaOfKey为"x"或空串,且前面调用返回的余数等于19则 009ABD67 mov dword ptr [ebp-4], 31 009ABD6E push 004A9C8C ; "X" 009ABD73 push 00C7E4CC ; "F" 009ABD78 push 1 009ABD7A call <jmp.&MSVBVM60.__vbaLsetFixstr> 009ABD7F mov dword ptr [ebp-4], 32 009ABD86 mov word ptr [ebp-60], 2 009ABD8C mov dword ptr [ebp-4], 33 009ABD93 and dword ptr [C7EC44], 0 009ABD9A mov dword ptr [ebp-4], 35 009ABDA1 cmp word ptr [ebp-60], 0 009ABDA6 jle 009AC2BB ; 若非前两种情况则转9AC2BB 009ABDAC mov dword ptr [ebp-4], 36 ; 取RegName ... ... 009ABE27 fldz 009ABE29 fstp qword ptr [ebp-11C] 009ABE2F mov edx, 004B02C4 ; "k" 009ABE34 lea ecx, dword ptr [ebp-84] 009ABE3A call <jmp.&MSVBVM60.__vbaStrCopy> 009ABE3F mov eax, dword ptr [ebp-7C] ; RegName 009ABE42 mov dword ptr [ebp-15C], eax 009ABE48 and dword ptr [ebp-7C], 0 009ABE4C mov edx, dword ptr [ebp-15C] 009ABE52 lea ecx, dword ptr [ebp-80] 009ABE55 call <jmp.&MSVBVM60.__vbaStrMove> 009ABE5A lea eax, dword ptr [ebp-11C] ; 0.0 009ABE60 push eax 009ABE61 lea eax, dword ptr [ebp-30] ; AlphaOfKey 009ABE64 push eax 009ABE65 lea eax, dword ptr [ebp-84] ; "k" 009ABE6B push eax 009ABE6C lea eax, dword ptr [ebp-80] ; RegName 009ABE6F push eax 009ABE70 call 00845426 ; 返回评估版的剩余天数 009ABE75 not ax 009ABE78 mov word ptr [ebp-128], ax ... ... 009ABE9F movsx eax, word ptr [ebp-128] 009ABEA6 test eax, eax 009ABEA8 je short 009ABEAF 009ABEAA jmp 009ACECF 009ABEAF mov dword ptr [ebp-4], 39 009ABEB6 fld qword ptr [ebp-3C] 009ABEB9 fstp qword ptr [C7D360] ; 取RegName ... ... 009ABF3A mov eax, dword ptr [ebp-7C] 009ABF3D mov dword ptr [ebp-160], eax 009ABF43 and dword ptr [ebp-7C], 0 009ABF47 mov edx, dword ptr [ebp-160] 009ABF4D mov ecx, 00C7E4D0 009ABF52 call <jmp.&MSVBVM60.__vbaStrMove> ; [C7E4D0]指向RegName 009ABF57 lea ecx, dword ptr [ebp-88] 009ABF5D call <jmp.&MSVBVM60.__vbaFreeObj> 009ABF62 mov dword ptr [ebp-4], 3B 009ABF69 mov edx, dword ptr [ebp-24] 009ABF6C mov ecx, 00C7E4E4 009ABF71 call <jmp.&MSVBVM60.__vbaStrCopy> ; [C7E4E4]指向NumberOfKey 009ABF76 mov dword ptr [ebp-4], 3C 009ABF7D mov edx, dword ptr [ebp-30] 009ABF80 mov ecx, 00C7E4F8 009ABF85 call <jmp.&MSVBVM60.__vbaStrCopy> ; [C7E4F8]指向AlphaOfKey 009ABF8A mov dword ptr [ebp-4], 3D 009ABF91 push 00C7E54C 009ABF96 push 00C7E550 009ABF9B push 00C7E4E4 009ABFA0 call 00BD4C31 ; 对NumberOfKey进行变换 009ABFA5 mov edx, eax 009ABFA7 lea ecx, dword ptr [ebp-24] 009ABFAA call <jmp.&MSVBVM60.__vbaStrMove> ; 在注册表中记录注册信息 ... ... 009AC1A0 mov dword ptr [ebp-4], 41 009AC1A7 and word ptr [C7D512], 0 009AC1AF mov dword ptr [ebp-4], 42 009AC1B6 push dword ptr [C7E4F8] ; AlphaOfKey 009AC1BC push 004998F0 ; vbNull 009AC1C1 call <jmp.&MSVBVM60.__vbaStrCmp> 009AC1C6 test eax, eax 009AC1C8 je 009AC26E 009AC1CE mov dword ptr [ebp-4], 43 009AC1D5 mov dword ptr [ebp-90], 1 009AC1DF mov dword ptr [ebp-98], 2 009AC1E9 lea eax, dword ptr [ebp-98] 009AC1EF push eax 009AC1F0 push 4 009AC1F2 push dword ptr [C7E4F8] 009AC1F8 call <jmp.&MSVBVM60.rtcMidCharBstr> 009AC1FD mov edx, eax 009AC1FF lea ecx, dword ptr [ebp-7C] 009AC202 call <jmp.&MSVBVM60.__vbaStrMove> 009AC207 push eax 009AC208 call <jmp.&MSVBVM60.rtcLowerCaseBstr> 009AC20D mov edx, eax 009AC20F lea ecx, dword ptr [ebp-6C] 009AC212 call <jmp.&MSVBVM60.__vbaStrMove> 009AC217 lea ecx, dword ptr [ebp-7C] 009AC21A call <jmp.&MSVBVM60.__vbaFreeStr> 009AC21F lea ecx, dword ptr [ebp-98] 009AC225 call <jmp.&MSVBVM60.__vbaFreeVar> 009AC22A mov dword ptr [ebp-4], 44 009AC231 push dword ptr [ebp-6C] 009AC234 push 004AF690 ; "s" 009AC239 call <jmp.&MSVBVM60.__vbaStrCmp> 009AC23E mov esi, eax 009AC240 neg esi 009AC242 sbb esi, esi 009AC244 neg esi 009AC246 push dword ptr [ebp-6C] 009AC249 push 004AE8E0 ; "x" 009AC24E call <jmp.&MSVBVM60.__vbaStrCmp> 009AC253 neg eax 009AC255 sbb eax, eax 009AC257 neg eax 009AC259 and esi, eax 009AC25B test esi, esi 009AC25D jnz short 009AC26E 009AC25F mov dword ptr [ebp-4], 45 009AC266 or word ptr [C7D512], 0FFFF 009AC26E mov dword ptr [ebp-4], 48 009AC275 mov eax, dword ptr [ebp+8] 009AC278 mov eax, dword ptr [eax] 009AC27A push dword ptr [ebp+8] 009AC27D call dword ptr [eax+714] 009AC283 mov dword ptr [ebp-120], eax 009AC289 cmp dword ptr [ebp-120], 0 009AC290 jge short 009AC2B2 009AC292 push 714 009AC297 push 004BB72C 009AC29C push dword ptr [ebp+8] 009AC29F push dword ptr [ebp-120] 009AC2A5 call <jmp.&MSVBVM60.__vbaHresultCheck> 009AC2AA mov dword ptr [ebp-1A8], eax 009AC2B0 jmp short 009AC2B9 009AC2B2 and dword ptr [ebp-1A8], 0 009AC2B9 jmp short 009AC2D5 009AC2BB mov dword ptr [ebp-4], 4A 009AC2C2 push dword ptr [ebp-30] 009AC2C5 push 004998F0 009AC2CA call <jmp.&MSVBVM60.__vbaStrCmp> ; AlphaOfKey与空串比较 009AC2CF test eax, eax 009AC2D1 jnz short 009AC2D5 ; 若非空串则转9ACEDB(出错提示) 009AC2D3 jmp short 009AC2DA 009AC2D5 jmp 009ACEDB ; C4OfAlphaOfKey="u"时的处理过程 ... ... ; C4OfAlphaOfKey="v"时的处理过程 ... ... 009ACECF mov dword ptr [ebp-4], 80 009ACED6 and word ptr [ebp-60], 0 009ACEDB mov dword ptr [ebp-4], 82 009ACEE2 mov ax, word ptr [ebp-60] 009ACEE6 mov word ptr [ebp-134], ax 009ACEED movsx eax, word ptr [ebp-134] 009ACEF4 mov dword ptr [ebp-1C4], eax 009ACEFA cmp dword ptr [ebp-1C4], 0 009ACF01 je short 009ACF0D 009ACF03 jmp 009AD2D8 009ACF08 jmp 009AD389 ; 注册信息有误时的处理过程,其中要进行提示 ... ... 009AD2D8 mov dword ptr [ebp-4], 90 009AD2DF mov dword ptr [ebp-C0], 80020004 009AD2E9 mov dword ptr [ebp-C8], 0A 009AD2F3 mov dword ptr [ebp-B0], 80020004 009AD2FD mov dword ptr [ebp-B8], 0A 009AD307 mov dword ptr [ebp-A0], 80020004 009AD311 mov dword ptr [ebp-A8], 0A 009AD31B mov dword ptr [ebp-D0], 004CAF0C ; UNICODE "License Key loaded OK" 009AD325 mov dword ptr [ebp-D8], 8 009AD32F lea edx, dword ptr [ebp-D8] 009AD335 lea ecx, dword ptr [ebp-98] 009AD33B call <jmp.&MSVBVM60.__vbaVarDup> 009AD340 lea eax, dword ptr [ebp-C8] 009AD346 push eax 009AD347 lea eax, dword ptr [ebp-B8] 009AD34D push eax 009AD34E lea eax, dword ptr [ebp-A8] 009AD354 push eax 009AD355 push 40 009AD357 lea eax, dword ptr [ebp-98] 009AD35D push eax 009AD35E call <jmp.&MSVBVM60.rtcMsgBox> ... ... 009AD389 mov dword ptr [ebp-4], 92 009AD390 mov eax, dword ptr [ebp+8] 009AD393 mov eax, dword ptr [eax] 009AD395 push dword ptr [ebp+8] 009AD398 call dword ptr [eax+70C] ; 调用9AA7F8,在注册信息窗体中显示注册类型 009AD39E mov dword ptr [ebp-120], eax 009AD3A4 cmp dword ptr [ebp-120], 0 009AD3AB jge short 009AD3CD 009AD3AD push 70C 009AD3B2 push 004BB72C 009AD3B7 push dword ptr [ebp+8] 009AD3BA push dword ptr [ebp-120] 009AD3C0 call <jmp.&MSVBVM60.__vbaHresultCheck> 009AD3C5 mov dword ptr [ebp-1E8], eax 009AD3CB jmp short 009AD3D4 009AD3CD and dword ptr [ebp-1E8], 0 009AD3D4 mov dword ptr [ebp-10], 0 009AD3DB wait 009AD3DC push 009AD47A 009AD3E1 jmp short 009AD42E ... ... ; 从过程返回时的一些善后工作 ... ... 009AD499 jmp <jmp.&MSVBVM60.__vbaFPException> 009AD49E call <jmp.&MSVBVM60.__vbaErrorOverflo>
1、调用9A908B时,实际上计算的是20位的NumOfKey除以CheckSumOfName的商和余数。
2、表面上看,AlphaOfKey的末三个字符可以是“nnn”。在后面调用845426时,会调用始于81DA26的过程。其中表明,AlphaOfKey的末三个字符是“nnn”意味着AlphaOfKey中包含有评估版的限制天数。
从分析中可以总结出如下几点:
1、注册名去掉空白后不得少于三个字符;
2、注册码中要有20位的数字;
3、若AlphaOfKey的第4个字符的小写为s,且NumOfKey除以CheckSumOfName的余数为0,则为标准版;
4、若AlphaOfKey的第4个字符的小写为x,且NumOfKey除以CheckSumOfName的余数为19,则为扩展版;
5、若AlphaOfKey的第4个字符的小写为u,且NumOfKey除以CheckSumOfName的余数为7,则为v7的升级版;
6、若AlphaOfKey的第4个字符的小写为v,且NumOfKey除以CheckSumOfName的余数为7,则为v8的升级版;
7、AlphaOfKey的第8个字符应符合855D81过程的算法。
表面上看,分析到此就为止了,我们可以根据前面的分析写出注册机,但有一个算法、策略的问题需要给大家交流。
用一个20位的符合条件的数值来反推出AlphaOfKey显然是不可能的事情。我的做法是,AlphaOfKey的前三个字符固定,第四个字符定为s、x、u、v之一,第五到第七个字符交互输入,第八个字符根据分析中的算法用注册名计算出来,计算CheckSumOfName后,用随机数逐位生成一个20位的整数。这个大整数除以CheckSumOfName的余数若不是0、19、7,则把它调整一下,使其达到要求。
这时,我满怀信心地用注册机生成了一个扩展版的Key,输入后却发现注册信息窗口下面显示的是“v7 Extended Edtion”。

这就有点不爽了。经过进一步的跟踪发现,原来在调用9AA7F8时,程序会进一步调用9A9A6D始的过程。这个过程会进一步验证AlphaOfKey的第四个字符是否是小写的"x"。只有当AlphaOfKey的第四个字符是小写的"x"时,生成的版本标识串才能是我们期望的“Extended Edtion”。把注册机修改一下,最后终于如愿以偿。