题目:注册显卡测试工具“3DMark2000v1.1”
软件功能:这个软件是加拿大人开发的,3DMark2000用来测试3D加速显卡的性能,对于游戏发烧友了解其显卡性能,购买何种显
卡提供至关重要信息。
工具:Softice
引子:今天安装并实验一下这个测试显卡性能的软件,需要注册,那我们就分析一下是否能够成功注册它。拿PEID查看,没有加
壳,VC开发的。可能软件比较老了,说不定现在同样的软件加了许多保护了。
题外话:听坛友说一款CloneCD比较有趣,昨天也安装了一下,结果这个软件对抗SOFTICE,用Asprotect1.23加壳的,KEYFILE
形式的保护,如果KEYFILE内容不正确,直接给你当机没有商量,用TRW跟踪也没有结果,而且也是经常死机,我一个小时内机器
就被停机不下10几次,我真服了这个软件作者了,软件做的不怎么样,功夫全下在保护上了,让人怀疑值得吗??谁有高招解决
它???赐教!!感谢!!
下面开始我们的3DMark2000破解历程,输入用户名wanggang,输入17位的注册码,每5位一组,共3组,分别用短杠连接起来。形
如11111-22222-33333。调出Softice下断点bpx getwindowtexta,F5退出,点击OK,被拦截,2次F12回到主程序空间。
0040C404 . 8B43 64 MOV EAX,DWORD PTR DS:[EBX+64] //用户名地址送EAX。
0040C407 . 8B48 F8 MOV ECX,DWORD PTR DS:[EAX-8]
0040C40A . 85C9 TEST ECX,ECX
0040C40C . 894424 10 MOV DWORD PTR SS:[ESP+10],EAX
0040C410 . 0F84 D3000000 JE 3DMARK20.0040C4E9
0040C416 . 8B6B 60 MOV EBP,DWORD PTR DS:[EBX+60] //注册码地址送EBP。
0040C419 . 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] //取回注册码长度送EAX。
0040C41C . 85C0 TEST EAX,EAX
0040C41E . 0F84 C5000000 JE 3DMARK20.0040C4E9
0040C424 . 83C9 FF OR ECX,FFFFFFFF
0040C427 . 33C0 XOR EAX,EAX
0040C429 . 8BFD MOV EDI,EBP
0040C42B . F2:AE REPNE SCAS BYTE PTR ES:[EDI] //搜索注册码,计算长度。
0040C42D . F7D1 NOT ECX
0040C42F . 49 DEC ECX
0040C430 . 83F9 11 CMP ECX,11 //与11h比较,即与十进制17比较。
0040C433 . 0F85 A5000000 JNZ 3DMARK20.0040C4DE //不相等则OVER。
0040C439 . BA D8995500 MOV EDX,3DMARK20.005599D8
0040C43E > 8B02 MOV EAX,DWORD PTR DS:[EDX]
0040C440 . 85C0 TEST EAX,EAX
0040C442 . 74 4B JE SHORT 3DMARK20.0040C48F
**********
0040C48F > 8B4424 10 MOV EAX,DWORD PTR SS:[ESP+10] //用户名地址送EAX。
0040C493 . 6A 01 PUSH 1
0040C495 . 50 PUSH EAX
0040C496 . E8 F54FFFFF CALL 3DMARK20.00401490 //这个函数根据用户名形成注册码。(1)
0040C49B . 83C4 08 ADD ESP,8
0040C49E . 8BF5 MOV ESI,EBP
0040C4A0 > 8A10 MOV DL,BYTE PTR DS:[EAX] //从这里到0040C4BE循环判断注册码。DL内放真
码。
0040C4A2 . 8ACA MOV CL,DL
0040C4A4 . 3A16 CMP DL,BYTE PTR DS:[ESI] //ESI指向的是假码。
0040C4A6 . 75 1C JNZ SHORT 3DMARK20.0040C4C4
0040C4A8 . 84C9 TEST CL,CL
0040C4AA . 74 14 JE SHORT 3DMARK20.0040C4C0
0040C4AC . 8A50 01 MOV DL,BYTE PTR DS:[EAX+1]
0040C4AF . 8ACA MOV CL,DL
0040C4B1 . 3A56 01 CMP DL,BYTE PTR DS:[ESI+1]
0040C4B4 . 75 0E JNZ SHORT 3DMARK20.0040C4C4
0040C4B6 . 83C0 02 ADD EAX,2
0040C4B9 . 83C6 02 ADD ESI,2
0040C4BC . 84C9 TEST CL,CL
0040C4BE .^75 E0 JNZ SHORT 3DMARK20.0040C4A0 //未完则继续循环上去。
0040C4C0 > 33C0 XOR EAX,EAX
0040C4C2 . EB 05 JMP SHORT 3DMARK20.0040C4C9
0040C4C4 > 1BC0 SBB EAX,EAX
0040C4C6 . 83D8 FF SBB EAX,-1
0040C4C9 > 85C0 TEST EAX,EAX
0040C4CB . 75 11 JNZ SHORT 3DMARK20.0040C4DE //如果注册码正确,则EAX=0,此处不跳。
0040C4CD . 6A 01 PUSH 1
0040C4CF . 8BCB MOV ECX,EBX
0040C4D1 . E8 5EA00F00 CALL <JMP.&MFC42.#2645> //关闭输入注册码对话框。顺利返回!
0040C4D6 . 5F POP EDI
0040C4D7 . 5E POP ESI
0040C4D8 . 5D POP EBP
0040C4D9 . 5B POP EBX
0040C4DA . 83C4 08 ADD ESP,8
0040C4DD . C3 RETN
=====================================================================================
从上面这段程序返回到下面代码处:
0047AF50 . 6A FF PUSH -1
0047AF52 . 68 E1535100 PUSH 3DMARK20.005153E1
0047AF57 . 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
0047AF5D . 50 PUSH EAX
0047AF5E . 64:8925 00000000 MOV DWORD PTR FS:[0],ESP
0047AF65 . 81EC 74030000 SUB ESP,374
0047AF6B . 53 PUSH EBX
0047AF6C . 55 PUSH EBP
0047AF6D . 56 PUSH ESI
0047AF6E . 57 PUSH EDI
0047AF6F . 894C24 14 MOV DWORD PTR SS:[ESP+14],ECX
0047AF73 . 33F6 XOR ESI,ESI
0047AF75 . 56 PUSH ESI
0047AF76 . 8D4C24 20 LEA ECX,DWORD PTR SS:[ESP+20]
0047AF7A . E8 1113F9FF CALL 3DMARK20.0040C290
0047AF7F . 8D4C24 1C LEA ECX,DWORD PTR SS:[ESP+1C]
0047AF83 . 89B424 8C030000 MOV DWORD PTR SS:[ESP+38C],ESI
0047AF8A . E8 23B30800 CALL <JMP.&MFC42.#2514>
0047AF8F . 83F8 01 CMP EAX,1
0047AF92 . 0F85 EE020000 JNZ 3DMARK20.0047B286
0047AF98 . 8D8424 80000000 LEA EAX,DWORD PTR SS:[ESP+80]
0047AF9F . 50 PUSH EAX
0047AFA0 . B9 60BA5500 MOV ECX,3DMARK20.0055BA60
0047AFA5 . E8 A6B40800 CALL <JMP.&MFC42.#858>
0047AFAA . 8D4C24 7C LEA ECX,DWORD PTR SS:[ESP+7C]
0047AFAE . 51 PUSH ECX
0047AFAF . B9 64BA5500 MOV ECX,3DMARK20.0055BA64
0047AFB4 . E8 97B40800 CALL <JMP.&MFC42.#858>
0047AFB9 . 8B15 60BA5500 MOV EDX,DWORD PTR DS:[55BA60]
0047AFBF . 52 PUSH EDX
0047AFC0 . E8 93B20800 CALL <JMP.&inetmfc.IC_setRegistrationName>
0047AFC5 . A1 64BA5500 MOV EAX,DWORD PTR DS:[55BA64] //假码地址送EAX。
0047AFCA . 50 PUSH EAX
0047AFCB . E8 82B20800 CALL <JMP.&inetmfc.IC_setRegistrationKey>
0047AFD0 . 33C0 XOR EAX,EAX
*省略多行,形成注册信息,并写入注册表。*
0047B16C . 8BFD MOV EDI,EBP
0047B16E . F2:AE REPNE SCAS BYTE PTR ES:[EDI]
0047B170 . F7D1 NOT ECX
0047B172 . 49 DEC ECX
0047B173 . 51 PUSH ECX
0047B174 . 55 PUSH EBP
0047B175 . 6A 01 PUSH 1
0047B177 . 50 PUSH EAX
0047B178 . 8D8C24 94020000 LEA ECX,DWORD PTR SS:[ESP+294]
0047B17F . 51 PUSH ECX
0047B180 . 8B5424 24 MOV EDX,DWORD PTR SS:[ESP+24]
0047B184 . 52 PUSH EDX
0047B185 . FFD6 CALL ESI
0047B187 . 8B4424 10 MOV EAX,DWORD PTR SS:[ESP+10]
0047B18B . 50 PUSH EAX
0047B18C . FF15 14005200 CALL DWORD PTR DS:[<&ADVAPI32.RegCloseKey>]
0047B192 . 6A 01 PUSH 1
0047B194 . B9 78B95500 MOV ECX,3DMARK20.0055B978
0047B199 . E8 22DFFEFF CALL 3DMARK20.004690C0
0047B19E . 8B7424 14 MOV ESI,DWORD PTR SS:[ESP+14]
0047B1A2 . 8B4E 20 MOV ECX,DWORD PTR DS:[ESI+20]
0047B1A5 . 51 PUSH ECX
0047B1A6 . FF15 20095200 CALL DWORD PTR DS:[<&USER32.DrawMenuBar>]
0047B1AC . B9 78B95500 MOV ECX,3DMARK20.0055B978
0047B1B1 . E8 9AC5FEFF CALL 3DMARK20.00467750
0047B1B6 . 85C0 TEST EAX,EAX
0047B1B8 . 74 68 JE SHORT 3DMARK20.0047B222 //此处跳走。
***********
0047B222 > B9 78B95500 MOV ECX,3DMARK20.0055B978
0047B227 . E8 64DAFEFF CALL 3DMARK20.00468C90
0047B22C . 51 PUSH ECX
0047B22D . 8BCC MOV ECX,ESP
0047B22F . 896424 18 MOV DWORD PTR SS:[ESP+18],ESP
0047B233 . 50 PUSH EAX
0047B234 . E8 ABB10800 CALL <JMP.&MFC42.#537>
0047B239 . 8BCE MOV ECX,ESI
0047B23B . E8 A0FBFFFF CALL 3DMARK20.0047ADE0
0047B240 . B9 78B95500 MOV ECX,3DMARK20.0055B978
0047B245 . E8 46DAFEFF CALL 3DMARK20.00468C90
0047B24A . 51 PUSH ECX
0047B24B . 8BCC MOV ECX,ESP
0047B24D . 896424 18 MOV DWORD PTR SS:[ESP+18],ESP
0047B251 . 50 PUSH EAX
0047B252 . E8 8DB10800 CALL <JMP.&MFC42.#537>
0047B257 . B9 78B95500 MOV ECX,3DMARK20.0055B978
0047B25C . E8 EFD9FEFF CALL 3DMARK20.00468C50
0047B261 . 8B06 MOV EAX,DWORD PTR DS:[ESI]
0047B263 . 6A 01 PUSH 1
0047B265 . 8BCE MOV ECX,ESI
0047B267 . FF90 E8000000 CALL DWORD PTR DS:[EAX+E8]
0047B26D . 6A 00 PUSH 0
0047B26F . 6A 00 PUSH 0
0047B271 . 68 9FF00000 PUSH 0F09F
0047B276 . B9 78B95500 MOV ECX,3DMARK20.0055B978
0047B27B . E8 E0F8FEFF CALL 3DMARK20.0046AB60
0047B280 . 50 PUSH EAX
0047B281 . E8 EAAF0800 CALL <JMP.&MFC42.#1200> //这里显示注册成功信息!!
=====================================================================================
下面分析(1)处的函数代码功能:
00401490 /$ 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
00401494 |. 8B4C24 08 MOV ECX,DWORD PTR SS:[ESP+8]
00401498 |. 81EC 40010000 SUB ESP,140
0040149E |. 53 PUSH EBX
0040149F |. 55 PUSH EBP
004014A0 |. 56 PUSH ESI
004014A1 |. 57 PUSH EDI
004014A2 |. 50 PUSH EAX
004014A3 |. 51 PUSH ECX
004014A4 |. 8D5424 58 LEA EDX,DWORD PTR SS:[ESP+58]
004014A8 |. 68 30D65400 PUSH 3DMARK20.0054D630
004014AD |. 52 PUSH EDX
004014AE |. FF15 40075200 CALL DWORD PTR DS:[<&MSVCRT.sprintf>] //把000000001串接在用户名前面,记串S1
。
004014B4 |. 83C9 FF OR ECX,FFFFFFFF
004014B7 |. 33C0 XOR EAX,EAX
004014B9 |. 83C4 10 ADD ESP,10
004014BC |. 8D7C24 50 LEA EDI,DWORD PTR SS:[ESP+50] //串S1地址送EDI。
004014C0 |. F2:AE REPNE SCAS BYTE PTR ES:[EDI]
004014C2 |. F7D1 NOT ECX
004014C4 |. 49 DEC ECX //串长送ECX。
004014C5 |. 8BF1 MOV ESI,ECX
004014C7 |. B8 FFFFFFFF MOV EAX,-1 //EAX初始化为FFFFFFFFh。
004014CC |. BA 00000000 MOV EDX,0
004014D1 |. 74 27 JE SHORT 3DMARK20.004014FA
004014D3 |> 33C9 /XOR ECX,ECX //ECX清零。
004014D5 |. 8A4C14 50 |MOV CL,BYTE PTR SS:[ESP+EDX+50] //串S1各位字符依次送CL。
004014D9 |. 8BF8 |MOV EDI,EAX //EAX值送EDI。
004014DB |. 81E7 FF000000 |AND EDI,0FF //取最低字节。
004014E1 |. C1E8 08 |SHR EAX,8 //EAX右移8次。
004014E4 |. 81E1 FF000000 |AND ECX,0FF //取ECX最低字节。
004014EA |. 33CF |XOR ECX,EDI //ECX与EDI异或运算。
004014EC |. 8B0C8D 9CD15400 |MOV ECX,DWORD PTR DS:[ECX*4+54D19C] //根据所得ECX进行查表,得到的结果送ECX
。
004014F3 |. 33C1 |XOR EAX,ECX //EAX与ECX异或运算。
004014F5 |. 42 |INC EDX //EDX增1。
004014F6 |. 3BD6 |CMP EDX,ESI //循环变量EDX是否到S1串长。
004014F8 |.^72 D9 \JB SHORT 3DMARK20.004014D3 //未完则继续循环查表。
004014FA |> F7D0 NOT EAX //得到的EAX求反。
004014FC |. 8BF0 MOV ESI,EAX //EAX结果送ESI。
004014FE |. C1E8 07 SHR EAX,7 //EAX逻辑右移7次。
00401501 |. C1E6 19 SHL ESI,19 //ESI逻辑左移25次。
00401504 |. 0BF0 OR ESI,EAX //ESI与EAX或运算。
00401506 |. 8BFE MOV EDI,ESI //ESI送EDI。
00401508 |. 8BD6 MOV EDX,ESI //ESI送EDX。
0040150A |. C1EF 1B SHR EDI,1B //EDI逻辑右移27次。
0040150D |. C1E2 05 SHL EDX,5 //EDX逻辑左移5次。
00401510 |. 8BEE MOV EBP,ESI //ESI送EBP。
00401512 |. 8BC6 MOV EAX,ESI //ESI送EAX。
00401514 |. C1E5 14 SHL EBP,14 //EBP逻辑左移20次。
00401517 |. C1E8 0C SHR EAX,0C //EAX逻辑右移12次。
0040151A |. 0BFA OR EDI,EDX //EDI与EDX或运算。
0040151C |. 0BE8 OR EBP,EAX //EBP与EAX或运算。
0040151E |. 33C9 XOR ECX,ECX //ECX清0。
00401520 |. 85FF TEST EDI,EDI
00401522 |. 74 37 JE SHORT 3DMARK20.0040155B //EDI为0则跳到下面。
00401524 |> 33D2 /XOR EDX,EDX //EDX清0。
00401526 |. 8BC7 |MOV EAX,EDI //EDI送EAX。
00401528 |. BB 1F000000 |MOV EBX,1F //1F送EBX。
0040152D |. F7F3 |DIV EBX //EAX除以EBX。
0040152F |. 41 |INC ECX
00401530 |. 0FBED2 |MOVSX EDX,DL //DL符号扩展为EDX。
00401533 |. 0FBE82 BCD55400 |MOVSX EAX,BYTE PTR DS:[EDX+54D5BC] //根据EDX得到地址,查表结果送EAX。
0040153A |. 8A90 9CD55400 |MOV DL,BYTE PTR DS:[EAX+54D59C] //再根据EAX得到地址,查另一个表,结果送
DL。
00401540 |. 88540C 0F |MOV BYTE PTR SS:[ESP+ECX+F],DL //DL送地址保存。
00401544 |. B8 85104208 |MOV EAX,8421085 //常量送EAX。
00401549 |. F7E7 |MUL EDI //EAX乘以EDI。
0040154B |. 2BFA |SUB EDI,EDX //EDI减去EDX。
0040154D |. D1EF |SHR EDI,1 //EDI逻辑右移1次。
0040154F |. 03FA |ADD EDI,EDX //EDI加上EDX。
00401551 |. C1EF 04 |SHR EDI,4 //EDI逻辑右移4次。
00401554 |.^75 CE \JNZ SHORT 3DMARK20.00401524 //如果EDI不为0则继续循环上去。
00401556 |. 83F9 07 CMP ECX,7 //ECX是否到7?
00401559 |. 73 2C JNB SHORT 3DMARK20.00401587 //不小于7则跳走。
0040155B |> 8BFE MOV EDI,ESI //否则下面这段循环继续运算并查表。
0040155D |. 0FAFF9 IMUL EDI,ECX
00401560 |> 33D2 /XOR EDX,EDX
00401562 |. 8BC7 |MOV EAX,EDI
00401564 |. BB 1F000000 |MOV EBX,1F
00401569 |. F7F3 |DIV EBX
0040156B |. 41 |INC ECX
0040156C |. 03FE |ADD EDI,ESI
0040156E |. 83F9 07 |CMP ECX,7
00401571 |. 0FBEC2 |MOVSX EAX,DL
00401574 |. 0FBE90 BCD55400 |MOVSX EDX,BYTE PTR DS:[EAX+54D5BC]
0040157B |. 8A82 9CD55400 |MOV AL,BYTE PTR DS:[EDX+54D59C]
00401581 |. 88440C 0F |MOV BYTE PTR SS:[ESP+ECX+F],AL
00401585 |.^72 D9 \JB SHORT 3DMARK20.00401560 //小于7位则继续循环。
00401587 |> 33DB XOR EBX,EBX //如果前面已经到了7位,则跳到这里。
00401589 |. 3BEB CMP EBP,EBX //EBP与EBX比较,EBP为前面获得的第二个
数。
0040158B |. 74 32 JE SHORT 3DMARK20.004015BF
0040158D |> 33D2 /XOR EDX,EDX //下面用EBP里的数做种子开始计算查表,获得剩余7
位字符。
0040158F |. 8BC5 |MOV EAX,EBP
00401591 |. BF 1F000000 |MOV EDI,1F
00401596 |. F7F7 |DIV EDI
00401598 |. 41 |INC ECX
00401599 |. 0FBED2 |MOVSX EDX,DL
0040159C |. 0FBE82 BCD55400 |MOVSX EAX,BYTE PTR DS:[EDX+54D5BC]
004015A3 |. 8A90 9CD55400 |MOV DL,BYTE PTR DS:[EAX+54D59C]
004015A9 |. 88540C 0F |MOV BYTE PTR SS:[ESP+ECX+F],DL
004015AD |. B8 85104208 |MOV EAX,8421085
004015B2 |. F7E5 |MUL EBP
004015B4 |. 2BEA |SUB EBP,EDX
004015B6 |. D1ED |SHR EBP,1
004015B8 |. 03EA |ADD EBP,EDX
004015BA |. C1ED 04 |SHR EBP,4
004015BD |.^75 CE \JNZ SHORT 3DMARK20.0040158D //EBP不为0,则继续循环。
004015BF |> 83F9 0F CMP ECX,0F //比较ECX是否到15?
004015C2 |. 73 2C JNB SHORT 3DMARK20.004015F0 //大于或等于15位则跳走。注册码已经产生
好了。
004015C4 |. 8BFE MOV EDI,ESI //否则,下面继续计算,直到满足15位注册
码。
004015C6 |. 0FAFF9 IMUL EDI,ECX
004015C9 |> 33D2 /XOR EDX,EDX
004015CB |. 8BC7 |MOV EAX,EDI
004015CD |. BD 1F000000 |MOV EBP,1F
004015D2 |. F7F5 |DIV EBP
004015D4 |. 41 |INC ECX
004015D5 |. 03FE |ADD EDI,ESI
004015D7 |. 83F9 0F |CMP ECX,0F
004015DA |. 0FBEC2 |MOVSX EAX,DL
004015DD |. 0FBE90 BCD55400 |MOVSX EDX,BYTE PTR DS:[EAX+54D5BC]
004015E4 |. 8A82 9CD55400 |MOV AL,BYTE PTR DS:[EDX+54D59C]
004015EA |. 88440C 0F |MOV BYTE PTR SS:[ESP+ECX+F],AL
004015EE |.^72 D9 \JB SHORT 3DMARK20.004015C9 //ECX小于15则继续循环产生注册码字符。
004015F0 |> 6A 05 PUSH 5
004015F2 |. 8D4C24 14 LEA ECX,DWORD PTR SS:[ESP+14]
004015F6 |. 51 PUSH ECX
004015F7 |. 68 E0095600 PUSH 3DMARK20.005609E0
004015FC |. FF15 3C075200 CALL DWORD PTR DS:[<&MSVCRT.strncpy>] //把注册码前5位复制到另外地方。
00401602 |. 83C9 FF OR ECX,FFFFFFFF
00401605 |. 33C0 XOR EAX,EAX
00401607 |. BF 2CD65400 MOV EDI,3DMARK20.0054D62C
0040160C |. F2:AE REPNE SCAS BYTE PTR ES:[EDI]
0040160E |. F7D1 NOT ECX
00401610 |. 2BF9 SUB EDI,ECX
00401612 |. 8BD1 MOV EDX,ECX
00401614 |. 83C9 FF OR ECX,FFFFFFFF
00401617 |. 8B2D 38075200 MOV EBP,DWORD PTR DS:[<&MSVCRT.strncat>]
0040161D |. 8BF7 MOV ESI,EDI
0040161F |. 881D E5095600 MOV BYTE PTR DS:[5609E5],BL
00401625 |. BF E0095600 MOV EDI,3DMARK20.005609E0
0040162A |. F2:AE REPNE SCAS BYTE PTR ES:[EDI]
0040162C |. 8BCA MOV ECX,EDX
0040162E |. C1E9 02 SHR ECX,2
00401631 |. 4F DEC EDI
00401632 |. F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
00401634 |. 6A 05 PUSH 5
00401636 |. 8D4424 25 LEA EAX,DWORD PTR SS:[ESP+25]
0040163A |. 8BCA MOV ECX,EDX
0040163C |. 50 PUSH EAX
0040163D |. 83E1 03 AND ECX,3
00401640 |. 68 E0095600 PUSH 3DMARK20.005609E0
00401645 |. F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] //把一个短杠'-'连接到前面5位字
符后面。
00401647 |. FFD5 CALL EBP //复制第二组5位字符到短杠符号
后面。
00401649 |. 83C9 FF OR ECX,FFFFFFFF
0040164C |. 33C0 XOR EAX,EAX
0040164E |. BF 2CD65400 MOV EDI,3DMARK20.0054D62C
00401653 |. F2:AE REPNE SCAS BYTE PTR ES:[EDI]
00401655 |. F7D1 NOT ECX
00401657 |. 2BF9 SUB EDI,ECX
00401659 |. 8BD1 MOV EDX,ECX
0040165B |. 83C9 FF OR ECX,FFFFFFFF
0040165E |. 8BF7 MOV ESI,EDI
00401660 |. 881D EB095600 MOV BYTE PTR DS:[5609EB],BL
00401666 |. BF E0095600 MOV EDI,3DMARK20.005609E0
0040166B |. F2:AE REPNE SCAS BYTE PTR ES:[EDI] //统计前面获得的字符数。
0040166D |. 8BCA MOV ECX,EDX
0040166F |. C1E9 02 SHR ECX,2
00401672 |. 4F DEC EDI
00401673 |. F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
00401675 |. 6A 05 PUSH 5
00401677 |. 8D4424 36 LEA EAX,DWORD PTR SS:[ESP+36]
0040167B |. 8BCA MOV ECX,EDX
0040167D |. 50 PUSH EAX
0040167E |. 83E1 03 AND ECX,3
00401681 |. 68 E0095600 PUSH 3DMARK20.005609E0
00401686 |. F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] //把一个短杠'-'连接到前面11位字
符后面。
00401688 |. FFD5 CALL EBP //复制第三组5位字符到短杠符号后
面。
0040168A |. 83C4 24 ADD ESP,24
0040168D |. 5F POP EDI
0040168E |. 5E POP ESI
0040168F |. 5D POP EBP
00401690 |. 881D F1095600 MOV BYTE PTR DS:[5609F1],BL
00401696 |. B8 E0095600 MOV EAX,3DMARK20.005609E0 //注册码地址送EAX。
0040169B |. 5B POP EBX
0040169C |. 81C4 40010000 ADD ESP,140
004016A2 \. C3 RETN
=====================================================================================
后记:
这个小软件的注册码机制不是很复杂,就是一个用种子数除以常数得到余数,然后查表得到一个数,再次查表得到注册码的符号。
用了1个多小时才写完这篇破文,注册机的实现比较简单,就是一个有1024个字节的大表格比较讨厌。另外,里面有个地方进行大
数乘法,在C语言内不支持大数相乘,只好采用汇编代码。我随便写了个注册机,局部错误在所难免,仅供参考而已!如果计算过
程用上面的汇编代码更好些。 #include "stdio.h"
#include "string.h"
void main()
{
long int table1[]={
0x00000000l,0x96300777l,0x2C610EEEl,0xBA510999l,0x19C46D07l,0x8FF46A70l,0x35A563E9l,0xA395649El,
0x3288DB0El,0xA4B8DC79l,0x1EE9D5E0l,0x88D9D297l,0x2B4CB609l,0xBD7CB17El,0x072DB8E7l,0x911DBF90l,
0x6410B71Dl,0xF220B06Al,0x4871B9F3l,0xDE41BE84l,0x7DD4DA1Al,0xEBE4DD6Dl,0x51B5D4F4l,0xC785D383l,
0x56986C13l,0xC0A86B64l,0x7AF962FDl,0xECC9658Al,0x4F5C0114l,0xD96C0663l,0x633D0FFAl,0xF50D088Dl,
0xC8206E3Bl,0x5E10694Cl,0xE44160D5l,0x727167A2l,0xD1E4033Cl,0x47D4044Bl,0xFD850DD2l,0x6BB50AA5l,
0xFAA8B535l,0x6C98B242l,0xD6C9BBDBl,0x40F9BCACl,0xE36CD832l,0x755CDF45l,0xCF0DD6DCl,0x593DD1ABl,
0xAC30D926l,0x3A00DE51l,0x8051D7C8l,0x1661D0BFl,0xB5F4B421l,0x23C4B356l,0x9995BACFl,0x0FA5BDB8l,
0x9EB80228l,0x0888055Fl,0xB2D90CC6l,0x24E90BB1l,0x877C6F2Fl,0x114C6858l,0xAB1D61C1l,0x3D2D66B6l,
0x9041DC76l,0x0671DB01l,0xBC20D298l,0x2A10D5EFl,0x8985B171l,0x1FB5B606l,0xA5E4BF9Fl,0x33D4B8E8l,
0xA2C90778l,0x34F9000Fl,0x8EA80996l,0x18980EE1l,0xBB0D6A7Fl,0x2D3D6D08l,0x976C6491l,0x015C63E6l,
0xF4516B6Bl,0x62616C1Cl,0xD8306585l,0x4E0062F2l,0xED95066Cl,0x7BA5011Bl,0xC1F40882l,0x57C40FF5l,
0xC6D9B065l,0x50E9B712l,0xEAB8BE8Bl,0x7C88B9FCl,0xDF1DDD62l,0x492DDA15l,0xF37CD38Cl,0x654CD4FBl,
0x5861B24Dl,0xCE51B53Al,0x7400BCA3l,0xE230BBD4l,0x41A5DF4Al,0xD795D83Dl,0x6DC4D1A4l,0xFBF4D6D3l,
0x6AE96943l,0xFCD96E34l,0x468867ADl,0xD0B860DAl,0x732D0444l,0xE51D0333l,0x5F4C0AAAl,0xC97C0DDDl,
0x3C710550l,0xAA410227l,0x10100BBEl,0x86200CC9l,0x25B56857l,0xB3856F20l,0x09D466B9l,0x9FE461CEl,
0x0EF9DE5El,0x98C9D929l,0x2298D0B0l,0xB4A8D7C7l,0x173DB359l,0x810DB42El,0x3B5CBDB7l,0xAD6CBAC0l,
0x2083B8EDl,0xB6B3BF9Al,0x0CE2B603l,0x9AD2B174l,0x3947D5EAl,0xAF77D29Dl,0x1526DB04l,0x8316DC73l,
0x120B63E3l,0x843B6494l,0x3E6A6D0Dl,0xA85A6A7Al,0x0BCF0EE4l,0x9DFF0993l,0x27AE000Al,0xB19E077Dl,
0x44930FF0l,0xD2A30887l,0x68F2011El,0xFEC20669l,0x5D5762F7l,0xCB676580l,0x71366C19l,0xE7066B6El,
0x761BD4FEl,0xE02BD389l,0x5A7ADA10l,0xCC4ADD67l,0x6FDFB9F9l,0xF9EFBE8El,0x43BEB717l,0xD58EB060l,
0xE8A3D6D6l,0x7E93D1A1l,0xC4C2D838l,0x52F2DF4Fl,0xF167BBD1l,0x6757BCA6l,0xDD06B53Fl,0x4B36B248l,
0xDA2B0DD8l,0x4C1B0AAFl,0xF64A0336l,0x607A0441l,0xC3EF60DFl,0x55DF67A8l,0xEF8E6E31l,0x79BE6946l,
0x8CB361CBl,0x1A8366BCl,0xA0D26F25l,0x36E26852l,0x95770CCCl,0x03470BBBl,0xB9160222l,0x2F260555l,
0xBE3BBAC5l,0x280BBDB2l,0x925AB42Bl,0x046AB35Cl,0xA7FFD7C2l,0x31CFD0B5l,0x8B9ED92Cl,0x1DAEDE5Bl,
0xB0C2649Bl,0x26F263ECl,0x9CA36A75l,0x0A936D02l,0xA906099Cl,0x3F360EEBl,0x85670772l,0x13570005l,
0x824ABF95l,0x147AB8E2l,0xAE2BB17Bl,0x381BB60Cl,0x9B8ED292l,0x0DBED5E5l,0xB7EFDC7Cl,0x21DFDB0Bl,
0xD4D2D386l,0x42E2D4F1l,0xF8B3DD68l,0x6E83DA1Fl,0xCD16BE81l,0x5B26B9F6l,0xE177B06Fl,0x7747B718l,
0xE65A0888l,0x706A0FFFl,0xCA3B0666l,0x5C0B0111l,0xFF9E658Fl,0x69AE62F8l,0xD3FF6B61l,0x45CF6C16l,
0x78E20AA0l,0xEED20DD7l,0x5483044El,0xC2B30339l,0x612667A7l,0xF71660D0l,0x4D476949l,0xDB776E3El,
0x4A6AD1AEl,0xDC5AD6D9l,0x660BDF40l,0xF03BD837l,0x53AEBCA9l,0xC59EBBDEl,0x7FCFB247l,0xE9FFB530l,
0x1CF2BDBDl,0x8AC2BACAl,0x3093B353l,0xA6A3B424l,0x0536D0BAl,0x9306D7CDl,0x2957DE54l,0xBF67D923l,
0x2E7A66B3l,0xB84A61C4l,0x021B685Dl,0x942B6F2Al,0x37BE0BB4l,0xA18E0CC3l,0x1BDF055Al,0x8DEF022Dl}; int table2[]={0x0A,0x16,0x1A,0x0B,0x07,0x08,0x01,0x17,0x05,0x1C,0x00,0x19,0x13,0x1B,0x03,0x1D,0x0D,
0x1E,0x02,0x18,0x0F,0x06,0x09,0x10,0x0C,0x0E,0x11,0x15,0x12,0x04,0x14,0x00};
int table3[]={0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x4A,
0x4B,0x4C,0x4D,0x4E,0x50,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x00};
char name[30],code[18],c;
char s1[40]="00000001";
int namelen;
unsigned long eax,ebx,ecx,edx,edi,esi,ebp;
unsigned long temp,a=0,b=0;
int i,j;
for(i=0;i<256;i++) //Table1表内的常量顺序颠倒过来。
{ temp=table1[i];
for(j=0;j<4;j++)
{
a=temp%0x100;
temp=temp>>8;
b=b*0x100;
b+=a;
}
table1[i]=b;
b=0;
}
printf("please input your name\n");
scanf("%s",name);
strcat(s1,name);
namelen=strlen(s1);
eax1=-1;
edx=0;
ecx=0;
for(i=0;i<namelen;i++)
{ecx=s1[i];
edi=eax1;
edi=edi&0xff;
eax1=eax1>>8;
ecx=ecx&0xff;
ecx=ecx^edi;
ecx=table1[ecx];
eax1=eax1^ecx;
ecx=0;
}
eax1=~eax1;
esi=eax1;
eax1=eax1>>7;
esi=esi<<0x19;
esi=esi|eax1;
edi=esi;
edx=esi;
edi=edi>>0x1b;
edx=edx<<5;
edi=edi|edx;
ebp=esi;
eax1=esi;
ebp=ebp<<0x14;
eax1=eax1>>0xc;
ebp=ebp|eax1;
ecx=0;
do
{
edx=0;
eax1=edi;
ebx=0x1f;
edx=eax1%ebx;
eax1=table2[edx];
c=table3[eax1];
if(ecx==5)
code[ecx++]=0x2D;
else
code[ecx++]=c;
__asm{
mov eax,8421085
mul edi
sub edi,edx
shr edi,1
add edi,edx
shr edi,4
}
}while((__asm edi)!=0); //请教各位大侠,这样用汇编是否合适?我想直接用edi的值比较。上面程序都对,可是这里EAX
与EDI相乘,需要高4字节,只好用汇编,不知这个循环条件是否可以用汇编代码?如果全部用汇编,就要全部把C代码换成汇编代
码了,那样直接采用上面软件里面的即可,当然需要局部修改。
if(ecx<7)
{edi=esi;
edi=edi*ecx;
do{
edx=0;
eax1=edi;
ebx=0x1f;
edx=eax1%ebx;
edi=edi+esi;
edx=table2[edx];
c=table3[edx];
if(ecx==5)
code[ecx++]=0x2D;
else
code[ecx++]=c;
}while(ecx<7);
}
else
{
ebx=0;
do{
edx=0;
eax1=ebp;
edi=0x1f;
edx=eax1%edi;
eax1=table2[edx];
c=table3[eax1];
if(ecx==0xC)
code[ecx++]=0x2D;
else
code[ecx++]=c;
__asm{
mov eax,8421085
mul ebp
sub ebp,edx
shr ebp,1
add ebp,edx
shr ebp,4
}
}while((__asm ebp)!=0);
}
if(ecx<0xf)
{edi=esi;
edi=edi*ecx;
do{
edx=0;
eax1=edi;
ebp=0x1f;
edx=eax1%ebp;
edi=edi+esi;
edx=table2[edx];
c=table3[edx];
if(ecx==0xC)
code[ecx++]=0x2D;
else
code[ecx++]=c;
}while(ecx<0xf);
}
printf("The code is %s",code);
} 结论:
用户名:wanggang
注册码:FKXN8-FR9EM-8C4D2 完稿:2006年2月8日 qduwg
qduwg@163.com
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!