[简介] 飞雪日历V1.62.0437 绿色软件 有万年历、时钟、世界时间、定时、限时、提醒、备忘录、系统热键、光驱控制、定期清理、语音报时等功能。
[来源] http://www.zheng99.com/
[限制] 未注册版没有时间和功能限制,但是定时弹出提醒注册的窗口
[工具] PEid, OllyDbg, Numega SmartCheck
[声明] 调试分析纯属兴趣,请不要用于其他目的
[过程]
先注册,随便填写注册名abc、注册码1234567890,程序仅提示已保存机器码和用户输入的注册名、注册码,没有其他反应。
PEiD查壳UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo,手工脱壳后再查是VB写的,但运行脱壳后的程序有"不精确的浮点数运算结果异常"而退出,看雪老大在脱壳基础第六课没有说这种粘壳的粽子怎么剥,
没法子只好带壳调试。
用SmartCheck打开运行原程序,是多线程,Thread0下的ThunRTMain有很多DispatchMessageA向下翻到一个TimerTmp(1)_Timer,展开看到有机器码等三项注册用的字串,估计是这里验证是否已注册,向前翻看可知是读自子目录FXSYS下的文件FXSYS.INI,还看到前面调用Randomize、用处理器信息字符串各ASCII值*2累加成机器码,有这些信息在OD就好定位了。
用OD打开、停下,翻屏找POPAD和长JMP,在真正入口点00405CE0下断,F9运行再停下时程序已脱壳,入口点上面几行就是输入表的跳转命令,找到MSVBVM60.rtcRandomize是JMP [DWORD DS:4010DC],查找命令CALL [DWORD DS:4010DC]只有一处。向下翻看见到读注册文件的地方就是我们要找的了。
00465880 55 PUSH EBP
...注册过一次就能到这里,这些忽略过...
00465B42 8B55 E0 MOV EDX,[DWORD SS:EBP-20] ; 注册名地址
00465B45 52 PUSH EDX
00465B46 FF15 2C104000 CALL [DWORD DS:40102C] ; MSVBVM60.__vbaLenBstr
00465B4C 3BC7 CMP EAX,EDI ; 注册名长度,不能少于2字节
00465B4E 0F8C 4F060000 JL FXRL.004661A3 ; 跳就完
00465B54 C745 88 0100000>MOV [DWORD SS:EBP-78],1
00465B5B 897D 80 MOV [DWORD SS:EBP-80],EDI
00465B5E 8D45 80 LEA EAX,[DWORD SS:EBP-80]
00465B61 50 PUSH EAX
00465B62 6A 01 PUSH 1
00465B64 8B4D E0 MOV ECX,[DWORD SS:EBP-20]
00465B67 51 PUSH ECX
00465B68 8B3D 20114000 MOV EDI,[DWORD DS:401120] ; MSVBVM60.rtcMidCharBstr
00465B6E FFD7 CALL EDI
00465B70 8BD0 MOV EDX,EAX ; 注册名第1个字符'a'(地址)
00465B72 8D4D A0 LEA ECX,[DWORD SS:EBP-60]
00465B75 FFD6 CALL ESI
00465B77 50 PUSH EAX
00465B78 FF15 50104000 CALL [DWORD DS:401050] ; MSVBVM60.rtcAnsiValueBstr
00465B7E 8BD8 MOV EBX,EAX ; 返回'a'的ASCII值61
00465B80 6A 01 PUSH 1
00465B82 8B55 CC MOV EDX,[DWORD SS:EBP-34] ; 注册码地址
00465B85 52 PUSH EDX
00465B86 FF15 CC124000 CALL [DWORD DS:4012CC] ; MSVBVM60.rtcLeftCharBstr
00465B8C 8BD0 MOV EDX,EAX ; 注册码第1个字符(地址)
00465B8E 8D4D 98 LEA ECX,[DWORD SS:EBP-68]
00465B91 FFD6 CALL ESI
00465B93 50 PUSH EAX
00465B94 6A 01 PUSH 1
00465B96 53 PUSH EBX
00465B97 FF15 08104000 CALL [DWORD DS:401008] ; MSVBVM60.__vbaStrI2
00465B9D 8BD0 MOV EDX,EAX ; 注册名第1字符ASCII值(十进制)转换为字符串"97"
00465B9F 8D4D 9C LEA ECX,[DWORD SS:EBP-64]
00465BA2 FFD6 CALL ESI
00465BA4 50 PUSH EAX
00465BA5 FF15 EC124000 CALL [DWORD DS:4012EC] ; MSVBVM60.rtcRightCharBstr
00465BAB 8BD0 MOV EDX,EAX
00465BAD 8D4D 94 LEA ECX,[DWORD SS:EBP-6C]
00465BB0 FFD6 CALL ESI
00465BB2 50 PUSH EAX ; "97"的最后1个字符'7'(地址)
00465BB3 FF15 60114000 CALL [DWORD DS:401160] ; MSVBVM60.__vbaStrCmp
00465BB9 8BD8 MOV EBX,EAX ; 比较'7'和注册码第1字符,如果相等就返回0
00465BBB F7DB NEG EBX
00465BBD 1BDB SBB EBX,EBX
00465BBF F7DB NEG EBX
00465BC1 F7DB NEG EBX
00465BC3 8D45 94 LEA EAX,[DWORD SS:EBP-6C]
00465BC6 50 PUSH EAX
00465BC7 8D4D 98 LEA ECX,[DWORD SS:EBP-68]
00465BCA 51 PUSH ECX
00465BCB 8D55 9C LEA EDX,[DWORD SS:EBP-64]
00465BCE 52 PUSH EDX
00465BCF 8D45 A0 LEA EAX,[DWORD SS:EBP-60]
00465BD2 50 PUSH EAX
00465BD3 6A 04 PUSH 4
00465BD5 FF15 70124000 CALL [DWORD DS:401270] ; MSVBVM60.__vbaFreeStrList
00465BDB 83C4 14 ADD ESP,14
00465BDE 8D4D 80 LEA ECX,[DWORD SS:EBP-80]
00465BE1 FF15 20104000 CALL [DWORD DS:401020] ; MSVBVM60.__vbaFreeVar
00465BE7 66:85DB TEST BX,BX
00465BEA 0F85 B3050000 JNZ FXRL.004661A3 ; 上面字符比较相等,这里就不会跳走,否则跳就完。此时知道注册码第1字符对应注册名a应该是7才对。
...然后比较注册名第2字符'b'与注册码第2字符,知道第2个应该是'8'。过程同上略过...
00465CA5 0F85 F8040000 JNZ FXRL.004661A3 ; 不能跳
00465CAB C745 88 0400028>MOV [DWORD SS:EBP-78],80020004
00465CB2 C745 80 0A00000>MOV [DWORD SS:EBP-80],0A
00465CB9 8D55 80 LEA EDX,[DWORD SS:EBP-80]
00465CBC 52 PUSH EDX
00465CBD 6A 03 PUSH 3
00465CBF 8B45 CC MOV EAX,[DWORD SS:EBP-34]
00465CC2 50 PUSH EAX
00465CC3 FFD7 CALL EDI
00465CC5 8BD0 MOV EDX,EAX ; 取得注册码第3字符开始的右边子串(地址)
00465CC7 8D4D CC LEA ECX,[DWORD SS:EBP-34]
00465CCA FFD6 CALL ESI
00465CCC 8D4D 80 LEA ECX,[DWORD SS:EBP-80]
00465CCF FF15 20104000 CALL [DWORD DS:401020] ; MSVBVM60.__vbaFreeVar
00465CD5 8B4D CC MOV ECX,[DWORD SS:EBP-34] ; 截取注册码第3字符开始的右边子串
00465CD8 51 PUSH ECX ; 入栈,下面把它转换成浮点数
00465CD9 FF15 50134000 CALL [DWORD DS:401350] ; MSVBVM60.rtcR8ValFromBstr
00465CDF FF15 14114000 CALL [DWORD DS:401114] ; MSVBVM60.__vbaFpR8
00465CE5 DC1D 30234000 FCOMP [QWORD DS:402330] ; 和999999.0比较,要比这个常数大才行
00465CEB DFE0 FSTSW AX
00465CED F6C4 41 TEST AH,41
00465CF0 C785 CCFEFFFF 0>MOV [DWORD SS:EBP-134],1
00465CFA 74 0A JE SHORT FXRL.00465D06 ; 必须跳(以使之赋值为1后面马上用到)
00465CFC C785 CCFEFFFF 0>MOV [DWORD SS:EBP-134],0 ; 然后同法比较机器码,暂时不管
00465D06 8D55 A4 LEA EDX,[DWORD SS:EBP-5C]
00465D09 52 PUSH EDX
00465D0A 8D45 A0 LEA EAX,[DWORD SS:EBP-60]
00465D0D 50 PUSH EAX
00465D0E FF15 0C124000 CALL [DWORD DS:40120C] ; MSVBVM60.__vbaStrVarVal
00465D14 50 PUSH EAX
00465D15 FF15 50134000 CALL [DWORD DS:401350] ; MSVBVM60.rtcR8ValFromBstr
00465D1B FF15 14114000 CALL [DWORD DS:401114] ; MSVBVM60.__vbaFpR8
00465D21 DC1D 28234000 FCOMP [QWORD DS:402328] ; 和101.0比较
00465D27 DFE0 FSTSW AX
00465D29 F6C4 41 TEST AH,41
00465D2C 75 07 JNZ SHORT FXRL.00465D35 ; 这里正常地是不跳的
00465D2E BB 01000000 MOV EBX,1
00465D33 EB 02 JMP SHORT FXRL.00465D37
00465D35 33DB XOR EBX,EBX
00465D37 8B4D E0 MOV ECX,[DWORD SS:EBP-20] ; 注册名,检查它的长度
00465D3A 51 PUSH ECX
00465D3B FF15 2C104000 CALL [DWORD DS:40102C] ; MSVBVM60.__vbaLenBstr
00465D41 33D2 XOR EDX,EDX
00465D43 83F8 01 CMP EAX,1
00465D46 0F9FC2 SETG DL ; 长度大于1则条件为真,寄存器DL设置为1
00465D49 F7DA NEG EDX
00465D4B 8B85 CCFEFFFF MOV EAX,[DWORD SS:EBP-134]
00465D51 F7D8 NEG EAX
00465D53 23D0 AND EDX,EAX
00465D55 F7DB NEG EBX
00465D57 23DA AND EBX,EDX
00465D59 8D4D A0 LEA ECX,[DWORD SS:EBP-60]
00465D5C FF15 4C134000 CALL [DWORD DS:40134C] ; MSVBVM60.__vbaFreeStr
00465D62 66:85DB TEST BX,BX
00465D65 0F84 38040000 JE FXRL.004661A3 ; 上面几个两个跳转正确到这里就不会跳走,继续
00465D6B BB 01000000 MOV EBX,1
00465D70 899D 48FFFFFF MOV [DWORD SS:EBP-B8],EBX
00465D76 C785 40FFFFFF 0>MOV [DWORD SS:EBP-C0],2
00465D80 8D95 40FFFFFF LEA EDX,[DWORD SS:EBP-C0]
00465D86 8D4D BC LEA ECX,[DWORD SS:EBP-44]
00465D89 FF15 18104000 CALL [DWORD DS:401018] ; MSVBVM60.__vbaVarMove
00465D8F C785 F0FEFFFF 0>MOV [DWORD SS:EBP-110],3
00465D99 66:3B9D F0FEFFF>CMP BX,[WORD SS:EBP-110] ; 循环机器码前3个字符
00465DA0 0F8F 91000000 JG FXRL.00465E37
00465DA6 C745 88 0100000>MOV [DWORD SS:EBP-78],1
00465DAD C745 80 0200000>MOV [DWORD SS:EBP-80],2
00465DB4 8D45 80 LEA EAX,[DWORD SS:EBP-80]
00465DB7 50 PUSH EAX
00465DB8 0FBFCB MOVSX ECX,BX
00465DBB 51 PUSH ECX
00465DBC 8D55 A4 LEA EDX,[DWORD SS:EBP-5C]
00465DBF 52 PUSH EDX
00465DC0 8D45 A0 LEA EAX,[DWORD SS:EBP-60]
00465DC3 50 PUSH EAX
00465DC4 FF15 0C124000 CALL [DWORD DS:40120C] ; MSVBVM60.__vbaStrVarVal
00465DCA 50 PUSH EAX
00465DCB FFD7 CALL EDI
00465DCD 8BD0 MOV EDX,EAX ; 机器码一字符(地址)
00465DCF 8D4D 9C LEA ECX,[DWORD SS:EBP-64]
00465DD2 FFD6 CALL ESI
00465DD4 50 PUSH EAX
00465DD5 FF15 50104000 CALL [DWORD DS:401050] ; MSVBVM60.rtcAnsiValueBstr
00465DDB 66:8985 38FFFFF>MOV [WORD SS:EBP-C8],AX ; 返回其ASCII值
00465DE2 C785 30FFFFFF 0>MOV [DWORD SS:EBP-D0],2
00465DEC 8D4D BC LEA ECX,[DWORD SS:EBP-44]
00465DEF 51 PUSH ECX
00465DF0 8D95 30FFFFFF LEA EDX,[DWORD SS:EBP-D0]
00465DF6 52 PUSH EDX
00465DF7 8D85 70FFFFFF LEA EAX,[DWORD SS:EBP-90]
00465DFD 50 PUSH EAX
00465DFE FF15 AC124000 CALL [DWORD DS:4012AC] ; MSVBVM60.__vbaVarAdd,跟进看到第1字符ASCII值加到1上,其他的再累加上去
00465E04 8BD0 MOV EDX,EAX
00465E06 8D4D BC LEA ECX,[DWORD SS:EBP-44]
00465E09 FF15 18104000 CALL [DWORD DS:401018] ; MSVBVM60.__vbaVarMove
00465E0F 8D4D 9C LEA ECX,[DWORD SS:EBP-64]
00465E12 51 PUSH ECX
00465E13 8D55 A0 LEA EDX,[DWORD SS:EBP-60]
00465E16 52 PUSH EDX
00465E17 6A 02 PUSH 2
00465E19 FF15 70124000 CALL [DWORD DS:401270] ; MSVBVM60.__vbaFreeStrList
00465E1F 83C4 0C ADD ESP,0C
00465E22 8D4D 80 LEA ECX,[DWORD SS:EBP-80]
00465E25 FF15 20104000 CALL [DWORD DS:401020] ; MSVBVM60.__vbaFreeVar
00465E2B B8 01000000 MOV EAX,1
00465E30 03D8 ADD EBX,EAX
00465E32 ^ E9 62FFFFFF JMP FXRL.00465D99
00465E37 8D45 A4 LEA EAX,[DWORD SS:EBP-5C] ; 上面循环体跳出到此
00465E3A 50 PUSH EAX
00465E3B 8D4D 80 LEA ECX,[DWORD SS:EBP-80]
00465E3E 51 PUSH ECX
00465E3F FF15 B4104000 CALL [DWORD DS:4010B4] ; MSVBVM60.__vbaLenVar
00465E45 50 PUSH EAX
00465E46 FF15 24124000 CALL [DWORD DS:401224] ; MSVBVM60.__vbaI2Var
00465E4C 8985 E8FEFFFF MOV [DWORD SS:EBP-118],EAX
00465E52 BB 04000000 MOV EBX,4
00465E57 66:3B9D E8FEFFF>CMP BX,[WORD SS:EBP-118] ; 循环机器码的第4字符开始后面的各字符
00465E5E 0F8F 91000000 JG FXRL.00465EF5
00465E64 C745 88 0100000>MOV [DWORD SS:EBP-78],1
00465E6B C745 80 0200000>MOV [DWORD SS:EBP-80],2
00465E72 8D55 80 LEA EDX,[DWORD SS:EBP-80]
00465E75 52 PUSH EDX
00465E76 0FBFC3 MOVSX EAX,BX
00465E79 50 PUSH EAX
00465E7A 8D4D A4 LEA ECX,[DWORD SS:EBP-5C]
00465E7D 51 PUSH ECX
00465E7E 8D55 A0 LEA EDX,[DWORD SS:EBP-60]
00465E81 52 PUSH EDX
00465E82 FF15 0C124000 CALL [DWORD DS:40120C] ; MSVBVM60.__vbaStrVarVal
00465E88 50 PUSH EAX ; 返回机器码地址
00465E89 FFD7 CALL EDI
00465E8B 8BD0 MOV EDX,EAX
00465E8D 8D4D 9C LEA ECX,[DWORD SS:EBP-64]
00465E90 FFD6 CALL ESI
00465E92 50 PUSH EAX
00465E93 FF15 50104000 CALL [DWORD DS:401050] ; MSVBVM60.rtcAnsiValueBstr
00465E99 66:8985 38FFFFF>MOV [WORD SS:EBP-C8],AX
00465EA0 C785 30FFFFFF 0>MOV [DWORD SS:EBP-D0],2
00465EAA 8D45 BC LEA EAX,[DWORD SS:EBP-44]
00465EAD 50 PUSH EAX
00465EAE 8D8D 30FFFFFF LEA ECX,[DWORD SS:EBP-D0]
00465EB4 51 PUSH ECX
00465EB5 8D95 70FFFFFF LEA EDX,[DWORD SS:EBP-90]
00465EBB 52 PUSH EDX
00465EBC FF15 C0114000 CALL [DWORD DS:4011C0] ; MSVBVM60.__vbaVarMul,跟进看到第一轮是上面那个循环的累加值为被乘数,注册码第4字符ASCII值为乘数,积作为下一轮的被乘数;乘数依次变为注册码第4字符以后各字符的ASCII值
00465EC2 8BD0 MOV EDX,EAX
00465EC4 8D4D BC LEA ECX,[DWORD SS:EBP-44]
00465EC7 FF15 18104000 CALL [DWORD DS:401018] ; MSVBVM60.__vbaVarMove
00465ECD 8D45 9C LEA EAX,[DWORD SS:EBP-64]
00465ED0 50 PUSH EAX
00465ED1 8D4D A0 LEA ECX,[DWORD SS:EBP-60]
00465ED4 51 PUSH ECX
00465ED5 6A 02 PUSH 2
00465ED7 FF15 70124000 CALL [DWORD DS:401270] ; MSVBVM60.__vbaFreeStrList
00465EDD 83C4 0C ADD ESP,0C
00465EE0 8D4D 80 LEA ECX,[DWORD SS:EBP-80]
00465EE3 FF15 20104000 CALL [DWORD DS:401020] ; MSVBVM60.__vbaFreeVar
00465EE9 B8 01000000 MOV EAX,1
00465EEE 03D8 ADD EBX,EAX
00465EF0 ^ E9 62FFFFFF JMP FXRL.00465E57
00465EF5 8D55 BC LEA EDX,[DWORD SS:EBP-44] ; 上面循环体跳出到此
//设上面两个循环体对机器码计算结果为RES(64位双精度浮点数)
00465EF8 52 PUSH EDX
00465EF9 FF15 80124000 CALL [DWORD DS:401280] ; MSVBVM60.__vbaR8Var
00465EFF E8 5AF9F9FF CALL FXRL.0040585E ; JMP 到 MSVBVM60._CIsqrt
00465F04 DD9D 04FFFFFF FSTP [QWORD SS:EBP-FC] ; 上面求出RES的平方根
00465F0A 6A 05 PUSH 5
00465F0C 8B85 08FFFFFF MOV EAX,[DWORD SS:EBP-F8]
00465F12 50 PUSH EAX
00465F13 8B8D 04FFFFFF MOV ECX,[DWORD SS:EBP-FC]
00465F19 51 PUSH ECX
00465F1A 8B1D A0114000 MOV EBX,[DWORD DS:4011A0] ; MSVBVM60.__vbaStrR8
00465F20 FFD3 CALL EBX ; 把sqrt(RES)从浮点数转换成字串(长度16,小数部分11位,四舍五入)
00465F22 8BD0 MOV EDX,EAX
00465F24 8D4D A0 LEA ECX,[DWORD SS:EBP-60]
00465F27 FFD6 CALL ESI
00465F29 50 PUSH EAX
00465F2A FF15 EC124000 CALL [DWORD DS:4012EC] ; MSVBVM60.rtcRightCharBstr
00465F30 8BD0 MOV EDX,EAX ; 返回EAX=该串最后5个字符子串(地址)
00465F32 8D4D 9C LEA ECX,[DWORD SS:EBP-64]
00465F35 FFD6 CALL ESI
00465F37 50 PUSH EAX
00465F38 FF15 50134000 CALL [DWORD DS:401350] ; MSVBVM60.rtcR8ValFromBstr,子串再转换成浮点数TAIL
00465F3E DD9D FCFEFFFF FSTP [QWORD SS:EBP-104]
00465F44 8D55 BC LEA EDX,[DWORD SS:EBP-44]
00465F47 52 PUSH EDX
00465F48 FF15 80124000 CALL [DWORD DS:401280] ; MSVBVM60.__vbaR8Var
00465F4E E8 0BF9F9FF CALL FXRL.0040585E ; JMP 到 MSVBVM60._CIsqrt
00465F53 DC0D 20234000 FMUL [QWORD DS:402320] ; 上面再一次计算RES的平方根,这里再乘以10000.0,合起来就是sqrt(RES)*10000.0
00465F59 FF15 30134000 CALL [DWORD DS:401330] ; MSVBVM60.__vbaFPInt,取整
00465F5F DC85 FCFEFFFF FADD [QWORD SS:EBP-104] ; 取整后再加上TAIL,得W=Int(sqrt(RES)*10000.0)+TAIL
00465F65 DD9D 48FFFFFF FSTP [QWORD SS:EBP-B8]
00465F6B C785 40FFFFFF 0>MOV [DWORD SS:EBP-C0],5
00465F75 8D95 40FFFFFF LEA EDX,[DWORD SS:EBP-C0]
00465F7B 8D4D BC LEA ECX,[DWORD SS:EBP-44]
00465F7E FF15 18104000 CALL [DWORD DS:401018] ; MSVBVM60.__vbaVarMove
00465F84 8D45 9C LEA EAX,[DWORD SS:EBP-64]
00465F87 50 PUSH EAX
00465F88 8D4D A0 LEA ECX,[DWORD SS:EBP-60]
00465F8B 51 PUSH ECX
00465F8C 6A 02 PUSH 2
00465F8E FF15 70124000 CALL [DWORD DS:401270] ; MSVBVM60.__vbaFreeStrList
00465F94 83C4 0C ADD ESP,0C
00465F97 C745 88 0100000>MOV [DWORD SS:EBP-78],1
00465F9E C745 80 0200000>MOV [DWORD SS:EBP-80],2
00465FA5 8D55 80 LEA EDX,[DWORD SS:EBP-80]
00465FA8 52 PUSH EDX
00465FA9 6A 01 PUSH 1
00465FAB 8B45 E0 MOV EAX,[DWORD SS:EBP-20]
00465FAE 50 PUSH EAX
00465FAF FFD7 CALL EDI
00465FB1 8BD0 MOV EDX,EAX
00465FB3 8D4D A0 LEA ECX,[DWORD SS:EBP-60]
00465FB6 FFD6 CALL ESI
00465FB8 50 PUSH EAX
00465FB9 FF15 50104000 CALL [DWORD DS:401050] ; MSVBVM60.rtcAnsiValueBstr
00465FBF 8985 0CFFFFFF MOV [DWORD SS:EBP-F4],EAX
00465FC5 8D4D BC LEA ECX,[DWORD SS:EBP-44]
00465FC8 51 PUSH ECX
00465FC9 FF15 80124000 CALL [DWORD DS:401280] ; MSVBVM60.__vbaR8Var
00465FCF E8 8AF8F9FF CALL FXRL.0040585E ; JMP 到 MSVBVM60._CIsqrt
00465FD4 E8 79F8F9FF CALL FXRL.00405852 ; JMP 到 MSVBVM60._CIlog
00465FD9 DD9D 04FFFFFF FSTP [QWORD SS:EBP-FC] ; 上面几行命令计算W的平方根,再求出根的自然对数LN
00465FDF 8B55 CC MOV EDX,[DWORD SS:EBP-34] ; 注册码第3字符开始的子串,现在还是假的,下面把它转换成浮点数HM
00465FE2 52 PUSH EDX
00465FE3 FF15 40124000 CALL [DWORD DS:401240] ; MSVBVM60.__vbaR8Str
00465FE9 DD9D C4FEFFFF FSTP [QWORD SS:EBP-13C]
00465FEF DD85 04FFFFFF FLD [QWORD SS:EBP-FC]
00465FF5 DC0D 18234000 FMUL [QWORD DS:402318] ; 对数LN乘100.0
00465FFB FF15 30134000 CALL [DWORD DS:401330] ; MSVBVM60.__vbaFPInt,对积取整得到LN100
00466001 8B85 0CFFFFFF MOV EAX,[DWORD SS:EBP-F4] ; 取注册名第1字符ASCII值
00466007 83C0 F9 ADD EAX,-7 ; 加-7,设为CA
0046600A 0FBFC8 MOVSX ECX,AX
0046600D 898D C0FEFFFF MOV [DWORD SS:EBP-140],ECX
00466013 DB85 C0FEFFFF FILD [DWORD SS:EBP-140] ; CA入浮点栈
00466019 DD9D B8FEFFFF FSTP [QWORD SS:EBP-148]
0046601F DC8D B8FEFFFF FMUL [QWORD SS:EBP-148] ; 将LN100与CA相乘
00466025 DCAD C4FEFFFF FSUBR [QWORD SS:EBP-13C] ; HM-(LN100*CA),下面把差(整数)转换成字串SS
0046602B 83EC 08 SUB ESP,8
0046602E DD1C24 FSTP [QWORD SS:ESP]
00466031 FFD3 CALL EBX
00466033 8BD0 MOV EDX,EAX
00466035 8D4D CC LEA ECX,[DWORD SS:EBP-34]
00466038 FFD6 CALL ESI
0046603A 8D4D A0 LEA ECX,[DWORD SS:EBP-60]
0046603D FF15 4C134000 CALL [DWORD DS:40134C] ; MSVBVM60.__vbaFreeStr
00466043 8D4D 80 LEA ECX,[DWORD SS:EBP-80]
00466046 FF15 20104000 CALL [DWORD DS:401020] ; MSVBVM60.__vbaFreeVar
//下面是最后一个循环体
0046604C 8B55 E0 MOV EDX,[DWORD SS:EBP-20]
0046604F 52 PUSH EDX
00466050 FF15 2C104000 CALL [DWORD DS:40102C] ; MSVBVM60.__vbaLenBstr
00466056 8BD8 MOV EBX,EAX ; 注册名长度
00466058 B8 02000000 MOV EAX,2 ; 循环结束条件是经计算过注册名第2字符以后
0046605D 66:3BD8 CMP BX,AX
00466060 8B45 CC MOV EAX,[DWORD SS:EBP-34] ; 第1轮循环这个地址指向字串SS,是该循环体的初始值,以后各轮它指向的字串是前一轮计算结果
00466063 0F8C 02010000 JL FXRL.0046616B
00466069 8985 48FFFFFF MOV [DWORD SS:EBP-B8],EAX
0046606F C785 40FFFFFF 0>MOV [DWORD SS:EBP-C0],8
00466079 C785 78FFFFFF 0>MOV [DWORD SS:EBP-88],1
00466083 C785 70FFFFFF 0>MOV [DWORD SS:EBP-90],2
0046608D 8D8D 70FFFFFF LEA ECX,[DWORD SS:EBP-90]
00466093 51 PUSH ECX
00466094 0FBFD3 MOVSX EDX,BX
00466097 52 PUSH EDX
00466098 8B45 E0 MOV EAX,[DWORD SS:EBP-20]
0046609B 50 PUSH EAX
0046609C FFD7 CALL EDI ; 倒取注册名各字符
0046609E 8BD0 MOV EDX,EAX
004660A0 8D4D A0 LEA ECX,[DWORD SS:EBP-60]
004660A3 FFD6 CALL ESI
004660A5 50 PUSH EAX
004660A6 FF15 50104000 CALL [DWORD DS:401050] ; MSVBVM60.rtcAnsiValueBstr
004660AC 83E8 32 SUB EAX,32 ; 当前字符的ASCII值减去32,设为Cn
004660AF 66:8985 28FFFFF>MOV [WORD SS:EBP-D8],AX
004660B6 C785 20FFFFFF 0>MOV [DWORD SS:EBP-E0],2
004660C0 8D4D BC LEA ECX,[DWORD SS:EBP-44]
004660C3 51 PUSH ECX
004660C4 FF15 80124000 CALL [DWORD DS:401280] ; MSVBVM60.__vbaR8Var
004660CA E8 83F7F9FF CALL FXRL.00405852 ; JMP 到 MSVBVM60._CIlog
004660CF DC0D 18234000 FMUL [QWORD DS:402318] ; 上句求出W的自然对数,这句乘以100.0,下句把积取整;明显该值在各轮是相同的,设为D
004660D5 FF15 30134000 CALL [DWORD DS:401330] ; MSVBVM60.__vbaFPInt
004660DB DD9D 18FFFFFF FSTP [QWORD SS:EBP-E8]
004660E1 C785 10FFFFFF 0>MOV [DWORD SS:EBP-F0],5
004660EB 8D95 40FFFFFF LEA EDX,[DWORD SS:EBP-C0]
004660F1 52 PUSH EDX
004660F2 8D45 BC LEA EAX,[DWORD SS:EBP-44]
004660F5 50 PUSH EAX
004660F6 8D4D 80 LEA ECX,[DWORD SS:EBP-80]
004660F9 51 PUSH ECX
004660FA FF15 04104000 CALL [DWORD DS:401004] ; MSVBVM60.__vbaVarSub,跟进看到SS串变成浮点数减去W,注意各轮SS是用上一轮的结果
00466100 50 PUSH EAX
00466101 8D95 20FFFFFF LEA EDX,[DWORD SS:EBP-E0]
00466107 52 PUSH EDX
00466108 8D85 60FFFFFF LEA EAX,[DWORD SS:EBP-A0]
0046610E 50 PUSH EAX
0046610F FF15 AC124000 CALL [DWORD DS:4012AC] ; MSVBVM60.__vbaVarAdd,差加上Cn
00466115 50 PUSH EAX
00466116 8D8D 10FFFFFF LEA ECX,[DWORD SS:EBP-F0]
0046611C 51 PUSH ECX
0046611D 8D95 50FFFFFF LEA EDX,[DWORD SS:EBP-B0]
00466123 52 PUSH EDX
00466124 FF15 AC124000 CALL [DWORD DS:4012AC] ; MSVBVM60.__vbaVarAdd,再加上D,得到这一轮计算结果,转换成字串用于下一轮
0046612A 50 PUSH EAX
0046612B FF15 30104000 CALL [DWORD DS:401030] ; MSVBVM60.__vbaStrVarMove
00466131 8BD0 MOV EDX,EAX
00466133 8D4D CC LEA ECX,[DWORD SS:EBP-34]
00466136 FFD6 CALL ESI
00466138 8D4D A0 LEA ECX,[DWORD SS:EBP-60]
0046613B FF15 4C134000 CALL [DWORD DS:40134C] ; MSVBVM60.__vbaFreeStr
00466141 8D85 50FFFFFF LEA EAX,[DWORD SS:EBP-B0]
00466147 50 PUSH EAX
00466148 8D8D 60FFFFFF LEA ECX,[DWORD SS:EBP-A0]
0046614E 51 PUSH ECX
0046614F 8D95 70FFFFFF LEA EDX,[DWORD SS:EBP-90]
00466155 52 PUSH EDX
00466156 6A 03 PUSH 3
00466158 FF15 3C104000 CALL [DWORD DS:40103C] ; MSVBVM60.__vbaFreeVarList
0046615E 83C4 10 ADD ESP,10
00466161 83C8 FF OR EAX,FFFFFFFF
00466164 03D8 ADD EBX,EAX
00466166 ^ E9 EDFEFFFF JMP FXRL.00466058
0046616B 50 PUSH EAX ; 循环的最后一轮处理过注册名第2字符'b'后,跳出到这里,准备返回上级
0046616C FF15 40124000 CALL [DWORD DS:401240] ; MSVBVM60.__vbaR8Str
00466172 DC25 20144000 FSUB [QWORD DS:401420]
00466178 DD5D D8 FSTP [QWORD SS:EBP-28]
0046617B FF15 D8104000 CALL [DWORD DS:4010D8] ; MSVBVM60.__vbaExitProc
00466181 9B WAIT
00466182 68 13624600 PUSH FXRL.00466213
00466187 EB 69 JMP SHORT FXRL.004661F2
...
004661F2 8D4D E0 LEA ECX,[DWORD SS:EBP-20]
004661F5 8B35 4C134000 MOV ESI,[DWORD DS:40134C] ; MSVBVM60.__vbaFreeStr
004661FB FFD6 CALL ESI
004661FD 8D4D CC LEA ECX,[DWORD SS:EBP-34]
00466200 FFD6 CALL ESI
00466202 8D4D BC LEA ECX,[DWORD SS:EBP-44]
00466205 8B35 20104000 MOV ESI,[DWORD DS:401020] ; MSVBVM60.__vbaFreeVar
0046620B FFD6 CALL ESI
0046620D 8D4D A4 LEA ECX,[DWORD SS:EBP-5C]
00466210 FFD6 CALL ESI
00466212 C3 RETN
上面返回到下面这部分
004D2BE5 FF15 4C104000 CALL [DWORD DS:40104C] ; MSVBVM60.__vbaFreeObjList
004D2BEB 83C4 0C ADD ESP,0C
004D2BEE C745 FC 1900000>MOV [DWORD SS:EBP-4],19
004D2BF5 E8 862CF9FF CALL FXRL.00465880 ; 调用注册验证部分
004D2BFA DD9D 78FFFFFF FSTP [QWORD SS:EBP-88] ; 验证结果的字串转换成浮点数
004D2C00 DD05 D04B4000 FLD [QWORD DS:404BD0]
004D2C06 DC85 78FFFFFF FADD [QWORD SS:EBP-88] ; 加常数98.0
004D2C0C DC0D C84B4000 FMUL [QWORD DS:404BC8] ; 乘常数3.0
004D2C12 FF15 14114000 CALL [DWORD DS:401114] ; MSVBVM60.__vbaFpR8
004D2C18 DC1D C04B4000 FCOMP [QWORD DS:404BC0] ; 与常数291.0相比,必须相等
004D2C1E DFE0 FSTSW AX
004D2C20 F6C4 40 TEST AH,40
004D2C23 74 0C JE SHORT FXRL.004D2C31 ; 不跳就是注册版
由(0-1+98)*3=291可知,调用返回的字串必须是"0"
总结:
1. 程序自己计算出机器码;用户注册名最少2字符
注册码是数字组成的字串,开头两个字符分别是注册名前两字符ASCII值的十进制个位数字
2. 由机器码前3字符(加法)和后半部分(乘法)计算出RES
TAIL是sqrt(RES)浮点数转换成字符串(长度16,小数部分11位)后的最后5个数字,变成浮点数(整)
W=Int(sqrt(RES)*10000.0)+TAIL,此W后面多次要用到
注册名第1字符ASCII值减7,变成浮点数,设为CA
注册码第3字符开始的余部设为HM
SS=HM-Int(ln(sqrt(W))*100.0)*CA,此SS是最后循环体计算用的初始值
3. 最后,循环倒取注册名各字符,直到第2字符计算过
Cn=当前字符ASCII值减32(转换成浮点数)
D=Int(ln(W)*100.0)
SS=SS-W+Cn+D
循环最后SS要等于0
4. 根据第2步不涉及注册码余部的一些计算结果,对第3步反向循环不难得出初始的SS,由它可得注册码剩余部分
HM=Int(ln(sqrt(W))*100.0)*CA+W*n-(D*n+CN)
其中n是注册名长度减1、CN是注册名除第1字符外各字符ASCII值减32h后的总和(转换成浮点数),Int表示取整,ln表示求自然对数,sqrt表示求平方根。
第一次写这么多,感谢你读完全文!
月中人
于2006年端午节
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!