一个十分简单的算法保护程序
日期:2007年1月29日 破解人:林海雪原
――――――――――――――――――――――――――――――――――――――――――― 【软件名称】: 软件版本:3.33
【软件大小】: KB
【下载地址】:http://
【软件简介】:
【软件限制】:
【破解声明】:初学Crack,只是感兴趣,没有其它目的。失误之处敬请诸位大侠赐教!
【破解工具】:
―――――――――――――――――――――――――――――――――――――――――――
【破解过程】:
这是一个十分简单的算法保护程序,特别对新手有用,所以就发到这,希望对新手能有一点帮助! 用PEID查一下:Borland Delphi 6.0 - 7.0 虽然我们不能迷信这个结果,但先用它看看还是有必要的. 既然是Delphi的,就可以用DEDE分析了.其实这个程序保护较弱,不用DEDE也是一样的(用字符串参考,你会得到很多有用的东西!!):
004E6C45 mov edx,winchm.004E7178 ASCII "Single-user License"
004E6C68 mov edx,winchm.004E7194 ASCII "2-user License"
004E6C8B mov edx,winchm.004E71AC ASCII "5-user License"
004E6CAE mov edx,winchm.004E71C4 ASCII "10-user License"
004E6CD1 mov edx,winchm.004E71DC ASCII "20-user License"
004E6CF4 mov edx,winchm.004E71F4 ASCII "50-user License"
004E6D17 mov edx,winchm.004E720C ASCII "Site License"
004E6DBE mov edx,winchm.004E7178 ASCII "Single-user License"
004E6DE1 mov edx,winchm.004E7194 ASCII "2-user License"
004E6E04 mov edx,winchm.004E71AC ASCII "5-user License"
004E6E27 mov edx,winchm.004E71C4 ASCII "10-user License"
004E6E4A mov edx,winchm.004E71DC ASCII "20-user License"
004E6E6D mov edx,winchm.004E71F4 ASCII "50-user License"
004E6E90 mov edx,winchm.004E720C ASCII "Site License"
004E6F3C mov ecx,winchm.004E7224 ASCII "-user License"
004E6FAA mov edx,winchm.004E720C ASCII "Site License"
004E7097 mov ecx,winchm.004E7224 ASCII "-user License"
004E7114 mov edx,winchm.004E720C ASCII "Site License" 在DEDE中,有这样一个窗体会引起你注意:TfrmRegister!!
事件如下:
Register
TfrmRegister.FormCreate 004E7648 *(为了防范作者玩火,这应注意一下,不用断的)
TfrmRegister.btnCleanInfoClick 004E7768
TfrmRegister.BitBtn3Click 004E78FC ***
TfrmRegister.Action1Update 004E796C *
TfrmRegister.Action1Execute 004E79F0 *
TfrmRegister.Label1Click 004E7B98 *
TfrmRegister._PROC_004E6494 004E6494
TfrmRegister._PROC_004E6558 004E6558
TfrmRegister._PROC_004E6A10 004E6A10
TfrmRegister._PROC_004E6A85 004E6A85
TfrmRegister._PROC_004E6BB8 004E6BB8
TfrmRegister._PROC_004E7235 004E7235
TfrmRegister._PROC_004E72D4 004E72D4
TfrmRegister._PROC_004E73D5 004E73D5
TfrmRegister._PROC_004E7460 004E7460
TfrmRegister._PROC_004E762D 004E762D
TfrmRegister._PROC_004E772C 004E772C
TfrmRegister._PROC_004E7964 004E7964
TfrmRegister._PROC_004E7BA1 004E7BA1
TfrmRegister._PROC_004E7BD0 004E7BD0
TfrmRegister._PROC_004E7BD8 004E7BD8
在上面的事件中只有加了"*"的能引人注目,先不管,用OD载入,在上面4处下断在说了,OD中断入口如下:
00512914 w> $ 55 push ebp
00512915 . 8BEC mov ebp,esp
00512917 . B9 06000000 mov ecx,6
0051291C > 6A 00 push 0
0051291E . 6A 00 push 0
00512920 . 49 dec ecx
00512921 .^ 75 F9 jnz short winchm.0051291C
00512923 . 51 push ecx
00512924 . 53 push ebx
00512925 . B8 AC245100 mov eax,winchm.005124AC
0051292A . E8 A93BEFFF call winchm.004064D8
0051292F . 33C0 xor eax,eax
00512931 . 55 push ebp 这是一个非标准的delphi入口,作者在dpr文件里弄了自己的代码!这说明PEID识别正确(绝大部份时候都是正确的).在上面4处下断,运行!结果未中断,而出来个框框,说"15 days left for trial period",在下面找到这个串:
004EAAC1 |. 8B86 10030000 mov eax,[dword ds:esi+310] ; |
004EAAC7 |. 8945 F4 mov [dword ss:ebp-C],eax ; |
004EAACA |. C645 F8 00 mov [byte ss:ebp-8],0 ; |
004EAACE |. 8D55 F4 lea edx,[dword ss:ebp-C] ; |
004EAAD1 |. 33C9 xor ecx,ecx ; |
004EAAD3 |. B8 84AB4E00 mov eax,winchm.004EAB84 ; |ASCII "%d days left for trial period"
004EAAD8 |. E8 D3F5F1FF call winchm.0040A0B0 ; \winchm.0040A0B0
004EAADD |. 8B55 FC mov edx,[dword ss:ebp-4]
这个框框还有个"entr reg code"的按钮,我点了下,立马中断了:
004E796C /. 55 push ebp
004E796D |. 8BEC mov ebp,esp
004E796F |. 6A 00 push 0
004E7971 |. 6A 00 push 0
(TfrmRegister.Action1Update 004E796C *)
看看上下文,感觉没有紧要之处,放行后,它要我输入name 和 License code,现在就各有所爱了,我就用scxtb 和 123456789 ,点register,又中断于下:
004E79F0 /. 55 push ebp
004E79F1 |. 8BEC mov ebp,esp
004E79F3 |. 33C9 xor ecx,ecx
004E79F5 |. 51 push ecx
004E79F6 |. 51 push ecx
(TfrmRegister.Action1Execute 004E79F0 *)
同样,上下看看,这次收获可不小了:
004E7AC9 |. A1 0C485100 mov eax,[dword ds:51480C]
004E7ACE |. 8B00 mov eax,[dword ds:eax]
004E7AD0 |. 33D2 xor edx,edx
004E7AD2 |. E8 F5CFF1FF call winchm.00404ACC
004E7AD7 |. 74 0C je short winchm.004E7AE5
004E7AD9 |. B8 687B4E00 mov eax,winchm.004E7B68 ; ASCII "Thank you!" ===========>注册成功!!
004E7ADE |. E8 15F6F4FF call winchm.004370F8
004E7AE3 |. EB 0A jmp short winchm.004E7AEF
004E7AE5 |> B8 7C7B4E00 mov eax,winchm.004E7B7C ; ASCII "Illegal registration code!"=====>注册失败!!
004E7AEA |. E8 09F6F4FF call winchm.004370F8
004E7AEF |> C786 4C020000 0>mov [dword ds:esi+24C],1
看来正确与否,就此见分晓了!主要代码如下:
004E7A4E |. E8 D146F9FF call winchm.0047C124
004E7A53 |. 8B45 F4 mov eax,[dword ss:ebp-C] ; (ASCII "scxtb")
004E7A56 |. 8D55 F8 lea edx,[dword ss:ebp-8]
004E7A59 |. E8 360DF2FF call winchm.00408794
004E7A5E |. 8B4D F8 mov ecx,[dword ss:ebp-8]
004E7A61 |. BA 487B4E00 mov edx,winchm.004E7B48 ; ASCII "RegName"
004E7A66 |. 8BC3 mov eax,ebx
004E7A68 |. E8 BFAFF5FF call winchm.00442A2C ; 写注册表
004E7A6D |. 8D45 EC lea eax,[dword ss:ebp-14]
004E7A70 |. 50 push eax
004E7A71 |. 8D55 E0 lea edx,[dword ss:ebp-20]
004E7A74 |. 8B86 0C030000 mov eax,[dword ds:esi+30C]
004E7A7A |. E8 A546F9FF call winchm.0047C124
004E7A7F |. 8B45 E0 mov eax,[dword ss:ebp-20] ; (ASCII "123456")
004E7A82 |. 8D55 E4 lea edx,[dword ss:ebp-1C]
004E7A85 |. E8 0A0DF2FF call winchm.00408794
004E7A8A |. 8B45 E4 mov eax,[dword ss:ebp-1C]
004E7A8D |. 8D55 E8 lea edx,[dword ss:ebp-18]
004E7A90 |. E8 AF0AF2FF call winchm.00408544 ; 转为大写
004E7A95 |. 8B45 E8 mov eax,[dword ss:ebp-18] ; |
004E7A98 |. B1 01 mov cl,1 ; |加解密的标志:1,加密
004E7A9A |. 66:BA FE05 mov dx,5FE ; |初始密码;
004E7A9E |. E8 31F9FFFF call winchm.004E73D4 ; \winchm.004E73D4
004E7AA3 |. 8B45 EC mov eax,[dword ss:ebp-14] ; RegCode加密
004E7AA6 |. 8D55 F0 lea edx,[dword ss:ebp-10]
004E7AA9 |. E8 86F7FFFF call winchm.004E7234
004E7AAE |. 8B4D F0 mov ecx,[dword ss:ebp-10] ; (ASCII "348678F37CE9")
004E7AB1 |. BA 587B4E00 mov edx,winchm.004E7B58 ; ASCII "RegCode"
004E7AB6 |. 8BC3 mov eax,ebx
004E7AB8 |. E8 6FAFF5FF call winchm.00442A2C ; 写注册表
004E7ABD |. 8BC3 mov eax,ebx 就是先把用户名和加密后的注册码写进注册表hKey = HKEY_CURRENT_USER\Software\Softany\winchm里在说,加密注册码过程如下(call winchm.004E73D4): 004E73D4 /$ 55 push ebp ;本地调用来自 004E750D, 004E7A9E
004E73D5 |. 8BEC mov ebp,esp ;很明显,004E750D处就是解密调用!
004E73D7 |. 83C4 F8 add esp,-8
..............
004E7414 |. 85C0 test eax,eax
004E7416 |. 7E 3F jle short winchm.004E7457 ; 加密和还原
004E7418 |> 0FB7D7 /movzx edx,di ; 05Fe:
004E741B |. C1EA 08 |shr edx,8
004E741E |. 3213 |xor dl,[byte ds:ebx] ; 与5 XOR
004E7420 |. 8816 |mov [byte ds:esi],dl
004E7422 |. 807D FB 00 |cmp [byte ss:ebp-5],0 ; 这是加解密的标志:1,加密;0,解密
004E7426 |. 74 17 |je short winchm.004E743F
004E7428 |. 81E2 FF000000 |and edx,0FF ; XOR的结果只要未2位
004E742E |. 66:03FA |add di,dx ; 与初始码相加
004E7431 |. 66:69D7 540D |imul dx,di,0D54 ; dx==di*0d54(结果保留word大小)
004E7436 |. 66:81C2 3422 |add dx,2234 ; +$2234
004E743B |. 8BFA |mov edi,edx ; 结果为下次XOR的密码
004E743D |. EB 13 |jmp short winchm.004E7452
004E743F |> 33D2 |xor edx,edx ; 这是解密!!
004E7441 |. 8A13 |mov dl,[byte ds:ebx]
004E7443 |. 66:03FA |add di,dx
004E7446 |. 66:69D7 540D |imul dx,di,0D54
004E744B |. 66:81C2 3422 |add dx,2234
004E7450 |. 8BFA |mov edi,edx
004E7452 |> 46 |inc esi
004E7453 |. 43 |inc ebx
004E7454 |. 48 |dec eax
004E7455 |.^ 75 C1 \jnz short winchm.004E7418
004E7457 |> 5F pop edi 作者大概是先加密写进注册表,在读出来解密验证了!很明显,004E750D处就是解密调用!
我们到004E750D处看看,果不出所料:
004E74FF . E8 D0FDFFFF call winchm.004E72D4
004E7504 . 8B45 EC mov eax,[dword ss:ebp-14] ; |
004E7507 . 33C9 xor ecx,ecx ; |
004E7509 . 66:BA FE05 mov dx,5FE ; |
004E750D . E8 C2FEFFFF call winchm.004E73D4 ; \winchm.004E73D4 向下我们可以定位到如下关键处:
004E758C . E8 1BCEF1FF call winchm.004043AC
004E7591 . 8B45 DC mov eax,[dword ss:ebp-24] ; (ASCII "scxtb")
004E7594 . 8D4D E4 lea ecx,[dword ss:ebp-1C]
004E7597 . 5A pop edx ; (00ECA07C), ASCII "123456789"
004E7598 . E8 1BF6FFFF call winchm.004E6BB8 ; 关键!!======>进入!!
004E759D . 8B55 E4 mov edx,[dword ss:ebp-1C]
004E75A0 . A1 0C485100 mov eax,[dword ds:51480C]
004E75A5 . E8 EAD3F1FF call winchm.00404994
004E75AA . A1 0C485100 mov eax,[dword ds:51480C]
004E75AF . 8B00 mov eax,[dword ds:eax]
004E75B1 . 33D2 xor edx,edx
004E75B3 . E8 14D5F1FF call winchm.00404ACC
004E75B8 . 75 16 jnz short winchm.004E75D0
004E75BA . A1 244A5100 mov eax,[dword ds:514A24]
004E75BF . BA 28764E00 mov edx,winchm.004E7628 ; UNICODE " [Unregistered]"
004E75C4 . E8 F7D3F1FF call winchm.004049C0
004E75C9 . A1 244A5100 mov eax,[dword ds:514A24]
004E75CE . EB 0A jmp short winchm.004E75DA
004E75D0 > A1 244A5100 mov eax,[dword ds:514A24]
004E75D5 . E8 56D2F1FF call winchm.00404830 =====>进入call winchm.004E6BB8:
004E6BB8 /$ 55 push ebp
004E6BB9 |. 8BEC mov ebp,esp
004E6BBB |. 51 push ecx
004E6BBC |. B9 05000000 mov ecx,5
004E6BC1 |> 6A 00 /push 0
........
004E6BF8 |. E8 A3D5F1FF call winchm.004041A0
004E6BFD |. 8B45 EC mov eax,[dword ss:ebp-14]
004E6C00 |. E8 DFD7F1FF call winchm.004043E4 ; 取注册码长度
004E6C05 |. 8B15 444B5100 mov edx,[dword ds:514B44] ; winchm.00515E0C
004E6C0B |. C702 FFFFFFFF mov [dword ds:edx],-1
004E6C11 |. 83F8 14 cmp eax,14 ; Switch (cases 14..22)
004E6C14 |. 0F85 23010000 jnz winchm.004E6D3D ; 14----22
004E6C1A |. A1 444B5100 mov eax,[dword ds:514B44] ; Case 14 of switch 004E6C11
004E6C1F |. 33D2 xor edx,edx
004E6C21 |. 8910 mov [dword ds:eax],edx
004E6C23 |. 8B45 EC mov eax,[dword ss:ebp-14]
004E6C26 |. E8 69F8FFFF call winchm.004E6494 ; 关键!!======>进入!!
004E6C2B |. 8945 F0 mov [dword ss:ebp-10],eax
004E6C2E |. 8955 F4 mov [dword ss:ebp-C],edx 这里说一点就行了:
004E6C11 |. 83F8 14 cmp eax,14 =====>比较假注册码长度;
004E6C14 |. 0F85 23010000 jnz winchm.004E6D3D =====>每次比较长度后的跳转就是很好的爆破点; 现在我们可以一些对注册码长度的要求了. 注册码长度如下5种(14;18;19;1D;22):
004E6C05 |. 8B15 444B5100 mov edx,dword ptr ds:[514B44] ; winchm.00515E0C
004E6C0B |. C702 FFFFFFFF mov dword ptr ds:[edx],-1
004E6C11 |. 83F8 14 cmp eax,14 ; Switch (cases 14..22)
004E6C14 |. 0F85 23010000 jnz winchm.004E6D3D ; 14----22
004E6C1A |. A1 444B5100 mov eax,dword ptr ds:[514B44] ; Case 14 of switch 004E6C11
.......
004E6D3D |> \83F8 19 cmp eax,19
004E6D40 |. 0F85 70010000 jnz winchm.004E6EB6
004E6D46 |. 8D45 E8 lea eax,[local.6] ; Case 19 of switch 004E6C11
.........
004E6EB6 |> \83F8 1D cmp eax,1D
004E6EB9 |. 0F85 12010000 jnz winchm.004E6FD1
004E6EBF |. 8D45 E8 lea eax,[local.6] ; Case 1D of switch 004E6C11
.......
004E6FD1 |> \83F8 22 cmp eax,22
004E6FD4 |. 0F85 E1000000 jnz winchm.004E70BB
004E6FDA |. 8D45 E8 lea eax,[local.6] ; Case 22 of switch 004E6C11
.......
004E70BB |> \83F8 18 cmp eax,18
004E70BE |. 75 72 jnz short winchm.004E7132
004E70C0 |. 8D45 E8 lea eax,[local.6] ; Case 18 of switch 004E6C11 我们来看下注册码长为20(14H)的情形:(call 004E6494为关键!)
======>进入!!跟进后可以看见下面的循环,就是计算注册码了(我已将注册码重填为:12345678901234567891):
004E64DF |. /7E 39 jle short winchm.004E651A
004E64E1 |. |BB 01000000 mov ebx,1 ; 计算注册码了!!
004E64E6 |> |8BC3 /mov eax,ebx ; 从1开始取循环数,以决定取注册码的位数
004E64E8 |. |99 |cdq ; 把EAX中的字的符号扩展到EDX中去
004E64E9 |. |52 |push edx ; /Arg2
004E64EA |. |50 |push eax ; |Arg1
004E64EB |. |B8 03000000 |mov eax,3 ; |
004E64F0 |. |E8 5BFFFFFF |call winchm.004E6450 ; \winchm.004E6450======>进入!!
004E64F5 |. |52 |push edx ; 3^n: n==循环数+1
004E64F6 |. |50 |push eax
004E64F7 |. |8B45 EC |mov eax,[local.5] ; 注册码 (ASCII "12345678901234567891")
004E64FA |. |8A4418 FF |mov al,byte ptr ds:[eax+ebx>; 取1位注册码的ASCII
004E64FE |. |25 FF000000 |and eax,0FF ; 与上面结果进行
004E6503 |. |33D2 |xor edx,edx
004E6505 |. |E8 02ECF1FF |call winchm.0040510C ; int64乘法
004E650A |. |0345 E0 |add eax,[local.8] ; 加上次结果
004E650D |. |1355 E4 |adc edx,[local.7] ; 带进位加法
004E6510 |. |8945 E0 |mov [local.8],eax
004E6513 |. |8955 E4 |mov [local.7],edx
004E6516 |. |43 |inc ebx ; 循环次数+1::注册码的下1位
004E6517 |. |4E |dec esi ; 控制器-1
004E6518 |.^|75 CC \jnz short winchm.004E64E6
004E651A |> \8B45 E0 mov eax,[local.8]
004E651D |. 8945 F0 mov [local.4],eax
004E6520 |. 8B45 E4 mov eax,[local.7]
004E6523 |. 8945 F4 mov [local.3],eax ======>进入!!上面的call winchm.004E6450如下(实质上是计算3^n): 004E6458 |. 8BF0 mov esi,eax
004E645A |. 8BC6 mov eax,esi ; esi==eax==3
004E645C |. 99 cdq
004E645D |. 8945 F8 mov [local.2],eax
004E6460 |. 8955 FC mov [local.1],edx
004E6463 |. 8B5D 08 mov ebx,[arg.1] ; 用上层循环次数来作这里的循环控制
004E6466 |. 85DB test ebx,ebx
004E6468 |. 7C 1A jl short winchm.004E6484
004E646A |. 43 inc ebx ; +1
004E646B |> 8BC6 /mov eax,esi ; esi=3
004E646D |. 99 |cdq
004E646E |. 52 |push edx
004E646F |. 50 |push eax
004E6470 |. 8B45 F8 |mov eax,[local.2] ; ==3(下次就是上轮的结果)
004E6473 |. 8B55 FC |mov edx,[local.1]
004E6476 |. E8 91ECF1FF |call winchm.0040510C ; int64乘法
004E647B |. 8945 F8 |mov [local.2],eax ; 保存结果
004E647E |. 8955 FC |mov [local.1],edx
004E6481 |. 4B |dec ebx
004E6482 |.^ 75 E7 \jnz short winchm.004E646B
004E6484 |> 8B45 F8 mov eax,[local.2] ; 结果就是3^n
004E6487 |. 8B55 FC mov edx,[local.1]
004E648A |. 5E pop esi ======>int64乘法 call winchm.0040510C :
这个是delphi的系统函数(procedure __llmul):
0040510C /$ 52 push edx ; int64 乘法
0040510D |. 50 push eax
0040510E |. 8B4424 10 mov eax,[dword ss:esp+10] ; c2的高位
00405112 |. F72424 mul [dword ss:esp] ; *c1的低位
00405115 |. 89C1 mov ecx,eax ; 结果==>ecx
00405117 |. 8B4424 04 mov eax,[dword ss:esp+4] ; c1的高位
0040511B |. F76424 0C mul [dword ss:esp+C] ; *c2的低位
0040511F |. 01C1 add ecx,eax ; 结果累加在ecx
00405121 |. 8B0424 mov eax,[dword ss:esp] ; c1的低位
00405124 |. F76424 0C mul [dword ss:esp+C] ; *c2的低位,就是返回值的低位--eax
00405128 |. 01CA add edx,ecx ; ecx累加在本次积的高位,就是返回值的高位--edx
0040512A |. 59 pop ecx
0040512B |. 59 pop ecx
0040512C \. C2 0800 retn 8 Borland的说法如下:
// 64 bit integer helper routines
//
// These functions always return the 64-bit result in EAX:EDX
// ------------------------------------------------------------------------------
// 64-bit signed multiply
// ------------------------------------------------------------------------------
//
// Param 1(EAX:EDX), Param 2([ESP+8]:[ESP+4]) ; before reg pushing
// 注册算法描述如下:
用注册码每1位的ASCII码与3的n次方进行int64乘法运算(n==注册码的对应位数+1),结果进行累加,累加和只能有7种情形注册成功!
这7种情形的运算结果分别如下所示,它分别对应了一种License类型(验证过程同硬件或用户名无关, 这样一来,就可以一码行天下了!): 004E6C2B |. 8945 F0 mov [dword ss:ebp-10],eax
004E6C2E |. 8955 F4 mov [dword ss:ebp-C],edx
004E6C31 |. 817D F4 9902000>cmp [dword ss:ebp-C],299
004E6C38 |. 75 1A jnz short winchm.004E6C54
004E6C3A |. 817D F0 5BA60EF>cmp [dword ss:ebp-10],F90EA65B ===>1:$299F90EA65B
004E6C41 |. 75 11 jnz short winchm.004E6C54
004E6C43 |. 8BC3 mov eax,ebx
004E6C45 |. BA 78714E00 mov edx,winchm.004E7178 ; ASCII "Single-user License"
004E6C4A |. E8 0DD5F1FF call winchm.0040415C
004E6C4F |. E9 E5040000 jmp winchm.004E7139
004E6C54 |> 817D F4 7D03000>cmp [dword ss:ebp-C],37D
004E6C5B |. 75 1A jnz short winchm.004E6C77
004E6C5D |. 817D F0 CAC1000>cmp [dword ss:ebp-10],800C1CA ===>2:$37D0800C1CA
004E6C64 |. 75 11 jnz short winchm.004E6C77
004E6C66 |. 8BC3 mov eax,ebx
004E6C68 |. BA 94714E00 mov edx,winchm.004E7194 ; ASCII "2-user License"
004E6C6D |. E8 EAD4F1FF call winchm.0040415C
004E6C72 |. E9 C2040000 jmp winchm.004E7139
004E6C77 |> 817D F4 9D02000>cmp [dword ss:ebp-C],29D
004E6C7E |. 75 1A jnz short winchm.004E6C9A
004E6C80 |. 817D F0 10AF842>cmp [dword ss:ebp-10],2884AF10 ===>3:$29D2884AF10
004E6C87 |. 75 11 jnz short winchm.004E6C9A
004E6C89 |. 8BC3 mov eax,ebx
004E6C8B |. BA AC714E00 mov edx,winchm.004E71AC ; ASCII "5-user License"
004E6C90 |. E8 C7D4F1FF call winchm.0040415C
004E6C95 |. E9 9F040000 jmp winchm.004E7139
004E6C9A |> 817D F4 6802000>cmp [dword ss:ebp-C],268
004E6CA1 |. 75 1A jnz short winchm.004E6CBD
004E6CA3 |. 817D F0 ED55AE4>cmp [dword ss:ebp-10],4FAE55ED ===>4:$2684FAE55ED
004E6CAA |. 75 11 jnz short winchm.004E6CBD
004E6CAC |. 8BC3 mov eax,ebx
004E6CAE |. BA C4714E00 mov edx,winchm.004E71C4 ; ASCII "10-user License"
004E6CB3 |. E8 A4D4F1FF call winchm.0040415C
004E6CB8 |. E9 7C040000 jmp winchm.004E7139
004E6CBD |> 817D F4 0F03000>cmp [dword ss:ebp-C],30F
004E6CC4 |. 75 1A jnz short winchm.004E6CE0
004E6CC6 |. 817D F0 A9C407B>cmp [dword ss:ebp-10],B107C4A9 ===>5:$30FB107C4A9
004E6CCD |. 75 11 jnz short winchm.004E6CE0
004E6CCF |. 8BC3 mov eax,ebx
004E6CD1 |. BA DC714E00 mov edx,winchm.004E71DC ; ASCII "20-user License"
004E6CD6 |. E8 81D4F1FF call winchm.0040415C
004E6CDB |. E9 59040000 jmp winchm.004E7139
004E6CE0 |> 817D F4 E002000>cmp [dword ss:ebp-C],2E0
004E6CE7 |. 75 1A jnz short winchm.004E6D03
004E6CE9 |. 817D F0 FB6A6F0>cmp [dword ss:ebp-10],0E6F6AFB ===>6:$2E00E6F6AFB
004E6CF0 |. 75 11 jnz short winchm.004E6D03
004E6CF2 |. 8BC3 mov eax,ebx
004E6CF4 |. BA F4714E00 mov edx,winchm.004E71F4 ; ASCII "50-user License"
004E6CF9 |. E8 5ED4F1FF call winchm.0040415C
004E6CFE |. E9 36040000 jmp winchm.004E7139
004E6D03 |> 817D F4 2A03000>cmp [dword ss:ebp-C],32A
004E6D0A |. 75 1A jnz short winchm.004E6D26
004E6D0C |. 817D F0 B27EC9B>cmp [dword ss:ebp-10],BCC97EB2 ===>7:$32ABCC97EB2
004E6D13 |. 75 11 jnz short winchm.004E6D26
004E6D15 |. 8BC3 mov eax,ebx
004E6D17 |. BA 0C724E00 mov edx,winchm.004E720C ; ASCII "Site License"
004E6D1C |. E8 3BD4F1FF call winchm.0040415C
004E6D21 |. E9 13040000 jmp winchm.004E7139 如果License类型为空, 那就是未注册了!
004E75AA . A1 0C485100 mov eax,[dword ds:51480C]
004E75AF . 8B00 mov eax,[dword ds:eax] ; (UNICODE "Site License")
004E75B1 . 33D2 xor edx,edx
004E75B3 . E8 14D5F1FF call winchm.00404ACC
004E75B8 . 75 16 jnz short winchm.004E75D0
004E75BA . A1 244A5100 mov eax,[dword ds:514A24]
004E75BF . BA 28764E00 mov edx,winchm.004E7628 ; UNICODE " [Unregistered]"
004E75C4 . E8 F7D3F1FF call winchm.004049C0
004E75C9 . A1 244A5100 mov eax,[dword ds:514A24]
004E75CE . EB 0A jmp short winchm.004E75DA
004E75D0 > A1 244A5100 mov eax,[dword ds:514A24]
004E75D5 . E8 56D2F1FF call winchm.00404830
004E75DA > 33C0 xor eax,eax 它的验证算法很简单,实现如下(大至的原里,细节上可能不对!):
var a,b,c:int64;
.....
result:=0;
for i:=0 to 19 do
begin
a:=int64(3)^(i+2);
b:=注册码[i];
c:=a*b;
result:=result+c;
end;
.....
注册机全部源代码(我没有更好的办法,也就只有穷举了):
var
Form1: TForm1;
bstr:array[0..19] of byte;
cstr:array[0..19] of int64;
str:array[0..20] of int64;
sstr:string[20];
implementation
{$R *.dfm}
function Butt(a:int64;b:integer):int64;
var i:integer;
begin
result:=a;
for i:=1 to b do
begin
result:=result*a;
end;
end;
procedure Tck;
var i:integer;
begin
for i:=0 to 19 do
begin
str[i]:=Butt(3,i+2);
end;
end;
procedure TForck(a:BYTE);
var i:integer;
begin
for i:=0 to 19 do
begin
bstr[i]:=a;
end;
end;
procedure subbb;
var a,b:int64;
i:integer;
begin
a:=$32ABCC97EB2; //ASCII "Site License" ======>我仅仅以这种License为例!!
b:=0;
for i:=0 to 19 do
begin
cstr[i]:=str[i]*bstr[i];
b:=b+cstr[i];
end;
str[20]:=a-b;
end;
procedure filstr;
var i:integer;
begin
for i:=19 downto 0 do
begin
byte(sstr[i+1]):=bstr[i];
end;
byte(sstr[0]):=20;
end;
// bstr[i]:=bstr[i-n]*3^n
procedure TForm1.ton2C;
var i:integer;
begin
if CheckBox1.Checked then
begin
for i:=19 downto 1 do
begin
//为了不在注册码中出现小写字母和不可输入字符,有如下限制
if (bstr[i]<$5D) and (bstr[i]>$21) and (bstr[i-1]<$5D) and (bstr[i-1]>$1E) then
begin
bstr[i]:=bstr[i]-1;
bstr[i-1]:=bstr[i-1]+3;
end;
end;
end else
begin
for i:=19 downto 2 do
begin
//为了不在注册码中出现小写字母和不可输入字符,有如下限制
if (bstr[i]>$1F) and (bstr[i]<$60) and (bstr[i-2]>$29) and (bstr[i-2]<$69) then
begin
bstr[i]:=bstr[i]+1;
bstr[i-2]:=bstr[i-2]-9;
end;
end;
end ;
end;
procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
d:byte;
Label fff,ffg;
begin
subbb;
if str[20] = 0 then goto fff;
while str[20]> 0 do
begin
d:=bstr[0];
TForck(d+1);
subbb;
end;
d:=bstr[0];
TForck(d-1);
subbb;
for i:=19 downto 0 do
begin
if str[20] = 0 then goto ffg;
while str[20]> 0 do
begin
bstr[i]:=bstr[i]+1;
subbb;
if str[20] = 0 then goto ffg;
end;
bstr[i]:=bstr[i]-1;
subbb;
end;
fff:
ton2C;
ffg:
filstr;
Edit1.Text:=sstr;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
Tck;
TForck($30); //用'0'初始, 其实我们可以一开始就用$49初始
end;
end. 注册机并不能算出全部注册码, 因为我仅仅考虑了很少的情况, 但对这种验证方式, 有一个注册码就够了!
可用注册码:
]TCZZXRSUZZQZBYTJTLH
<;=<<<<><<>>>=>>=>PJ
ZUCZZXRSUZZQZBYTJTII
至于其它几种情形变化不是很大,也不是很难,就留下你来分析好了...
程序对时间(试用期)的检查在下面, 我对浮点运算不懂, 无法解说了, 自己看看好了:
004EA9EF |. B1 01 mov cl,1
004EA9F1 |. BA 40AB4E00 mov edx,winchm.004EAB40 ; ASCII "\Software\Microsoft\Internet Explorer"
004EA9F6 |. 8BC3 mov eax,ebx
004EA9F8 |. E8 137AF5FF call winchm.00442410
004EA9FD |. BA 70AB4E00 mov edx,winchm.004EAB70 ; ASCII "CloseTime"
004EAA02 |. 8BC3 mov eax,ebx
004EAA04 |. E8 5382F5FF call winchm.00442C5C
004EAA09 |. 84C0 test al,al
004EAA0B |. 75 2E jnz short winchm.004EAA3B
004EAA0D |. E8 6E020000 call winchm.004EAC80
004EAA12 |. E8 99E8FFFF call winchm.004E92B0
004EAA17 |. E8 7403F2FF call winchm.0040AD90
004EAA1C |. 83C4 F8 add esp,-8 ; /
004EAA1F |. DD1C24 fstp [qword ss:esp] ; |Arg1 (8 字节)
004EAA22 |. 9B wait ; |
004EAA23 |. BA 70AB4E00 mov edx,winchm.004EAB70 ; |ASCII "CloseTime"
004EAA28 |. 8BC3 mov eax,ebx ; |
004EAA2A |. E8 0981F5FF call winchm.00442B38 ; \winchm.00442B38
004EAA2F |. C786 10030000>mov [dword ds:esi+310],0F
004EAA39 |. EB 74 jmp short winchm.004EAAAF
004EAA3B |> \E8 5003F2FF call winchm.0040AD90
004EAA40 |. 83C4 F8 add esp,-8
004EAA43 |. DD1C24 fstp [qword ss:esp]
004EAA46 |. 9B wait
004EAA47 |. BA 70AB4E00 mov edx,winchm.004EAB70 ; ASCII "CloseTime"
004EAA4C |. 8BC3 mov eax,ebx
004EAA4E |. E8 F980F5FF call winchm.00442B4C
004EAA53 |. 83C4 F8 add esp,-8 ; |
004EAA56 |. DD1C24 fstp [qword ss:esp] ; |Arg1 (8 字节)
004EAA59 |. 9B wait ; |
004EAA5A |. E8 2DB4FFFF call winchm.004E5E8C ; \winchm.004E5E8C
004EAA5F |. 84C0 test al,al
004EAA61 |. 7C 33 jl short winchm.004EAA96
004EAA63 |. E8 2803F2FF call winchm.0040AD90
004EAA68 |. 83C4 F8 add esp,-8
004EAA6B |. DD1C24 fstp [qword ss:esp]
004EAA6E |. 9B wait
004EAA6F |. BA 70AB4E00 mov edx,winchm.004EAB70 ; ASCII "CloseTime"
004EAA74 |. 8BC3 mov eax,ebx
004EAA76 |. E8 D180F5FF call winchm.00442B4C
004EAA7B |. 83C4 F8 add esp,-8 ; |
004EAA7E |. DD1C24 fstp [qword ss:esp] ; |Arg1 (8 字节)
004EAA81 |. 9B wait ; |
004EAA82 |. E8 DDB2FFFF call winchm.004E5D64 ; \winchm.004E5D64
004EAA87 |. BA 0F000000 mov edx,0F ; 最长试用期==15天(F)
004EAA8C |. 2BD0 sub edx,eax ; eax==已用天数
004EAA8E |. 8996 10030000 mov [dword ds:esi+310],edx ; 乘余天数
004EAA94 |. EB 08 jmp short winchm.004EAA9E
004EAA96 |> 33C0 xor eax,eax
004EAA98 |. 8986 10030000 mov [dword ds:esi+310],eax
004EAA9E |> 83BE 10030000>cmp [dword ds:esi+310],0 ; 试用期已用完?
004EAAA5 |. 7D 08 jge short winchm.004EAAAF
004EAAA7 |. 33C0 xor eax,eax
004EAAA9 |. 8986 10030000 mov [dword ds:esi+310],eax
004EAAAF |> 8BC3 mov eax,ebx
004EAAB1 |. E8 E677F5FF call winchm.0044229C
004EAAB6 |. 8BC3 mov eax,ebx
004EAAB8 |. E8 BB88F1FF call winchm.00403378
004EAABD |. 8D45 FC lea eax,[dword ss:ebp-4]
004EAAC0 |. 50 push eax ; /Arg1
004EAAC1 |. 8B86 10030000 mov eax,[dword ds:esi+310] ; |
004EAAC7 |. 8945 F4 mov [dword ss:ebp-C],eax ; |
004EAACA |. C645 F8 00 mov [byte ss:ebp-8],0 ; |
004EAACE |. 8D55 F4 lea edx,[dword ss:ebp-C] ; |
004EAAD1 |. 33C9 xor ecx,ecx ; |
004EAAD3 |. B8 84AB4E00 mov eax,winchm.004EAB84 ; |ASCII "%d days left for trial period"
004EAAD8 |. E8 D3F5F1FF call winchm.0040A0B0 ; \winchm.0040A0B0
004EAADD |. 8B55 FC mov edx,[dword ss:ebp-4]
004EAAE0 |. 8B86 0C030000 mov eax,[dword ds:esi+30C]
004EAAE6 |. E8 6916F9FF call winchm.0047C154
004EAAEB |. 83BE 10030000>cmp [dword ds:esi+310],0 ; 在次检查试用期已用完?
004EAAF2 |. 75 20 jnz short winchm.004EAB14
004EAAF4 |. BA ACAB4E00 mov edx,winchm.004EABAC ; ASCII "Close"
004EAAF9 |. 8B86 FC020000 mov eax,[dword ds:esi+2FC]
004EAAFF |. E8 5016F9FF call winchm.0047C154 好似在[HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer]下有一个"CloseTime"项, 记录了安装或第1次使用时间, 删除它就没有了限制?
注册机源码:
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
上传的附件: