斗地主7.2版算法分析
[软件介绍]“斗地主”是近来流行全国的一种扑克游戏。
该游戏由四人玩两副牌(108张)或三人玩一副牌(54张),
地主为一方,其余三家或两家为另一方,双方对战,
先出完的一方胜。出牌规则类似“争上游”。
[使用限制] 试用30次和每次7局限制。
[保护方式] 采用机器码与注册名联合检查注册码,以保证注册码不得多机使用。
[破解工具] olldbg1.10 、Peid0.92、Aspackdie1.41,RegSnap
[作者] CrackerWu[BCG]
破解过程:
1.软件信息:
该软件用VB编写,加ASPack 2.12 壳。
用RegSnap可发现试用次数保存在如下两处位置:
---------------------------------------------------------------
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProgrameID
Old value: String: "6" New value: String: "7" HKEY_LOCAL_MACHINE\SOFTWARE\DDZ\Infomation\LicenseNumber
Old value: String: "6" New value: String: "7"
--------------------------------------------------------------
注册码保存在:
[HKEY_LOCAL_MACHINE\SOFTWARE\DDZ\Infomation]
@="斗地主软件信息"
"SetupDir"="d:\\DDZ"
"ProductId"="DDZ070040040530"
"ProductName"="斗地主扑克游戏"
"Writer"="周军"
"Version"="7.2 Build 668"
"LicenseNumber"="7"
"CPUCode"="6659630247"
"LicenseDate"="2005-3-8"
"RegName"="CrackerWu[BCG]"
"RegCode"=" "
"SetupDate"="2005-3-8"
从《斗地主》扑克游戏注册说明及帮助中得到如下信息:
注册名(中英文均可,但至少要两个字符以上),
采用机器码与注册名联合检查注册码
从注册框中输入注册码=10位才能注册。
任意输入注册码:1234567890
重启软件发现软件标题栏中 [未注册]字样消失了,但玩到第7局就回弹出
注册对话框,要求注册。
再运行软件[未注册]字样又出现了。检查注册表发现输入注册码被清除啦。
看来注册流程可能是:
在启动时先检查注册码是否存在,最后到第7局才判断是否正确。
2.脱壳后软件不能正常运行,跟踪可发现在如下位置有自校验:
004AD46D . 52 PUSH EDX
004AD46E . FF15 20134000 CALL DWORD PTR DS:[<&MSVBVM60.#578>] ; MSVBVM60.rtcFileLen
004AD474 . 3D 801A0600 CMP EAX,61A80 ;比较文件长度若大于等于61A80 就玩完啦!
004AD479 7D 07 JGE SHORT unpacked.004AD482 004ADCFD . 52 PUSH EDX
004ADCFE . FF15 20134000 CALL DWORD PTR DS:[<&MSVBVM60.#578>] ; MSVBVM60.rtcFileLen
004ADD04 . 3D 801A0600 CMP EAX,61A80 ;比较文件长度若大于等于61A80 就玩完啦!
004ADD09 7D 07 JGE SHORT unpacked.004ADD12
把上面两处跳转NOP掉,软件可正常运行.
3.用OD载入后通过查找参靠字符串:regcode 发现有10处,全部设断再一一跟踪可看到它是怎样检查注册码的. 下面这段是游戏中每次点击发牌后都要被OD中断在这里:
00440D9E . FF15 B0104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaHresultCheckObj>; MSVBVM60.__vbaHresultCheckObj
00440DA4 > 8B1D F8124000 MOV EBX,DWORD PTR DS:[<&MSVBVM60.__vbaStrCopy>] ; MSVBVM60.__vbaStrCopy
00440DAA . BA DCED4100 MOV EDX,unpacked.0041EDDC ; UNICODE "regcode"
00440DAF . 8D4D DC LEA ECX,DWORD PTR SS:[EBP-24]
00440DB2 . FFD3 CALL EBX ; <&MSVBVM60.__vbaStrCopy>
00440DB4 . BA 90B74100 MOV EDX,unpacked.0041B790 ; UNICODE "SoftWare\DDZ\Infomation"
00440DB9 . 8D4D E0 LEA ECX,DWORD PTR SS:[EBP-20]
00440DBC . FFD3 CALL EBX
00440DBE . 8D45 DC LEA EAX,DWORD PTR SS:[EBP-24]
00440DC1 . 50 PUSH EAX ;"regcode"入栈
00440DC2 . 8D4D E0 LEA ECX,DWORD PTR SS:[EBP-20]
00440DC5 . 51 PUSH ECX ; "SoftWare\DDZ\Infomation"入栈
00440DC6 . 8D55 9C LEA EDX,DWORD PTR SS:[EBP-64]
00440DC9 . 52 PUSH EDX
00440DCA . C745 9C 020000>MOV DWORD PTR SS:[EBP-64],80000002
00440DD1 . E8 9A060600 CALL unpacked.004A1470 ;调用一个通用子程序从注册表中读取注册码。
00440DD6 . 8BD0 MOV EDX,EAX
00440DD8 . 8D4D D8 LEA ECX,DWORD PTR SS:[EBP-28]
00440DDB . FF15 98134000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrMove>] ; MSVBVM60.__vbaStrMove
00440DE1 . 50 PUSH EAX
00440DE2 . 68 38B84100 PUSH unpacked.0041B838
00440DE7 . FF15 A4114000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrCmp>] ; MSVBVM60.__vbaStrCmp
00440DED . 8B55 A0 MOV EDX,DWORD PTR SS:[EBP-60]
00440DF0 . 8BF0 MOV ESI,EAX
00440DF2 . F7DE NEG ESI
00440DF4 . 1BF6 SBB ESI,ESI
00440DF6 . 46 INC ESI
00440DF7 . 8D45 D8 LEA EAX,DWORD PTR SS:[EBP-28]
00440DFA . 50 PUSH EAX
00440DFB . F7DE NEG ESI
00440DFD . 8D4D DC LEA ECX,DWORD PTR SS:[EBP-24]
00440E00 . 0BF2 OR ESI,EDX
00440E02 . 51 PUSH ECX
00440E03 . 8D55 E0 LEA EDX,DWORD PTR SS:[EBP-20]
00440E06 . 52 PUSH EDX
00440E07 . 6A 03 PUSH 3
00440E09 . FF15 08134000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeStrList>] ; MSVBVM60.__vbaFreeStrList
00440E0F . 83C4 10 ADD ESP,10
00440E12 . 8D4D D4 LEA ECX,DWORD PTR SS:[EBP-2C]
00440E15 . FF15 E4134000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeObj>] ; MSVBVM60.__vbaFreeObj
00440E1B . 66:85F6 TEST SI,SI ;(爆破可改为 xor si,si 保正一定跳过下面限制)
00440E1E . 0F84 62020000 JE unpacked.00441086 ;SI若为零就跳过试用30次和每次7局限制.
00440E24 . 833D 3C335200 >CMP DWORD PTR DS:[52333C],1E ;比较试用次数时否大于30次
00440E2B . 7D 1B JGE SHORT unpacked.00440E48
00440E2D . 833D 70315200 >CMP DWORD PTR DS:[523170],7 ;比较游戏局数时否小于7局
00440E34 . 0F8C 4C020000 JL unpacked.00441086
00440E3A . 66:833D 003152>CMP WORD PTR DS:[523100],0
00440E42 . 0F85 3E020000 JNZ unpacked.00441086
00440E48 > 66:833D 003152>CMP WORD PTR DS:[523100],0
00440E50 . 75 0A JNZ SHORT unpacked.00440E5C
00440E52 . 66:833D 403352>CMP WORD PTR DS:[523340],0
00440E5A . 74 2A JE SHORT unpacked.00440E86
00440E5C > 8B07 MOV EAX,DWORD PTR DS:[EDI]
00440E5E . 8D4D A0 LEA ECX,DWORD PTR SS:[EBP-60]
00440E61 . 51 PUSH ECX
00440E62 . 57 PUSH EDI 当游戏玩到第7局时被OD首先中断在这里 : 004599F4 . BA DCED4100 MOV EDX,unpacked.0041EDDC ; UNICODE "regcode"
004599F9 . 8D4D C0 LEA ECX,DWORD PTR SS:[EBP-40]
004599FC . 897D E8 MOV DWORD PTR SS:[EBP-18],EDI
004599FF . 897D E0 MOV DWORD PTR SS:[EBP-20],EDI
00459A02 . 897D D4 MOV DWORD PTR SS:[EBP-2C],EDI
00459A05 . 897D D0 MOV DWORD PTR SS:[EBP-30],EDI
00459A08 . 897D CC MOV DWORD PTR SS:[EBP-34],EDI
00459A0B . 897D C8 MOV DWORD PTR SS:[EBP-38],EDI
00459A0E . 897D C4 MOV DWORD PTR SS:[EBP-3C],EDI
00459A11 . 897D C0 MOV DWORD PTR SS:[EBP-40],EDI
00459A14 . 897D BC MOV DWORD PTR SS:[EBP-44],EDI
00459A17 . 897D B8 MOV DWORD PTR SS:[EBP-48],EDI
00459A1A . 897D B4 MOV DWORD PTR SS:[EBP-4C],EDI
00459A1D . 897D A4 MOV DWORD PTR SS:[EBP-5C],EDI
00459A20 . 897D 94 MOV DWORD PTR SS:[EBP-6C],EDI
00459A23 . 897D 84 MOV DWORD PTR SS:[EBP-7C],EDI
00459A26 . 89BD 74FFFFFF MOV DWORD PTR SS:[EBP-8C],EDI
00459A2C . 89BD 70FFFFFF MOV DWORD PTR SS:[EBP-90],EDI
00459A32 . 89BD 6CFFFFFF MOV DWORD PTR SS:[EBP-94],EDI
00459A38 . FFD3 CALL EBX ; <&MSVBVM60.__vbaStrCopy>
00459A3A . BA 90B74100 MOV EDX,unpacked.0041B790 ; UNICODE "SoftWare\DDZ\Infomation"
00459A3F . 8D4D C4 LEA ECX,DWORD PTR SS:[EBP-3C]
00459A42 . FFD3 CALL EBX
00459A44 . 8D45 C0 LEA EAX,DWORD PTR SS:[EBP-40]
00459A47 . 50 PUSH EAX "regcode"入栈
00459A48 . 8D4D C4 LEA ECX,DWORD PTR SS:[EBP-3C]
00459A4B . 51 PUSH ECX ;"SoftWare\DDZ\Infomation"入栈
00459A4C . 8D95 6CFFFFFF LEA EDX,DWORD PTR SS:[EBP-94]
00459A52 . 52 PUSH EDX
00459A53 . C785 6CFFFFFF >MOV DWORD PTR SS:[EBP-94],80000002
00459A5D . E8 0E7A0400 CALL unpacked.004A1470 ;调用一个通用子程序从注册表中读取注册码。
00459A62 . 8B35 98134000 MOV ESI,DWORD PTR DS:[<&MSVBVM60.__vbaStrMove>] ; MSVBVM60.__vbaStrMove
00459A68 . 8BD0 MOV EDX,EAX
00459A6A . 8D4D CC LEA ECX,DWORD PTR SS:[EBP-34]
00459A6D . FFD6 CALL ESI ; <&MSVBVM60.__vbaStrMove>
00459A6F . 8D45 C0 LEA EAX,DWORD PTR SS:[EBP-40]
00459A72 . 50 PUSH EAX
00459A73 . 8D4D C4 LEA ECX,DWORD PTR SS:[EBP-3C]
00459A76 . 51 PUSH ECX
00459A77 . 6A 02 PUSH 2
00459A79 . FF15 08134000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeStrList>] ; MSVBVM60.__vbaFreeStrList
00459A7F . 83C4 0C ADD ESP,0C
00459A82 . BA E0064200 MOV EDX,unpacked.004206E0 ; UNICODE "regname"
00459A87 . 8D4D C0 LEA ECX,DWORD PTR SS:[EBP-40]
00459A8A . FFD3 CALL EBX
00459A8C . BA 90B74100 MOV EDX,unpacked.0041B790 ; UNICODE "SoftWare\DDZ\Infomation"
00459A91 . 8D4D C4 LEA ECX,DWORD PTR SS:[EBP-3C]
00459A94 . FFD3 CALL EBX
00459A96 . 8D55 C0 LEA EDX,DWORD PTR SS:[EBP-40]
00459A99 . 52 PUSH EDX ;"regname"入栈
00459A9A . 8D45 C4 LEA EAX,DWORD PTR SS:[EBP-3C]
00459A9D . 50 PUSH EAX ;"SoftWare\DDZ\Infomation"入栈
00459A9E . 8D8D 6CFFFFFF LEA ECX,DWORD PTR SS:[EBP-94]
00459AA4 . 51 PUSH ECX
00459AA5 . C785 6CFFFFFF >MOV DWORD PTR SS:[EBP-94],80000002
00459AAF . E8 BC790400 CALL unpacked.004A1470 ; 调用一个通用子程序从注册表中读取注册名
;返回注册名字符放在eax中
00459AB4 . 8D55 A4 LEA EDX,DWORD PTR SS:[EBP-5C]
00459AB7 . 8945 AC MOV DWORD PTR SS:[EBP-54],EAX
00459ABA . 52 PUSH EDX
00459ABB . 8D45 94 LEA EAX,DWORD PTR SS:[EBP-6C]
00459ABE . 50 PUSH EAX
00459ABF . C745 A4 080000>MOV DWORD PTR SS:[EBP-5C],8
00459AC6 . FF15 80104000 CALL DWORD PTR DS:[<&MSVBVM60.#518>] ; MSVBVM60.rtcLowerCaseVar
;注册名字符转为小写
00459ACC . 8D4D 94 LEA ECX,DWORD PTR SS:[EBP-6C]
00459ACF . 51 PUSH ECX
00459AD0 . FF15 38104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrVarMove>] ; MSVBVM60.__vbaStrVarMove
00459AD6 . 8BD0 MOV EDX,EAX
00459AD8 . 8D4D D0 LEA ECX,DWORD PTR SS:[EBP-30]
00459ADB . FFD6 CALL ESI
00459ADD . 8D55 C0 LEA EDX,DWORD PTR SS:[EBP-40]
00459AE0 . 52 PUSH EDX
00459AE1 . 8D45 C4 LEA EAX,DWORD PTR SS:[EBP-3C]
00459AE4 . 50 PUSH EAX
00459AE5 . 6A 02 PUSH 2
00459AE7 . FF15 08134000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeStrList>] ; MSVBVM60.__vbaFreeStrList
00459AED . 8D4D 94 LEA ECX,DWORD PTR SS:[EBP-6C]
00459AF0 . 51 PUSH ECX
00459AF1 . 8D55 A4 LEA EDX,DWORD PTR SS:[EBP-5C]
00459AF4 . 52 PUSH EDX
00459AF5 . 6A 02 PUSH 2
00459AF7 . FF15 44104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeVarList>] ; MSVBVM60.__vbaFreeVarList
00459AFD . 8B45 CC MOV EAX,DWORD PTR SS:[EBP-34]
00459B00 . 83C4 18 ADD ESP,18
00459B03 . 50 PUSH EAX ;注册码入栈
00459B04 . FF15 40104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaLenBstr>] ; MSVBVM60.__vbaLenBstr
;求注册码长度
00459B0A . 8B4D D0 MOV ECX,DWORD PTR SS:[EBP-30]
00459B0D . 33DB XOR EBX,EBX
00459B0F . 83F8 0A CMP EAX,0A ; 比较注册码长度是否10位
00459B12 . 51 PUSH ECX ;注册名入栈
00459B13 . 0F95C3 SETNE BL
00459B16 . FF15 40104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaLenBstr>] ; MSVBVM60.__vbaLenBstr
;求注册名长度
00459B1C . 33D2 XOR EDX,EDX
00459B1E . 83F8 01 CMP EAX,1 ; 比较注册名长度是否大于1位
00459B21 . 0F9EC2 SETLE DL
00459B24 . 0BDA OR EBX,EDX ;只要不满作上两条就跳
00459B26 . 0F85 08040000 JNZ unpacked.00459F34 ;跳就是注册不正确
00459B2C . 6A 07 PUSH 7
00459B2E . 8D45 84 LEA EAX,DWORD PTR SS:[EBP-7C]
00459B31 . 50 PUSH EAX
00459B32 . 8D4D A4 LEA ECX,DWORD PTR SS:[EBP-5C]
00459B35 . 51 PUSH ECX
00459B36 . C745 8C 183452>MOV DWORD PTR SS:[EBP-74],unpacked.00523418
00459B3D . C745 84 084000>MOV DWORD PTR SS:[EBP-7C],4008
00459B44 . FF15 AC134000 CALL DWORD PTR DS:[<&MSVBVM60.#619>] ; MSVBVM60.rtcRightCharVar
;取机器码右边7个字符
00459B4A . 8B55 D0 MOV EDX,DWORD PTR SS:[EBP-30]
00459B4D . 8D45 A4 LEA EAX,DWORD PTR SS:[EBP-5C]
00459B50 . 50 PUSH EAX
00459B51 . 8D8D 74FFFFFF LEA ECX,DWORD PTR SS:[EBP-8C]
00459B57 . 8995 7CFFFFFF MOV DWORD PTR SS:[EBP-84],EDX
00459B5D . 51 PUSH ECX
00459B5E . 8D55 94 LEA EDX,DWORD PTR SS:[EBP-6C]
00459B61 . 52 PUSH EDX
00459B62 . C785 74FFFFFF >MOV DWORD PTR SS:[EBP-8C],8
00459B6C . FF15 98124000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarCat>] ; MSVBVM60.__vbaVarCat
;机器码右边7个字符与注册名连接成一个字符串
00459B72 . 50 PUSH EAX
00459B73 . FF15 38104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrVarMove>] ; MSVBVM60.__vbaStrVarMove
00459B79 . 8BD0 MOV EDX,EAX
00459B7B . 8D4D D4 LEA ECX,DWORD PTR SS:[EBP-2C]
00459B7E . FFD6 CALL ESI
00459B80 . 8D45 94 LEA EAX,DWORD PTR SS:[EBP-6C]
00459B83 . 50 PUSH EAX
00459B84 . 8D4D A4 LEA ECX,DWORD PTR SS:[EBP-5C]
00459B87 . 51 PUSH ECX
00459B88 . 6A 02 PUSH 2
00459B8A . FF15 44104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeVarList>] ; MSVBVM60.__vbaFreeVarList
00459B90 . 83C4 0C ADD ESP,0C
00459B93 . 8D55 D4 LEA EDX,DWORD PTR SS:[EBP-2C]
00459B96 . 52 PUSH EDX ;上面机器码与注册名连接字符串入栈
00459B97 . E8 34340500 CALL unpacked.004ACFD0 ;计算注册码关键call !!!!!!!!!!!!!!
00459B9C . 8BD0 MOV EDX,EAX
00459B9E . 8D4D C8 LEA ECX,DWORD PTR SS:[EBP-38]
00459BA1 . FFD6 CALL ESI
00459BA3 . 8B45 CC MOV EAX,DWORD PTR SS:[EBP-34]
00459BA6 . 8B4D C8 MOV ECX,DWORD PTR SS:[EBP-38]
00459BA9 . 50 PUSH EAX ;注册表中保存注册码入栈
00459BAA . 51 PUSH ECX ;程序计算注册码入栈
00459BAB . FF15 A4114000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrCmp>] ; MSVBVM60.__vbaStrCmp
;比较注册码
00459BB1 . 85C0 TEST EAX,EAX
00459BB3 . 75 2F JNZ SHORT unpacked.00459BE4 ;跳向未注册(标题栏出现了[未注册]字样)。
..............................
跳出上面子称序后来到这段>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
00447876 > C785 E8FEFFFF >MOV DWORD PTR SS:[EBP-118],0
00447880 > C745 FC 480000>MOV DWORD PTR SS:[EBP-4],48
00447887 . A1 70315200 MOV EAX,DWORD PTR DS:[523170]
0044788C . 99 CDQ
0044788D . B9 07000000 MOV ECX,7
00447892 . F7F9 IDIV ECX ;游戏局数除7
00447894 . 83FA 06 CMP EDX,6 ; 比较是否为6,为6就检查注册.
(可修改这里让游系每局都检查注册,方便我们跟踪)
00447897 . 75 16 JNZ SHORT unpacked.004478AF
00447899 . C745 FC 490000>MOV DWORD PTR SS:[EBP-4],49
004478A0 . 8B55 08 MOV EDX,DWORD PTR SS:[EBP+8]
004478A3 . 8B02 MOV EAX,DWORD PTR DS:[EDX]
004478A5 . 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+8]
004478A8 . 51 PUSH ECX
004478A9 . FF90 D4080000 CALL DWORD PTR DS:[EAX+8D4] ;检查用户是否已注册 call
004478AF > C745 FC 4B0000>MOV DWORD PTR SS:[EBP-4],4B ;跳出上面子称序后来到这里。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 下面跟进计算注册码关键call :
*************************************************************************************
004ACFD0 $ 55 PUSH EBP
004ACFD1 . 8BEC MOV EBP,ESP
004ACFD3 . 83EC 0C SUB ESP,0C
004ACFD6 . 68 A6924000 PUSH <JMP.&MSVBVM60.__vbaExceptHandler> ; SE handler installation
004ACFDB . 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
004ACFE1 . 50 PUSH EAX
004ACFE2 . 64:8925 000000>MOV DWORD PTR FS:[0],ESP
004ACFE9 . 81EC 9C000000 SUB ESP,9C
004ACFEF . 53 PUSH EBX
004ACFF0 . 56 PUSH ESI
004ACFF1 . 57 PUSH EDI
004ACFF2 . 8965 F4 MOV DWORD PTR SS:[EBP-C],ESP
004ACFF5 . C745 F8 505C40>MOV DWORD PTR SS:[EBP-8],unpacked.00405C50
004ACFFC . 8B5D 08 MOV EBX,DWORD PTR SS:[EBP+8] ;机器码与注册名连接字符串送EBX
004ACFFF . 33C0 XOR EAX,EAX
004AD001 . BE 01000000 MOV ESI,1 ;esi=1
004AD006 . 33C9 XOR ECX,ECX
004AD008 . 8945 D4 MOV DWORD PTR SS:[EBP-2C],EAX
004AD00B . 8945 D0 MOV DWORD PTR SS:[EBP-30],EAX
004AD00E . 8945 CC MOV DWORD PTR SS:[EBP-34],EAX
004AD011 . 8945 C8 MOV DWORD PTR SS:[EBP-38],EAX
004AD014 . 8945 C4 MOV DWORD PTR SS:[EBP-3C],EAX
004AD017 . 8945 C0 MOV DWORD PTR SS:[EBP-40],EAX
004AD01A . 8945 B0 MOV DWORD PTR SS:[EBP-50],EAX
004AD01D . 8945 A0 MOV DWORD PTR SS:[EBP-60],EAX
004AD020 . 8945 90 MOV DWORD PTR SS:[EBP-70],EAX
004AD023 . 8945 80 MOV DWORD PTR SS:[EBP-80],EAX
004AD026 . 894D DC MOV DWORD PTR SS:[EBP-24],ECX
004AD029 . 8945 D8 MOV DWORD PTR SS:[EBP-28],EAX
004AD02C . 8BFE MOV EDI,ESI ;循环变量edi=esi=1
004AD02E > B8 05000000 MOV EAX,5 ;循环开始 ,eax=5
004AD033 . 3BF8 CMP EDI,EAX ;比较循还次数是否大于5
004AD035 . 0F8F 94010000 JG unpacked.004AD1CF ;大于就跳出循环 (循环中第一部分)
004AD03B . 50 PUSH EAX ;5入栈
004AD03C . 8D45 80 LEA EAX,DWORD PTR SS:[EBP-80]
004AD03F . 50 PUSH EAX
004AD040 . 8D4D B0 LEA ECX,DWORD PTR SS:[EBP-50]
004AD043 . 51 PUSH ECX
004AD044 . 895D 88 MOV DWORD PTR SS:[EBP-78],EBX ;机器码与注册名连接字符串送[EBP-78]
004AD047 . C745 80 084000>MOV DWORD PTR SS:[EBP-80],4008
004AD04E . FF15 88134000 CALL DWORD PTR DS:[<&MSVBVM60.#617>] ; MSVBVM60.rtcLeftCharVar
;取机器码与注册名连接字符串左边5个字符组成字符串
;(为叙述方便设为L5)
004AD054 . 8D55 A0 LEA EDX,DWORD PTR SS:[EBP-60]
004AD057 . 52 PUSH EDX
004AD058 . 56 PUSH ESI
004AD059 . 8D45 B0 LEA EAX,DWORD PTR SS:[EBP-50] ;L5入栈
004AD05C . 50 PUSH EAX
004AD05D . 8D4D 90 LEA ECX,DWORD PTR SS:[EBP-70] ;[EBP-70]为返回值地址
004AD060 . 51 PUSH ECX
004AD061 . C745 A8 010000>MOV DWORD PTR SS:[EBP-58],1
004AD068 . C745 A0 020000>MOV DWORD PTR SS:[EBP-60],2
004AD06F . FF15 84114000 CALL DWORD PTR DS:[<&MSVBVM60.#632>] ; MSVBVM60.rtcMidCharVar
;依次取L5每个字符
004AD075 . 8D55 90 LEA EDX,DWORD PTR SS:[EBP-70]
004AD078 . 52 PUSH EDX
004AD079 . 8D45 C4 LEA EAX,DWORD PTR SS:[EBP-3C]
004AD07C . 50 PUSH EAX
004AD07D . FF15 94124000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrVarVal>] ; MSVBVM60.__vbaStrVarVal
;转字符
004AD083 . 50 PUSH EAX
004AD084 . FF15 20104000 CALL DWORD PTR DS:[<&MSVBVM60.#693>] ; MSVBVM60.rtcByteValueBstr
;求字符字节ASCII值
004AD08A . 8885 6CFFFFFF MOV BYTE PTR SS:[EBP-94],AL ;L5每个字符字节ASCII值依次送[EBP-94]
004AD090 . B8 05000000 MOV EAX,5
004AD095 . 2BC7 SUB EAX,EDI ;5减 循环变量edi值
004AD097 . 8985 58FFFFFF MOV DWORD PTR SS:[EBP-A8],EAX ;送到[EBP-A8]
004AD09D . DB85 58FFFFFF FILD DWORD PTR SS:[EBP-A8] ;装入浮点寄存器
004AD0A3 . 83EC 08 SUB ESP,8
004AD0A6 . DD1C24 FSTP QWORD PTR SS:[ESP]
004AD0A9 . 68 00002440 PUSH 40240000
004AD0AE . 6A 00 PUSH 0
004AD0B0 . FF15 18134000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaPowerR8>] ; MSVBVM60.__vbaPowerR8
;求10的乘方.
;依次为求:10的4次方,10的3次方,10的2次方,10的1次方,10的0次方.
004AD0B6 . 8B85 6CFFFFFF MOV EAX,DWORD PTR SS:[EBP-94]
004AD0BC . 25 FF000000 AND EAX,0FF
004AD0C1 . 99 CDQ
004AD0C2 . B9 0A000000 MOV ECX,0A ;L5每个字符ASCII码值除10
004AD0C7 . F7F9 IDIV ECX
004AD0C9 . 8995 54FFFFFF MOV DWORD PTR SS:[EBP-AC],EDX ;余数送[EBP-AC]
004AD0CF . DB85 54FFFFFF FILD DWORD PTR SS:[EBP-AC] ;[EBP-AC]装入浮点寄存器
004AD0D5 . DEC9 FMULP ST(1),ST ;余数与上面10的乘方相乘
004AD0D7 . DA45 DC FIADD DWORD PTR SS:[EBP-24] ;循环累加到[EBP-24]
004AD0DA . FF15 6C134000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFpI4>] ; MSVBVM60.__vbaFpI4
;转整数
004AD0E0 . 8D4D C4 LEA ECX,DWORD PTR SS:[EBP-3C]
004AD0E3 . 8945 DC MOV DWORD PTR SS:[EBP-24],EAX ;整数值送[EBP-24]
004AD0E6 . FF15 E8134000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeStr>] ; MSVBVM60.__vbaFreeStr
004AD0EC . 8D55 90 LEA EDX,DWORD PTR SS:[EBP-70]
004AD0EF . 52 PUSH EDX
004AD0F0 . 8D45 A0 LEA EAX,DWORD PTR SS:[EBP-60]
004AD0F3 . 50 PUSH EAX
004AD0F4 . 8D4D B0 LEA ECX,DWORD PTR SS:[EBP-50]
004AD0F7 . 51 PUSH ECX
004AD0F8 . 6A 03 PUSH 3
004AD0FA . FF15 44104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeVarList>] ; MSVBVM60.__vbaFreeVarList
004AD100 . 83C4 10 ADD ESP,10
(循环中第二部分)
004AD103 . 6A 05 PUSH 5 ;5入栈
004AD105 . 8D55 80 LEA EDX,DWORD PTR SS:[EBP-80]
004AD108 . 52 PUSH EDX
004AD109 . 8D45 B0 LEA EAX,DWORD PTR SS:[EBP-50]
004AD10C . 50 PUSH EAX
004AD10D . 895D 88 MOV DWORD PTR SS:[EBP-78],EBX ; 机器码与注册名连接字符串送[EBP-78]
004AD110 . C745 80 084000>MOV DWORD PTR SS:[EBP-80],4008
004AD117 . FF15 AC134000 CALL DWORD PTR DS:[<&MSVBVM60.#619>] ; MSVBVM60.rtcRightCharVar
;取机器码与注册名连接字符串右边5个字符组成字符串
;(为叙述方便设为R5)
004AD11D . 8D4D A0 LEA ECX,DWORD PTR SS:[EBP-60]
004AD120 . 51 PUSH ECX
004AD121 . 56 PUSH ESI ;初始为1
004AD122 . 8D55 B0 LEA EDX,DWORD PTR SS:[EBP-50]
004AD125 . 52 PUSH EDX ;R5入栈
004AD126 . 8D45 90 LEA EAX,DWORD PTR SS:[EBP-70] ;[EBP-70]为返回值地址
004AD129 . 50 PUSH EAX
004AD12A . C745 A8 010000>MOV DWORD PTR SS:[EBP-58],1
004AD131 . C745 A0 020000>MOV DWORD PTR SS:[EBP-60],2
004AD138 . FF15 84114000 CALL DWORD PTR DS:[<&MSVBVM60.#632>] ; MSVBVM60.rtcMidCharVar
;依次取R5每个字符
004AD13E . 8D4D 90 LEA ECX,DWORD PTR SS:[EBP-70]
004AD141 . 51 PUSH ECX
004AD142 . 8D55 C4 LEA EDX,DWORD PTR SS:[EBP-3C]
004AD145 . 52 PUSH EDX
004AD146 . FF15 94124000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrVarVal>] ; MSVBVM60.__vbaStrVarVal
;转字符
004AD14C . 50 PUSH EAX
004AD14D . FF15 20104000 CALL DWORD PTR DS:[<&MSVBVM60.#693>] ; MSVBVM60.rtcByteValueBstr
;求字符字节ASCII值 (当为汉字时取的是低位字节)
004AD153 . DB85 58FFFFFF FILD DWORD PTR SS:[EBP-A8] ; [EBP-A8]装入浮点寄存器
004AD159 . 83EC 08 SUB ESP,8
004AD15C . 8885 6CFFFFFF MOV BYTE PTR SS:[EBP-94],AL ;L5每个字符字节ASCII值依次送[EBP-94]
004AD162 . DD1C24 FSTP QWORD PTR SS:[ESP]
004AD165 . 68 00002440 PUSH 40240000
004AD16A . 6A 00 PUSH 0
004AD16C . FF15 18134000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaPowerR8>] ; MSVBVM60.__vbaPowerR8
;求10的乘方.
004AD172 . 8B85 6CFFFFFF MOV EAX,DWORD PTR SS:[EBP-94]
004AD178 . 25 FF000000 AND EAX,0FF
004AD17D . 99 CDQ
004AD17E . B9 0A000000 MOV ECX,0A
004AD183 . F7F9 IDIV ECX ;除10
004AD185 . 8995 50FFFFFF MOV DWORD PTR SS:[EBP-B0],EDX
004AD18B . DB85 50FFFFFF FILD DWORD PTR SS:[EBP-B0]
004AD191 . DEC9 FMULP ST(1),ST ;余数与上面10的乘方相乘
004AD193 . DA45 D8 FIADD DWORD PTR SS:[EBP-28] ;循环累加到[EBP-28]
004AD196 . FF15 6C134000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFpI4>] ; MSVBVM60.__vbaFpI4
;转整数
004AD19C . 8D4D C4 LEA ECX,DWORD PTR SS:[EBP-3C]
004AD19F . 8945 D8 MOV DWORD PTR SS:[EBP-28],EAX ; 整数值送[EBP-28]
004AD1A2 . FF15 E8134000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeStr>] ; MSVBVM60.__vbaFreeStr
004AD1A8 . 8D55 90 LEA EDX,DWORD PTR SS:[EBP-70]
004AD1AB . 52 PUSH EDX
004AD1AC . 8D45 A0 LEA EAX,DWORD PTR SS:[EBP-60]
004AD1AF . 50 PUSH EAX
004AD1B0 . 8D4D B0 LEA ECX,DWORD PTR SS:[EBP-50]
004AD1B3 . 51 PUSH ECX
004AD1B4 . 6A 03 PUSH 3
004AD1B6 . FF15 44104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeVarList>] ; MSVBVM60.__vbaFreeVarList
004AD1BC . 8B4D DC MOV ECX,DWORD PTR SS:[EBP-24] ;[EBP-24]中值送[EBP-24]
004AD1BF . 83C4 10 ADD ESP,10
004AD1C2 . B8 01000000 MOV EAX,1
004AD1C7 . 46 INC ESI ;esi加1
004AD1C8 . 03F8 ADD EDI,EAX ;edi加1
004AD1CA .^E9 5FFEFFFF JMP unpacked.004AD02E ;跳向循环开头 循环结束后来到这里:
004AD1CF > 8B55 D8 MOV EDX,DWORD PTR SS:[EBP-28]
004AD1D2 . 81F1 CADE0000 XOR ECX,0DECA ; 上面第一部分累加值与57034(十进制)作异或
004AD1D8 . 81F2 13700000 XOR EDX,7013 ; 上面第二部分累加值与28691(十进制)作异或
004AD1DE . 81F9 9F860100 CMP ECX,1869F ; 与99999作比较,若大于就转为小于99999的数
004AD1E4 . 8955 D8 MOV DWORD PTR SS:[EBP-28],EDX ;异或值[EBP-28]
004AD1E7 . 7E 16 JLE SHORT unpacked.004AD1FF ;
________________________________________________________________________
004AD1E9 . B8 67666666 MOV EAX,66666667 ;这段是把ECX中数转为小于99999(十进制)的数
004AD1EE . F7E9 IMUL ECX
004AD1F0 . C1FA 02 SAR EDX,2
004AD1F3 . 8BC2 MOV EAX,EDX
004AD1F5 . C1E8 1F SHR EAX,1F
004AD1F8 . 03D0 ADD EDX,EAX
004AD1FA . 8955 DC MOV DWORD PTR SS:[EBP-24],EDX
004AD1FD . 8BCA MOV ECX,EDX
_________________________________________________________________________
004AD1FF > BE 10270000 MOV ESI,2710 ;ESI=10000(十进制)
004AD204 . 3BCE CMP ECX,ESI ;与10000(十进制)作比较,若小于就加10000
004AD206 . 7D 02 JGE SHORT unpacked.004AD20A
004AD208 . 03CE ADD ECX,ESI ;加10000(十进制)
----------------------------------------------对第二部分异或值作同样处理(保证数为5位,在10000--99999之间)
004AD20A > 8B55 D8 MOV EDX,DWORD PTR SS:[EBP-28]
004AD20D . 81FA 9F860100 CMP EDX,1869F
004AD213 . 7E 14 JLE SHORT unpacked.004AD229
004AD215 . B8 67666666 MOV EAX,66666667
004AD21A . F7EA IMUL EDX
004AD21C . C1FA 02 SAR EDX,2
004AD21F . 8BC2 MOV EAX,EDX
004AD221 . C1E8 1F SHR EAX,1F
004AD224 . 03D0 ADD EDX,EAX
004AD226 . 8955 D8 MOV DWORD PTR SS:[EBP-28],EDX
004AD229 > 8B45 D8 MOV EAX,DWORD PTR SS:[EBP-28]
004AD22C . 3BC6 CMP EAX,ESI
004AD22E . 7D 05 JGE SHORT unpacked.004AD235
004AD230 . 03C6 ADD EAX,ESI
004AD232 . 8945 D8 MOV DWORD PTR SS:[EBP-28],EAX
-------------------------------------------------------------
004AD235 > 8B3D 18104000 MOV EDI,DWORD PTR DS:[<&MSVBVM60.__vbaStrI4>] ; MSVBVM60.__vbaStrI4
004AD23B . 51 PUSH ECX
004AD23C . FFD7 CALL EDI ; <&MSVBVM60.__vbaStrI4>
;整数转字符串
004AD23E . 8B35 98134000 MOV ESI,DWORD PTR DS:[<&MSVBVM60.__vbaStrMove>] ; MSVBVM60.__vbaStrMove
004AD244 . 8BD0 MOV EDX,EAX
004AD246 . 8D4D C4 LEA ECX,DWORD PTR SS:[EBP-3C]
004AD249 . FFD6 CALL ESI ; <&MSVBVM60.__vbaStrMove>
004AD24B . 8B4D D8 MOV ECX,DWORD PTR SS:[EBP-28]
004AD24E . 50 PUSH EAX
004AD24F . 51 PUSH ECX
004AD250 . FFD7 CALL EDI ;整数转字符串
004AD252 . 8BD0 MOV EDX,EAX
004AD254 . 8D4D C0 LEA ECX,DWORD PTR SS:[EBP-40]
004AD257 . FFD6 CALL ESI
004AD259 . 50 PUSH EAX
004AD25A . FF15 98104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrCat>] ; MSVBVM60.__vbaStrCat
;连结字符串得到注册码
004AD260 . 8BD0 MOV EDX,EAX
004AD262 . 8D4D CC LEA ECX,DWORD PTR SS:[EBP-34]
004AD265 . FFD6 CALL ESI
004AD267 . 8D55 C0 LEA EDX,DWORD PTR SS:[EBP-40]
004AD26A . 52 PUSH EDX
004AD26B . 8D45 C4 LEA EAX,DWORD PTR SS:[EBP-3C]
004AD26E . 50 PUSH EAX
004AD26F . 6A 02 PUSH 2
004AD271 . FF15 08134000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeStrList>] ; MSVBVM60.__vbaFreeStrList
004AD277 . 8B55 CC MOV EDX,DWORD PTR SS:[EBP-34]
004AD27A . 83C4 0C ADD ESP,0C
004AD27D . 8D4D D4 LEA ECX,DWORD PTR SS:[EBP-2C]
004AD280 . FF15 F8124000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrCopy>] ; MSVBVM60.__vbaStrCopy
004AD286 . 9B WAIT
004AD287 . 68 DBD24A00 PUSH unpacked.004AD2DB
004AD28C . EB 37 JMP SHORT unpacked.004AD2C5
004AD28E . F645 FC 04 TEST BYTE PTR SS:[EBP-4],4
004AD292 . 74 09 JE SHORT unpacked.004AD29D
004AD294 . 8D4D D4 LEA ECX,DWORD PTR SS:[EBP-2C]
004AD297 . FF15 E8134000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeStr>] ; MSVBVM60.__vbaFreeStr
004AD29D > 8D4D C0 LEA ECX,DWORD PTR SS:[EBP-40]
004AD2A0 . 51 PUSH ECX
004AD2A1 . 8D55 C4 LEA EDX,DWORD PTR SS:[EBP-3C]
004AD2A4 . 52 PUSH EDX
004AD2A5 . 6A 02 PUSH 2
004AD2A7 . FF15 08134000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeStrList>] ; MSVBVM60.__vbaFreeStrList
004AD2AD . 8D45 90 LEA EAX,DWORD PTR SS:[EBP-70]
004AD2B0 . 50 PUSH EAX
004AD2B1 . 8D4D A0 LEA ECX,DWORD PTR SS:[EBP-60]
004AD2B4 . 51 PUSH ECX
004AD2B5 . 8D55 B0 LEA EDX,DWORD PTR SS:[EBP-50]
004AD2B8 . 52 PUSH EDX
004AD2B9 . 6A 03 PUSH 3
004AD2BB . FF15 44104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeVarList>] ; MSVBVM60.__vbaFreeVarList
004AD2C1 . 83C4 1C ADD ESP,1C
004AD2C4 . C3 RETN
004AD2C5 > 8B35 E8134000 MOV ESI,DWORD PTR DS:[<&MSVBVM60.__vbaFreeStr>] ; MSVBVM60.__vbaFreeStr
004AD2CB . 8D4D D0 LEA ECX,DWORD PTR SS:[EBP-30]
004AD2CE . FFD6 CALL ESI ; <&MSVBVM60.__vbaFreeStr>
004AD2D0 . 8D4D CC LEA ECX,DWORD PTR SS:[EBP-34]
004AD2D3 . FFD6 CALL ESI
004AD2D5 . 8D4D C8 LEA ECX,DWORD PTR SS:[EBP-38]
004AD2D8 . FFD6 CALL ESI
004AD2DA . C3 RETN
004AD2DB . 8B4D EC MOV ECX,DWORD PTR SS:[EBP-14]
004AD2DE . 8B45 D4 MOV EAX,DWORD PTR SS:[EBP-2C]
004AD2E1 . 5F POP EDI
004AD2E2 . 5E POP ESI
004AD2E3 . 64:890D 000000>MOV DWORD PTR FS:[0],ECX
004AD2EA . 5B POP EBX
004AD2EB . 8BE5 MOV ESP,EBP
004AD2ED . 5D POP EBP
004AD2EE . C2 0400 RETN 4
***********************************************************************************************
4.算法总结:
以我的机器为例:
机器码: 6654554209
用户名: CrackerWu[BCG]
-------------------------------------------------------
取机器码右边7个字符: 4554209
用户名大写转小写得到: crackerwu[bcg]
与用户名字符串连结得到: 4554209crackerwu[bcg]
取左边5个字符得到:45542
取右边5个字符得到:[bcg]
字符 "4" 的ASCII值除10余数:52 mod 10 =2
字符 "5" 的ASCII值除10余数:53 mod 10 =3
字符 "5" 的ASCII值除10余数:53 mod 10 =3
字符 "4" 的ASCII值除10余数:52 mod 10 =2
字符 "2" 的ASCII值除10余数:50 mod 10 =0
2 x 10^4+3 x 10^3+3 x 10^2+2x 10^1+0 x 10^0=2320
( 若累加和不在10000--99999之间,还要转为10000--99999之间的5位数)
字符 "[" 的ASCII值除10余数:91 mod 10 =1 (注:为汉字时取低位字节ASCII码值)
字符 "b" 的ASCII值除10余数:98 mod 10 =8
字符 "c" 的ASCII值除10余数:99 mod 10 =9
字符 "g" 的ASCII值除10余数:103 mod 10 =3
字符 "]" 的ASCII值除10余数:93 mod 10 =3
1 x 10^4+8 x 10^3+8 x 10^2+3 x 10^1+83 x 10^0=18833
( 若累加和不在10000--99999之间,还要转为10000--99999之间的5位数)
23320 xor 57034(常数) =34258
18833 xor 28691(常数) =14822
两整数转字符串连结起来就得到注册码: 3425814822
5.VB注册机:
(使用 《软件加密技术内幕》配套光盘中 VbInLineASM控件 内联汇编 )
Private Sub Label1_Click()
Dim i As Integer
Dim s1 As String, s2 As String, s3 As String
Dim r1 As String, r2 As String
Dim t1 As Long, t2 As Long
On Error Resume Next
s1 = Text1.Text '机器码
s2 = Text2.Text '用户名
If IsNumeric(s1) <> True Or Len(s1) <> 10 Or Len(s2) < 2 Then
MsgBox "机器码10位数字,用户名至少两个字符!!", vbInformation, "提示:"
Exit Sub
End If
s3 = Right(s1, 7) + LCase(s2)
r1 = Left(s3, 5)
r2 = Right(s3, 5)
For i = 1 To 5
c1 = (AscB(Mid(r1, i, 1)) Mod 10) * (10 ^ (5 - i)) + c1
c2 = (AscB(Mid(r2, i, 1)) Mod 10) * (10 ^ (5 - i)) + c2
Next i
t1 = c1 Xor 57034
t2 = c2 Xor 28691 If t1 > 99999 Then
Call ss(t1)
End If
If t1 < 10000 Then
t1 = 10000 + t1
End If
If t2 > 99999 Then
Call ss(t2)
End If
If t2 < 10000 Then
t2 = 10000 + t2
End If
Text3.Text = Trim(Str(t1)) + Trim(Str(t2)) End Sub
'Module1 中内联汇编代码,把大于99999的数转换为10000--99999之间的5位数
Sub ss(ByRef t As Long)
'#ASM_START
' push ebp
' mov ebp, esp
' MOV edx,DWORD PTR SS:[ebp+8]
' mov ecx,edx
' MOV EDX,DWORD PTR DS:[EDX]
' MOV EAX,1717986919
' IMUL EDX
' SAR EDX,2
' MOV EAX,EDX
' SHR EAX,31
' ADD EDX,EAX
' mov DWORD PTR SS:[ecx],edx
' mov esp, ebp
' pop ebp
' ret 8
'#ASM_END
End Sub
6.后记:
它还有网络验证,反正我也是在单机下偶尔玩玩而已,我分析的是7.2.0.667版.
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!