• 标 题:Tutor 9  How to crack Second Copy 97 version 5.31 build 96
  • 作 者:dREAMtHEATER
  • 时 间:13th, August 1999
  • 链 接:http://bbs.pediy.com

作者:dREAMtHEATER
E-mail:dreamtheater@263.net
写作日期:13th, August 1999

软件背景资料

运行平台: Win9X 
文件名称: setup97.exe
程序类型: 备份工具
下载地点: http://www.centered.com
文件大小: 702KB

使用的工具

SoftIce V4.0--Win9X Debugger
W32Dasm V8.93--Win9X Dissembler
Hex WorkShop v2.54--Hex Editor
RegSnap V2.51--Registry Analyzing Tool

难易程度

Easy(x)  Medium( )  Hard( )  Pro( )

                  ----------=======声明========----------

      未经作者同意,不得修改、引用原文,一切权利保留。
      本教程只供教学用,其他一切用途皆被禁止。
             
                  ----------=======软件介绍========----------
   
      软件的作者这样说:

      Second Copy 97 allows you to keep a "second copy" of all your important files at
a different location.  Set it up once and forget about it.  Second Copy 97 will copy
your files at specified intervals in the background without manual intervention. 
Initially it will copy all specified files.  In subsequent runs it will only copy new
or changed files.

                ----------=======软件的保护机制========-------

      典型的name/code注册形式,未注册时,每次启动都有nagscreen,告诉你还可以使用多少天
,时间和注册信息均存在本软件同目录下的SC97.cfg文件中

SC97.cfg格式(sample):

[General]
Settings=8E21  〈==第一次运行的时间
Version=5.31
Build=96
RegName=dREAMtHEATER 
RegKey=466A-2E7B-37B2

      这实际上就是一个INI文件,只有[General]一个小节,不要被他的文件扩展名所迷惑!
      另外,我还需说明,code还分"Single User License"与"Site License"之分,后面我会详
讲。

                  ----------========正文========----------

Part1 Snippet out code

      在注册窗口中,输入任意的name/code,我输入dREAMtHEATER/1234567890
      在SoftIce中设断点bpx hmemcpy ,Ctrl-D,回到注册窗口,press "Register" button,重新回
到SoftIce中,再次Ctrl-D,又立即回到SoftIce中,"bc *",取消所有断点,Press F12数次,程序停
在:

:00461DAE E875A5FCFF              call 0042C328
:00461DB3 8B45F8                  mov eax, dword ptr [ebp-08]  <==SoftIce回到这里,eax
向我们输入的code
:00461DB6 50                      push eax
:00461DB7 8D55F4                  lea edx, dword ptr [ebp-0C]  <==edx指向name
:00461DBA 8B83E4010000            mov eax, dword ptr [ebx+000001E4]
:00461DC0 E863A5FCFF              call 0042C328
:00461DC5 8B45F4                  mov eax, dword ptr [ebp-0C]
:00461DC8 5A                      pop edx
:00461DC9 E8D2F3FFFF              call 004611A0  <==计算注册码,trace into
:00461DCE 8BF0                    mov esi, eax
:00461DD0 85F6                    test esi, esi
:00461DD2 0F8E0A010000            jle 00461EE2    <==返回值esi<=0,注册失败
:00461DD8 8D45F0                  lea eax, dword ptr [ebp-10]
:00461DDB E82C0C0000              call 00462A0C
:00461DE0 8B4DF0                  mov ecx, dword ptr [ebp-10]
:00461DE3 B201                    mov dl, 01
:00461DE5 A1FC374400              mov eax, dword ptr [004437FC]
:00461DEA E8691AFEFF              call 00443858
:00461DEF 8945FC                  mov dword ptr [ebp-04], eax
:00461DF2 33C0                    xor eax, eax
:00461DF4 55                      push ebp
:00461DF5 68DB1E4600              push 00461EDB
:00461DFA 64FF30                  push dword ptr fs:[eax]
:00461DFD 648920                  mov dword ptr fs:[eax], esp
:00461E00 8D55F8                  lea edx, dword ptr [ebp-08]
:00461E03 8B83E4010000            mov eax, dword ptr [ebx+000001E4]
:00461E09 E81AA5FCFF              call 0042C328
:00461E0E 8B45F8                  mov eax, dword ptr [ebp-08]
:00461E11 50                      push eax

* Possible StringData Ref from Code Obj ->"RegName"
                                  |
:00461E12 B9A01F4600              mov ecx, 00461FA0

* Possible StringData Ref from Code Obj ->"General"
                                  |
:00461E17 BAB01F4600              mov edx, 00461FB0
:00461E1C 8B45FC                  mov eax, dword ptr [ebp-04]
:00461E1F E8C81AFEFF              call 004438EC
:00461E24 8D55F8                  lea edx, dword ptr [ebp-08]
:00461E27 8B83F0010000            mov eax, dword ptr [ebx+000001F0]
:00461E2D E8F6A4FCFF              call 0042C328
:00461E32 8B45F8                  mov eax, dword ptr [ebp-08]
:00461E35 50                      push eax

* Possible StringData Ref from Code Obj ->"RegKey"
                                  |
:00461E36 B9C01F4600              mov ecx, 00461FC0

* Possible StringData Ref from Code Obj ->"General"
                                  |
:00461E3B BAB01F4600              mov edx, 00461FB0
:00461E40 8B45FC                  mov eax, dword ptr [ebp-04]
:00461E43 E8A41AFEFF              call 004438EC
:00461E48 A1A0CE4700              mov eax, dword ptr [0047CEA0]
:00461E4D 8B00                    mov eax, dword ptr [eax]
:00461E4F 50                      push eax

* Possible StringData Ref from Code Obj ->"Version"
                                  |
:00461E50 B9D01F4600              mov ecx, 00461FD0

* Possible StringData Ref from Code Obj ->"General"
                                  |
:00461E55 BAB01F4600              mov edx, 00461FB0
:00461E5A 8B45FC                  mov eax, dword ptr [ebp-04]
:00461E5D E88A1AFEFF              call 004438EC
:00461E62 6A00                    push 00000000

* Possible StringData Ref from Code Obj ->"You are now registered with "
                                  |
:00461E64 68E01F4600              push 00461FE0
:00461E69 8D55EC                  lea edx, dword ptr [ebp-14]
:00461E6C 8BC6                    mov eax, esi
:00461E6E E87155FAFF              call 004073E4
:00461E73 FF75EC                  push [ebp-14]

* Possible StringData Ref from Code Obj ->" user license."
                                  |
:00461E76 6808204600              push 00462008
:00461E7B 6820204600              push 00462020

* Possible StringData Ref from Code Obj ->"Keep the registration key in a "
                                        ->"safe place."
                                  |
:00461E80 6830204600              push 00462030
:00461E85 6820204600              push 00462020

* Possible StringData Ref from Code Obj ->"You can also see this key on the "
                                        ->"About box."
                                  |
:00461E8A 6864204600              push 00462064
:00461E8F 8D45F0                  lea eax, dword ptr [ebp-10]
:00461E92 BA07000000              mov edx, 00000007
:00461E97 E8601EFAFF              call 00403CFC
:00461E9C 8B45F0                  mov eax, dword ptr [ebp-10]
:00461E9F 668B0D6C1F4600          mov cx, word ptr [00461F6C]
:00461EA6 B202                    mov dl, 02
:00461EA8 E833E5FDFF              call 004403E0
:00461EAD A194CE4700              mov eax, dword ptr [0047CE94]
:00461EB2 8B00                    mov eax, dword ptr [eax]
:00461EB4 33D2                    xor edx, edx
:00461EB6 E839F8FFFF              call 004616F4
:00461EBB C7835001000001000000    mov dword ptr [ebx+00000150], 00000001
:00461EC5 33C0                    xor eax, eax
:00461EC7 5A                      pop edx
:00461EC8 59                      pop ecx
:00461EC9 59                      pop ecx
:00461ECA 648910                  mov dword ptr fs:[eax], edx
:00461ECD 68351F4600              push 00461F35

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00461EE0(U)
|
:00461ED2 8B45FC                  mov eax, dword ptr [ebp-04]
:00461ED5 E84E0FFAFF              call 00402E28
:00461EDA C3                      ret


:00461EDB E90015FAFF              jmp 004033E0
:00461EE0 EBF0                    jmp 00461ED2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00461DD2(C)
|
:00461EE2 8D55F8                  lea edx, dword ptr [ebp-08]
:00461EE5 8B83F0010000            mov eax, dword ptr [ebx+000001F0]
:00461EEB E838A4FCFF              call 0042C328
:00461EF0 8B55F8                  mov edx, dword ptr [ebp-08]

* Possible StringData Ref from Code Obj ->"HELPMEPLEASE"
                                  |
:00461EF3 B898204600              mov eax, 00462098
:00461EF8 E82720FAFF              call 00403F24
:00461EFD 85C0                    test eax, eax
:00461EFF 7E1F                    jle 00461F20
:00461F01 8B83F4010000            mov eax, dword ptr [ebx+000001F4]
:00461F07 8B88E0000000            mov ecx, dword ptr [eax+000000E0]
:00461F0D A1DCCF4700              mov eax, dword ptr [0047CFDC]
:00461F12 8B00                    mov eax, dword ptr [eax]
:00461F14 BA01000000              mov edx, 00000001
:00461F19 E8524FFCFF              call 00426E70
:00461F1E EB15                    jmp 00461F35

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00461EFF(C)
|
:00461F20 6A00                    push 00000000
:00461F22 668B0D6C1F4600          mov cx, word ptr [00461F6C]
:00461F29 B201                    mov dl, 01

* Possible StringData Ref from Code Obj ->"Invalid Registration Key"
                                  |
:00461F2B B8B0204600              mov eax, 004620B0
:00461F30 E8ABE4FDFF              call 004403E0

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00461DA0(U), :00461F1E(U)
|
:00461F35 33C0                    xor eax, eax
:00461F37 5A                      pop edx
:00461F38 59                      pop ecx
:00461F39 59                      pop ecx
:00461F3A 648910                  mov dword ptr fs:[eax], edx
:00461F3D 68641F4600              push 00461F64

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00461F62(U)
|
:00461F42 8D45EC                  lea eax, dword ptr [ebp-14]
:00461F45 BA02000000              mov edx, 00000002
:00461F4A E8951AFAFF              call 004039E4
:00461F4F 8D45F4                  lea eax, dword ptr [ebp-0C]
:00461F52 BA02000000              mov edx, 00000002
:00461F57 E8881AFAFF              call 004039E4
:00461F5C C3                      ret

    让我们trace into call 004611A0

* Referenced by a CALL at Addresses:
|:00461BF5  , :00461DC9  , :00462BBF  , :004635B8 
|
:004611A0 55                      push ebp
:004611A1 8BEC                    mov ebp, esp
:004611A3 33C9                    xor ecx, ecx
:004611A5 51                      push ecx
:004611A6 51                      push ecx
:004611A7 51                      push ecx
:004611A8 51                      push ecx
:004611A9 53                      push ebx
:004611AA 56                      push esi
:004611AB 57                      push edi
:004611AC 8BDA                    mov ebx, edx
:004611AE 8BF0                    mov esi, eax
:004611B0 33C0                    xor eax, eax
:004611B2 55                      push ebp
:004611B3 688C124600              push 0046128C
:004611B8 64FF30                  push dword ptr fs:[eax]
:004611BB 648920                  mov dword ptr fs:[eax], esp
:004611BE 85F6                    test esi, esi
:004611C0 0F84A9000000            je 0046126F
:004611C6 8BC3                    mov eax, ebx
:004611C8 E86F2AFAFF              call 00403C3C  <==计算输入的code的长度
:004611CD 83F80E                  cmp eax, 0000000E  〈==code必须是14个字符
:004611D0 0F8599000000            jne 0046126F
:004611D6 8D45F8                  lea eax, dword ptr [ebp-08]
:004611D9 50                      push eax
:004611DA B904000000              mov ecx, 00000004
:004611DF BA01000000              mov edx, 00000001
:004611E4 8BC3                    mov eax, ebx
:004611E6 E8552CFAFF              call 00403E40
:004611EB 8D45F4                  lea eax, dword ptr [ebp-0C]
:004611EE 50                      push eax
:004611EF B909000000              mov ecx, 00000009
:004611F4 BA06000000              mov edx, 00000006
:004611F9 8BC3                    mov eax, ebx
:004611FB E8402CFAFF              call 00403E40
:00461200 8D45FC                  lea eax, dword ptr [ebp-04]
:00461203 8BCE                    mov ecx, esi  〈==ecx指向name
:00461205 8B55F8                  mov edx, dword ptr [ebp-08]  <==edx指向fake code的前
四位
:00461208 E87B2AFAFF              call 00403C88
:0046120D 8D55F0                  lea edx, dword ptr [ebp-10]
:00461210 8B45FC                  mov eax, dword ptr [ebp-04]
:00461213 E898010000              call 004613B0
:00461218 8B55F0                  mov edx, dword ptr [ebp-10]  <==指向real code的后九位
:0046121B 8B45F4                  mov eax, dword ptr [ebp-0C]  <==指向fake code的后九位
:0046121E E8292BFAFF              call 00403D4C    <==比较real与fake的后九位
:00461223 7546                    jne 0046126B
:00461225 33D2                    xor edx, edx
:00461227 55                      push ebp
:00461228 685D124600              push 0046125D 

      该子程序是真正计算注册码的部分,程序首先计算你输入的code是否是14个字符,然后根据
你输入的name以及code的前四位计算code的后面的八个数值。
      我必须说明,你必须trace into call 00403D4C,看懂程序如何比较code的后九位,这部分
我就不想讲了,留给读者自己去练习,不是很难,记住,要想提高自己的技术,必须能看懂一部分
汇编代码,否则真的很难深入!
      为了验证code的规律性,我反复实验了十多次,总结如下:程序取code的前四位算出
"Single User License"或者"Site License"(包括user的数目)的后八位code,但前四位数是应该
有限制的,只能包括数字,字母应是"A"--"F",看来程序要取前四位code的十六进制值,我没有继续
去研究,第五位可以是任意字符,倒数三位是固定的,是“7B2”。code形式应为xxxxxxxx-x7B2。

Part 2  做Patch


线索

    Part 1里列出的计算注册码的子程序被四个地方呼叫,分别是:00461BF5  , :00461DC9  ,
:00462BBF  , :004635B8,让我们去00461BF5处看看该子程序的返回值是什么。

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00461BA1(C)
|
:00461BBD 6A00                    push 00000000
:00461BBF 8D45F4                  lea eax, dword ptr [ebp-0C]
:00461BC2 50                      push eax

* Possible StringData Ref from Code Obj ->"RegKey"
                                  |
:00461BC3 B9301D4600              mov ecx, 00461D30

* Possible StringData Ref from Code Obj ->"General"
                                  |
:00461BC8 BA001D4600              mov edx, 00461D00
:00461BCD 8B45FC                  mov eax, dword ptr [ebp-04]
:00461BD0 E8B71CFEFF              call 0044388C
:00461BD5 8B45F4                  mov eax, dword ptr [ebp-0C]
:00461BD8 50                      push eax
:00461BD9 6A00                    push 00000000
:00461BDB 8D45F0                  lea eax, dword ptr [ebp-10]
:00461BDE 50                      push eax

* Possible StringData Ref from Code Obj ->"RegName"
                                  |
:00461BDF B9401D4600              mov ecx, 00461D40

* Possible StringData Ref from Code Obj ->"General"
                                  |
:00461BE4 BA001D4600              mov edx, 00461D00
:00461BE9 8B45FC                  mov eax, dword ptr [ebp-04]
:00461BEC E89B1CFEFF              call 0044388C
:00461BF1 8B45F0                  mov eax, dword ptr [ebp-10]
:00461BF4 5A                      pop edx
:00461BF5 E8A6F5FFFF              call 004611A0  <==计算注册码
:00461BFA 85C0                    test eax, eax
:00461BFC 7570                    jne 00461C6E  〈== if eax=1,then you have been
registered
:00461BFE A1F4CE4700              mov eax, dword ptr [0047CEF4]
:00461C03 C60001                  mov byte ptr [eax], 01
:00461C06 A1DCCF4700              mov eax, dword ptr [0047CFDC]
:00461C0B 8B00                    mov eax, dword ptr [eax]
:00461C0D 8B482C                  mov ecx, dword ptr [eax+2C]
:00461C10 B201                    mov dl, 01
:00461C12 A134264600              mov eax, dword ptr [00462634]
:00461C17 E8CCFEFBFF              call 00421AE8
:00461C1C 8945F8                  mov dword ptr [ebp-08], eax
:00461C1F 33C0                    xor eax, eax
:00461C21 55                      push ebp
:00461C22 685C1C4600              push 00461C5C
:00461C27 64FF30                  push dword ptr fs:[eax]
:00461C2A 648920                  mov dword ptr fs:[eax], esp
:00461C2D 8B45F8                  mov eax, dword ptr [ebp-08]
:00461C30 C780480200000B000000    mov dword ptr [ebx+00000248], 0000000B
:00461C3A 8B45F8                  mov eax, dword ptr [ebp-08]
:00461C3D 8B80DC010000            mov eax, dword ptr [eax+000001DC]
:00461C43 B201                    mov dl, 01
:00461C45 E866BBFDFF              call 0043D7B0
:00461C4A 8B45F8                  mov eax, dword ptr [ebp-08]
:00461C4D E8AE2EFCFF              call 00424B00  <==呼叫nagscreen
:00461C52 33C0                    xor eax, eax
:00461C54 5A                      pop edx
:00461C55 59                      pop ecx
:00461C56 59                      pop ecx
:00461C57 648910                  mov dword ptr fs:[eax], edx
:00461C5A EB12                    jmp 00461C6E
:00461C5C E98315FAFF              jmp 004031E4
:00461C61 8B45F8                  mov eax, dword ptr [ebp-08]
:00461C64 E8BF11FAFF              call 00402E28
:00461C69 E81A18FAFF              call 00403488

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00461BFC(C), :00461C5A(U)
|
:00461C6E 33C0                    xor eax, eax
:00461C70 5A                      pop edx
:00461C71 59                      pop ecx
   
    该段代码从文件SC97.cfg中读取RegName、RegKey,并进行注册码的验证,
    这样我们可以在004611A0处改代码为 (1)mov eax, 00000001 (2)ret,然后删掉文件SC97.cfg
,重新启动程序,nag screen不见了,但about中"registered to"还是"unregistered",没关系,用
NotePad打开文件SC97.cfg,按照我软件的保护机制中讲的SC97.cfg文件格式添上RegName、RegKey
这两行,内容随意输入你想要的,保存,再重新启动程序,ABOUT会告诉你"registered to xxxx",
Kool!     

                ----------=======The Patch========----------

      在文件sc97.exe的offset:000605A0h处,修改558BEC33C951为B801000000C3。