• 标 题:WinPowerDown完全破解  
  • 作 者:RoBa
  • 时 间:2003/08/31 03:52pm
  • 链 接:http://bbs.pediy.com

WinPowerDown完全破解

又是从古董老光盘上找的一个软件,程序不大,功能也没多少,就是一个自动关机,但保护却做得相当不简单(对于我这样的菜鸟来说).我把它放了上来,当一个CrackMe吧!

运行,先来一个下马威:"Soft-Ice detected shutting down",好家伙,祭出FrogsICE,点一个Enable按钮,顺利闯关!
HEHE~~,别找不到输入注册码的地方哟.点About,再点第二行那个加下划线的"Register Information",终于出来了(好隐蔽 )
输入NAME:RoBa , CODE:87654321 下断,很容易来到这里:

:00455AAD 53                      push ebx
:00455AAE 56                      push esi
:00455AAF 8BD8                    mov ebx, eax
:00455AB1 33C0                    xor eax, eax
:00455AB3 55                      push ebp
:00455AB4 68335C4500              push 00455C33
:00455AB9 64FF30                  push dword ptr fs:[eax]
:00455ABC 648920                  mov dword ptr fs:[eax], esp
:00455ABF 8D55F8                  lea edx, dword ptr [ebp-08]
:00455AC2 8B83D0020000            mov eax, dword ptr [ebx+000002D0]
:00455AC8 E84736FDFF              call 00429114
:00455ACD 8B45F8                  mov eax, dword ptr [ebp-08]       <--刚进来是在这里
:00455AD0 8D55FC                  lea edx, dword ptr [ebp-04]       <--EAX为假码

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455A64(C)
|
:00455AD3 E8C4200000              call 00457B9C  <--这里才是真正的关键(见下面的分析)
:00455AD8 8B45FC                  mov eax, dword ptr [ebp-04]
:00455ADB 50                      push eax
:00455ADC 8D55F8                  lea edx, dword ptr [ebp-08]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455A70(C)
|
:00455ADF 8B83CC020000            mov eax, dword ptr [ebx+000002CC]
:00455AE5 E82A36FDFF              call 00429114
:00455AEA 8B55F8                  mov edx, dword ptr [ebp-08]
:00455AED 58                      pop eax
:00455AEE E8E5E1FAFF              call 00403CD8  <--这个好像是关键的CALL,从下面很容易找到这里
:00455AF3 0F85E6000000            jne 00455BDF   <--跳过去就OVER
:00455AF9 8B83CC020000            mov eax, dword ptr [ebx+000002CC]
:00455AFF E88435FDFF              call 00429088      <--得到NAME长度
:00455B04 83F804                  cmp eax, 00000004  <--NAME长度与4比较
:00455B07 0F8ED2000000            jle 00455BDF       <--小于等于4就OVER
:00455B0D B201                    mov dl, 01
:00455B0F A10CE24400              mov eax, dword ptr [0044E20C]
:00455B14 E83388FFFF              call 0044E34C
:00455B19 8BF0                    mov esi, eax
:00455B1B BA02000080              mov edx, 80000002
:00455B20 8BC6                    mov eax, esi
:00455B22 E8BD88FFFF              call 0044E3E4
:00455B27 B101                    mov cl, 01

* Possible StringData Ref from Code Obj ->"SOFTWARE\Koger\WinPowerDown"
                                 |
:00455B29 BA485C4500              mov edx, 00455C48
:00455B2E 8BC6                    mov eax, esi
:00455B30 E81389FFFF              call 0044E448
:00455B35 8D55F8                  lea edx, dword ptr [ebp-08]
:00455B38 8B83CC020000            mov eax, dword ptr [ebx+000002CC]
:00455B3E E8D135FDFF              call 00429114
:00455B43 8B4DF8                  mov ecx, dword ptr [ebp-08]

* Possible StringData Ref from Code Obj ->"Name"
                                 |
:00455B46 BA6C5C4500              mov edx, 00455C6C
:00455B4B 8BC6                    mov eax, esi
:00455B4D E8928AFFFF              call 0044E5E4
:00455B52 8D55F8                  lea edx, dword ptr [ebp-08]
:00455B55 8B83D0020000            mov eax, dword ptr [ebx+000002D0]
:00455B5B E8B435FDFF              call 00429114
:00455B60 8B45F8                  mov eax, dword ptr [ebp-08]
:00455B63 50                      push eax
:00455B64 8D55FC                  lea edx, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"B269A74F" <--莫名其妙
                                 |
:00455B67 B87C5C4500              mov eax, 00455C7C
:00455B6C E82B200000              call 00457B9C
:00455B71 8B55FC                  mov edx, dword ptr [ebp-04]
:00455B74 8BC6                    mov eax, esi
:00455B76 59                      pop ecx
:00455B77 E8688AFFFF              call 0044E5E4
:00455B7C 8BC6                    mov eax, esi
:00455B7E E829D2FAFF              call 00402DAC
:00455B83 A154BF4500              mov eax, dword ptr [0045BF54]
:00455B88 C60001                  mov byte ptr [eax], 01
:00455B8B 6A00                    push 00000000

* Possible StringData Ref from Code Obj ->"Thank you "
                                 |
:00455B8D 68905C4500              push 00455C90
:00455B92 8D55F8                  lea edx, dword ptr [ebp-08]
:00455B95 8B83CC020000            mov eax, dword ptr [ebx+000002CC]
:00455B9B E87435FDFF              call 00429114  <--到这里就成功了
:00455BA0 FF75F8                  push [ebp-08]
:00455BA3 8D55F4                  lea edx, dword ptr [ebp-0C]

* Possible StringData Ref from Code Obj ->"F561AE7092DD27E923E833D02DE531F4131542FC14E658"
                                       ->"B046DC26040315F4"  <--莫名其妙的干扰字串
                                 |
:00455BA6 B8A45C4500              mov eax, 00455CA4
:00455BAB E8EC1F0000              call 00457B9C
:00455BB0 FF75F4                  push [ebp-0C]

* Possible StringData Ref from Code Obj ->". If you have any suggestions, "
                                       ->"please write to me at koger@iname.com"
                                 |
:00455BB3 68EC5C4500              push 00455CEC
:00455BB8 8D45FC                  lea eax, dword ptr [ebp-04]
:00455BBB BA04000000              mov edx, 00000004
:00455BC0 E8C3E0FAFF              call 00403C88
:00455BC5 8B45FC                  mov eax, dword ptr [ebp-04]
:00455BC8 668B0D345D4500          mov cx, word ptr [00455D34]
:00455BCF B202                    mov dl, 02
:00455BD1 E8C647FFFF              call 0044A39C
:00455BD6 8BC3                    mov eax, ebx
:00455BD8 E827C9FEFF              call 00442504
:00455BDD EB2E                    jmp 00455C0D

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00455AF3(C), :00455B07(C)
|
:00455BDF 6A00                    push 00000000
:00455BE1 8D55FC                  lea edx, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"E34CD729E72037CC40C342C259BC77859E61B8BD53A664"
                                       ->"BEB1"    <--又是一堆干扰字串
                                 |
:00455BE4 B8405D4500              mov eax, 00455D40
:00455BE9 E8AE1F0000              call 00457B9C
:00455BEE 8B45FC                  mov eax, dword ptr [ebp-04]
:00455BF1 668B0D345D4500          mov cx, word ptr [00455D34]
:00455BF8 B201                    mov dl, 01
:00455BFA E89D47FFFF              call 0044A39C  <--在这里会有出错提示,向上找跳过此处的地方
:00455BFF 8B83CC020000            mov eax, dword ptr [ebx+000002CC]
:00455C05 8B10                    mov edx, dword ptr [eax]
:00455C07 FF92B4000000            call dword ptr [edx+000000B4]

好像不太难嘛,进入455AEE处的CALL看看.追了半天发现,程序将我输入的用户名RoBa与一个乱七八糟,根本不是可输入字符的东东比较(下面会有比较过程),一样的话就注册成功.难道我们能从键盘上输入这种字符?当然不是.注意一开始的时候程序就把假码87654321取了出来,因此我推测程序是从注册码反算出用户名(好狡猾 ),因为我们的假码不符合规定,所以算出的NAME也就乱七八糟啦.

那么我们从455ACD处取出假码后向后看,到455AEE处一共有两个CALL,先进455AD3看看:

* Referenced by a CALL at Addresses:
|:00455AD3   , :00455B6C   , :00455BAB   , :00455BE9   , :00457D8D  
|:00458D51   , :00458D6A  
|
:00457B9C 55                      push ebp

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00457B28(C)
|
:00457B9D 8BEC                    mov ebp, esp
:00457B9F 83C4DC                  add esp, FFFFFFDC
:00457BA2 53                      push ebx
:00457BA3 56                      push esi
:00457BA4 57                      push edi
:00457BA5 33C9                    xor ecx, ecx
:00457BA7 894DE0                  mov dword ptr [ebp-20], ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00457B3B(C)
|
:00457BAA 894DDC                  mov dword ptr [ebp-24], ecx
:00457BAD 894DE8                  mov dword ptr [ebp-18], ecx
:00457BB0 894DE4                  mov dword ptr [ebp-1C], ecx
:00457BB3 8955F8                  mov dword ptr [ebp-08], edx
:00457BB6 8945FC                  mov dword ptr [ebp-04], eax
:00457BB9 8B45FC                  mov eax, dword ptr [ebp-04]
:00457BBC E8BBC1FAFF              call 00403D7C
:00457BC1 33C0                    xor eax, eax
:00457BC3 55                      push ebp
:00457BC4 68F57C4500              push 00457CF5
:00457BC9 64FF30                  push dword ptr fs:[eax]
:00457BCC 648920                  mov dword ptr fs:[eax], esp
:00457BCF 8D45E8                  lea eax, dword ptr [ebp-18]

* Possible StringData Ref from Code Obj ->"winpowerdown"
                                 |
:00457BD2 BA0C7D4500              mov edx, 00457D0C
:00457BD7 E808BEFAFF              call 004039E4
:00457BDC 8B45E8                  mov eax, dword ptr [ebp-18]
:00457BDF E8E4BFFAFF              call 00403BC8
:00457BE4 8945F4                  mov dword ptr [ebp-0C], eax
:00457BE7 33F6                    xor esi, esi
:00457BE9 33C0                    xor eax, eax
:00457BEB 55                      push ebp
:00457BEC 68BD7C4500              push 00457CBD
:00457BF1 64FF30                  push dword ptr fs:[eax]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00457B85(C)
|
:00457BF4 648920                  mov dword ptr fs:[eax], esp
:00457BF7 8D45DC                  lea eax, dword ptr [ebp-24]
:00457BFA 50                      push eax
:00457BFB B902000000              mov ecx, 00000002
:00457C00 BA01000000              mov edx, 00000001 <--EDX=1 这是下面CALL的一个参数
:00457C05 8B45FC                  mov eax, dword ptr [ebp-04] <--EAX=假码
:00457C08 E8BFC1FAFF              call 00403DCC <--这个CALL是从第EDX个字符起取假码的两个字符,作为下面比较的"旧数"
                                               <--我是从结果推测出来的
:00457C0D 8B4DDC                  mov ecx, dword ptr [ebp-24] <--ECX=取出来的两字符
:00457C10 8D45E0                  lea eax, dword ptr [ebp-20]
:00457C13 BA247D4500              mov edx, 00457D24    <--EDX='$'
:00457C18 E8F7BFFAFF              call 00403C14 <--把'$'和两个字符合并起来
:00457C1D 8B45E0                  mov eax, dword ptr [ebp-20] <--合并后给EAX
                                               <--DELPHI中表现十六进制数的方法
:00457C20 E8FBFFFAFF              call 00407C20 <--把两个字符变成数给了EAX
                                               <--如果你的假码出现了0-F以外的就OVER了
:00457C25 8BF8                    mov edi, eax
:00457C27 C745F003000000          mov [ebp-10], 00000003 <--[ebp-10]是循环变量=3

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00457CAD(C)
|
:00457C2E 8D45DC                  lea eax, dword ptr [ebp-24]
:00457C31 50                      push eax
:00457C32 B902000000              mov ecx, 00000002
:00457C37 8B55F0                  mov edx, dword ptr [ebp-10] <--EDX=[EBP-10]
:00457C3A 8B45FC                  mov eax, dword ptr [ebp-04] <--EAX=假码
:00457C3D E88AC1FAFF              call 00403DCC <--从第[EBP-10]个字符起取两个字符(和上面一样)
:00457C42 8B4DDC                  mov ecx, dword ptr [ebp-24]
:00457C45 8D45E0                  lea eax, dword ptr [ebp-20]
:00457C48 BA247D4500              mov edx, 00457D24
:00457C4D E8C2BFFAFF              call 00403C14
:00457C52 8B45E0                  mov eax, dword ptr [ebp-20]
:00457C55 E8C6FFFAFF              call 00407C20 <--和上面相同的计算 EAX=字符变成的数(记为"新数")
:00457C5A 8945EC                  mov dword ptr [ebp-14], eax <--"新数"放在[EBP-14]
:00457C5D 3B75F4                  cmp esi, dword ptr [ebp-0C] <--看ESI是否大于10
:00457C60 7D03                    jge 00457C65
:00457C62 46                      inc esi <--ESI不大于10就ESI+1
:00457C63 EB05                    jmp 00457C6A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00457C60(C)
|
:00457C65 BE01000000              mov esi, 00000001 <--ESI大于10就ESI=1
                            <--从下面知道ESI是控制循环取出"winpowerdown"这10个字符
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00457C63(U)
|
:00457C6A 8B45E8                  mov eax, dword ptr [ebp-18] <--[ebp-18]处是字串"winpowerdown"
:00457C6D 33DB                    xor ebx, ebx
:00457C6F 8A5C30FF                mov bl, byte ptr [eax+esi-01]<--依次取出字符
:00457C73 335DEC                  xor ebx, dword ptr [ebp-14] <--[EBP-14]是刚取出的"新数",与字符进行异或运算,放入EBX
:00457C76 3BFB                    cmp edi, ebx <--EDI为"旧数",与EBX比较
:00457C78 7C0A                    jl 00457C84
:00457C7A 81C3FF000000            add ebx, 000000FF
:00457C80 2BDF                    sub ebx, edi
:00457C82 EB02                    jmp 00457C86

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00457C78(C)
|
:00457C84 2BDF                    sub ebx, edi <--若EBX>EDI则EBX=EBX-EDI,否则EBX=EBX+$FF-EDI

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00457C82(U)
|
:00457C86 8D45E0                  lea eax, dword ptr [ebp-20]
:00457C89 8BD3                    mov edx, ebx
:00457C8B E860BEFAFF              call 00403AF0 <--这个CALL好像是把计算结果放入内存中
:00457C90 8B55E0                  mov edx, dword ptr [ebp-20]
:00457C93 8D45E4                  lea eax, dword ptr [ebp-1C]
:00457C96 E835BFFAFF              call 00403BD0
:00457C9B 8B7DEC                  mov edi, dword ptr [ebp-14]<--把"新数"存入EDI作下次比较的"旧数"
:00457C9E 8345F002                add dword ptr [ebp-10], 00000002 <--[EBP-10]每次+2
:00457CA2 8B45FC                  mov eax, dword ptr [ebp-04]
:00457CA5 E81EBFFAFF              call 00403BC8
:00457CAA 3B45F0                  cmp eax, dword ptr [ebp-10] <--EAX为假码长度,看是否计算完毕
:00457CAD 0F8F7BFFFFFF            jg 00457C2E     <--循环结束
:00457CB3 33C0                    xor eax, eax
:00457CB5 5A                      pop edx
:00457CB6 59                      pop ecx
:00457CB7 59                      pop ecx
:00457CB8 648910                  mov dword ptr fs:[eax], edx
:00457CBB EB0A                    jmp 00457CC7
:00457CBD E942B5FAFF              jmp 00403204
:00457CC2 E8EDB7FAFF              call 004034B4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00457CBB(U)
|
:00457CC7 8B45F8                  mov eax, dword ptr [ebp-08]
:00457CCA 8B55E4                  mov edx, dword ptr [ebp-1C]
:00457CCD E812BDFAFF              call 004039E4
:00457CD2 33C0                    xor eax, eax
:00457CD4 5A                      pop edx
:00457CD5 59                      pop ecx
:00457CD6 59                      pop ecx
:00457CD7 648910                  mov dword ptr fs:[eax], edx
:00457CDA 68FC7C4500              push 00457CFC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00457CFA(U)
|
:00457CDF 8D45DC                  lea eax, dword ptr [ebp-24]
:00457CE2 BA04000000              mov edx, 00000004
:00457CE7 E884BCFAFF              call 00403970
:00457CEC 8D45FC                  lea eax, dword ptr [ebp-04]
:00457CEF E858BCFAFF              call 0040394C
:00457CF4 C3                      ret

整理一下思路,程序先取出CODE的前两位(用M表示),然后再取后面的两位(用N表示),并且从字串"winpowerdown"中每次循环取出一个字符(用P表示),计算S=(N XOR P)-M,如果结果S小于0则加上S=S+$FF(这个S必须与NAME中的字符符合)然后把N给了M,再取后面的两位作为N计算,直到CODE取完为止,计算出的一串字符与NAME完全相同则注册成功.

下面是455AED处的CALL,只是将计算结果与用户名比较(这个阴险的软件害得我在这里面找了半天才发现不对):

* Referenced by a CALL at Addresses:
|:0040F477   , :004137C9   , :00418999   , :00419848   , :00428232  
|:004282BD   , :00428EF7   , :0042916C   , :00433BB3   , :0043419D  
|:0043430D   , :00434481   , :004371D9   , :0043729D   , :00437678  
|:00437737   , :00437B92   , :00437DE6   , :00438351   , :0043850F  
|:00445F17   , :0044BC14   , :0044BFF9   , :00455AEE   , :004564EE  
|:00458356   , :00458D87   , :00459677   , :004596F6  <--无数次的进行检查,想暴破真的不容易  
|
:00403CD8 53                      push ebx
:00403CD9 56                      push esi
:00403CDA 57                      push edi
:00403CDB 89C6                    mov esi, eax <--[esi]处是上面的计算结果
:00403CDD 89D7                    mov edi, edx <--[edi]处是输入的NAME
:00403CDF 39D0                    cmp eax, edx
:00403CE1 0F848F000000            je 00403D76
:00403CE7 85F6                    test esi, esi
:00403CE9 7468                    je 00403D53
:00403CEB 85FF                    test edi, edi
:00403CED 746B                    je 00403D5A
:00403CEF 8B46FC                  mov eax, dword ptr [esi-04]
:00403CF2 8B57FC                  mov edx, dword ptr [edi-04]
:00403CF5 29D0                    sub eax, edx
:00403CF7 7702                    ja 00403CFB
:00403CF9 01C2                    add edx, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403CF7(C)
|
:00403CFB 52                      push edx
:00403CFC C1EA02                  shr edx, 02
:00403CFF 7426                    je 00403D27

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403D1D(C)
|
:00403D01 8B0E                    mov ecx, dword ptr [esi]
:00403D03 8B1F                    mov ebx, dword ptr [edi]
:00403D05 39D9                    cmp ecx, ebx
:00403D07 7558                    jne 00403D61
:00403D09 4A                      dec edx
:00403D0A 7415                    je 00403D21
:00403D0C 8B4E04                  mov ecx, dword ptr [esi+04]
:00403D0F 8B5F04                  mov ebx, dword ptr [edi+04]
:00403D12 39D9                    cmp ecx, ebx
:00403D14 754B                    jne 00403D61
:00403D16 83C608                  add esi, 00000008
:00403D19 83C708                  add edi, 00000008
:00403D1C 4A                      dec edx
:00403D1D 75E2                    jne 00403D01
:00403D1F EB06                    jmp 00403D27

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403D0A(C)
|
:00403D21 83C604                  add esi, 00000004
:00403D24 83C704                  add edi, 00000004

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00403CFF(C), :00403D1F(U)
|
:00403D27 5A                      pop edx
:00403D28 83E203                  and edx, 00000003
:00403D2B 7422                    je 00403D4F
:00403D2D 8B0E                    mov ecx, dword ptr [esi]
:00403D2F 8B1F                    mov ebx, dword ptr [edi]
:00403D31 38D9                    cmp cl, bl
:00403D33 7541                    jne 00403D76
:00403D35 4A                      dec edx
:00403D36 7417                    je 00403D4F
:00403D38 38FD                    cmp ch, bh
:00403D3A 753A                    jne 00403D76
:00403D3C 4A                      dec edx
:00403D3D 7410                    je 00403D4F
:00403D3F 81E30000FF00            and ebx, 00FF0000
:00403D45 81E10000FF00            and ecx, 00FF0000
:00403D4B 39D9                    cmp ecx, ebx
:00403D4D 7527                    jne 00403D76

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00403D2B(C), :00403D36(C), :00403D3D(C)
|
:00403D4F 01C0                    add eax, eax
:00403D51 EB23                    jmp 00403D76

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403CE9(C)
|
:00403D53 8B57FC                  mov edx, dword ptr [edi-04]
:00403D56 29D0                    sub eax, edx
:00403D58 EB1C                    jmp 00403D76

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403CED(C)
|
:00403D5A 8B46FC                  mov eax, dword ptr [esi-04]
:00403D5D 29D0                    sub eax, edx
:00403D5F EB15                    jmp 00403D76

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00403D07(C), :00403D14(C)
|
:00403D61 5A                      pop edx
:00403D62 38D9                    cmp cl, bl  
:00403D64 7510                    jne 00403D76
:00403D66 38FD                    cmp ch, bh
:00403D68 750C                    jne 00403D76
:00403D6A C1E910                  shr ecx, 10
:00403D6D C1EB10                  shr ebx, 10
:00403D70 38D9                    cmp cl, bl
:00403D72 7502                    jne 00403D76
:00403D74 38FD                    cmp ch, bh

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00403CE1(C), :00403D33(C), :00403D3A(C), :00403D4D(C), :00403D51(U)
|:00403D58(U), :00403D5F(U), :00403D64(C), :00403D68(C), :00403D72(C)
|
:00403D76 5F                      pop edi
:00403D77 5E                      pop esi
:00403D78 5B                      pop ebx
:00403D79 C3                      ret

这上面一堆跳来跳去让人烦,大致是每次取出32位(即4位字符)进行比较,然后再后跳32位再比等等,(我打字打得太累了,各位凑合看看吧,哪位大哥给补上注释小弟感激不尽~~~)总之只要NAME与注册码反算得到的一致就成功了.

算法搞定了,剩下的就是注册机了.因为判断是从CODE到NAME,写注册机还要逆回来:得到NAME以后,先任取两位数作CODE的前两位,然后CODE的(N*2+1)和(N*2+2)两位=[CODE的(N*2-1)和(N*2)两位组成的数+NAME中的第N个字符] XOR ['winpowerdown'中的第N个字符]  (XOR的逆运算恰巧也是XOR)


我写的注册机:(Borland Pascal 7.0)

Program CrackWinPowerDown;
var name,st,code:string;
   a:array[1..10] of integer;
   p,s,h,l :integer;
begin
    st:='winpowerdown';
    fillchar(code,sizeof(code),0);
    write('Please input your name:');
    readln(name);
    a[1]:=$66;   //可以在$00--$FF中任意选取
    for p:=1 to length(name) do
    begin
         s:=a[p]+ord(name[p]);
         if s>$FF then s:=s-$FF;
         a[p+1]:=(s xor ord(st[p]));
    end;
    for p:=1 to length(name)+1 do
    begin
         h:=a[p] div 16; l:=a[p] mod 16;
         if h<=9 then code[p*2-1]:=chr(48+h)
                 else code[p*2-1]:=chr(55+h);
         if l<=9 then code[p*2]:=chr(48+l)
                 else code[p*2]:=chr(55+l);
       //不知道怎么转成十六进制,用了一个笨方法
    end;
    write('CODE:');
    for p:=1 to (length(name)+1)*2 do
    write(code[p]); writeln;
    writeln('Crack by RoBa    Thank you');
end.

用注册机算出一个可用的NAME: RoBa1986
                     CODE: 66CF56F62836183519

输入以后,显示"THANK YOU",点确定~~~~????怎么还是Unregistered?难道还有暗桩?我晕倒...N分钟后悠悠醒转,关闭程序,再打开一次,"Register To RoBa1986". 原来如此!!