首页
社区
课程
招聘
[原创]Second Copy 2000注册码算法分析及注册机
发表于: 2006-1-16 21:48 4313

[原创]Second Copy 2000注册码算法分析及注册机

qduwg 活跃值
35
2006-1-16 21:48
4313
题目:Second Copy 2000注册码算法分析及注册机
软件介绍:这是一款美国人写的程序,Second Copy 2000允许你在不同地方保存重要文件的备份, Second Copy 2000能够在没有人为干预的情况下,在指

定的时间间隔内拷贝你的文件。该软件采用图形界面表示信息,使用该软件十分简便,通过给欲拷贝的文件建立一个描述文件,可以拷贝到其他目录,驱

动器和网络上的其他计算机。描述文件定义了源位置,目的位置及拷贝频率。该软件注册费用USD$29.95.未注册软件30天试用期限,而且每次启动出现NAG


运行平台: Windows 9x/Me/NT4/2000.
破解难度:易
破解工具:SOFTICE,OD,PEID

引子:今天又在光盘上找到这个软件,为了练手的目的,所以随便安装了一下,看看是否可以破解掉,结果情况不错,跟踪了大概1个小时,就搞定了这个

软件的注册码了。所以赶紧写出教程,让您也分享我的快乐吧。拿出PEID查看是否加壳,显示没有,是DELPHI写的。这就好办多了。现在软件都一般带壳

,比较讨厌的。运行这个软件,首先“砰”弹出一个NAG,上面有按钮,点击注册按钮,打开注册窗口,输入你的用户名和注册码。比如wanggang,

7878787878,过会你会看到这个注册码不是这个形式的。调出SOFTICE,首先下断点bpx getwindowtexta,结果不好用,没有拦住,虽然通过OD我看到它用

了这个函数,但是不知为什么拦不住。我只好改bpx hmemcpy了,这是万能断点。绝对好用。按6次F12来到主程序空间,然后换F10,我们来到下面代码处

了:
1. 整体程序框架结构
004A9AA1  |. E8 0E04FAFF    CALL SECCOPY.00449EB4
004A9AA6  |. 8B45 F4        MOV EAX,DWORD PTR SS:[EBP-C]    //这是假注册码地址送EAX。
004A9AA9  |. 50             PUSH EAX  
004A9AAA  |. 8D55 F0        LEA EDX,DWORD PTR SS:[EBP-10]
004A9AAD  |. 8B83 D8020000  MOV EAX,DWORD PTR DS:[EBX+2D8]
004A9AB3  |. E8 FC03FAFF    CALL SECCOPY.00449EB4
004A9AB8  |. 8B45 F0        MOV EAX,DWORD PTR SS:[EBP-10]
004A9ABB  |. 5A             POP EDX
004A9ABC  |. E8 B7FBFFFF    CALL SECCOPY.004A9678        //看这个结构绝对经典,后面带TEST。F8跟入。
004A9AC1  |. 84C0           TEST AL,AL
004A9AC3  |. 74 0C          JE SHORT SECCOPY.004A9AD1
004A9AC5  |. C783 34020000 >MOV DWORD PTR DS:[EBX+234],1
004A9ACF  |. EB 15          JMP SHORT SECCOPY.004A9AE6
004A9AD1  |> 8D55 EC        LEA EDX,DWORD PTR SS:[EBP-14]
004A9AD4  |. A1 78ED4C00    MOV EAX,DWORD PTR DS:[4CED78]
004A9AD9  |. E8 F6C0F5FF    CALL SECCOPY.00405BD4
004A9ADE  |. 8B45 EC        MOV EAX,DWORD PTR SS:[EBP-14]
004A9AE1  |. E8 9A93FBFF    CALL SECCOPY.00462E80
=======================================================
下面来看004A9ABC处的 CALL SECCOPY.004A9678,这是这个函数的框架 :
*省略开头20多行
004A96AE  |. 8B55 F8        MOV EDX,DWORD PTR SS:[EBP-8]
004A96B1  |. 8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]
004A96B4  |. E8 9BDEFFFF    CALL SECCOPY.004A7554    //这个函数是关键,我们记为(1),代码在下面。
004A96B9  |. 8BF0           MOV ESI,EAX              //如果函数成功返回,则下面代码是写入注册表内数据。
004A96BB  |. 85F6           TEST ESI,ESI
004A96BD  |. 0F8E 9F000000  JLE SECCOPY.004A9762           //此处没有跳。
004A96C3  |. 8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]   //用户名地址送EAX
004A96C6  |. 50             PUSH EAX
004A96C7  |. A1 F4F44C00    MOV EAX,DWORD PTR DS:[4CF4F4]  //下面是准备注册信息。
004A96CC  |. 8B00           MOV EAX,DWORD PTR DS:[EAX]
004A96CE  |. B9 94974A00    MOV ECX,SECCOPY.004A9794
004A96D3  |. BA A4974A00    MOV EDX,SECCOPY.004A97A4
004A96D8  |. 8B18           MOV EBX,DWORD PTR DS:[EAX]
004A96DA  |. FF53 04        CALL DWORD PTR DS:[EBX+4]       //此函数把数据写入注册表。
004A96DD  |. 8B45 F8        MOV EAX,DWORD PTR SS:[EBP-8]    //假注册码地址送EAX
004A96E0  |. 50             PUSH EAX
004A96E1  |. A1 F4F44C00    MOV EAX,DWORD PTR DS:[4CF4F4]
004A96E6  |. 8B00           MOV EAX,DWORD PTR DS:[EAX]
004A96E8  |. BA A4974A00    MOV EDX,SECCOPY.004A97A4
004A96ED  |. B9 B4974A00    MOV ECX,SECCOPY.004A97B4
004A96F2  |. 8B18           MOV EBX,DWORD PTR DS:[EAX]
004A96F4  |. FF53 04        CALL DWORD PTR DS:[EBX+4]      //此函数把数据写入注册表。
004A96F7  |. 68 C4974A00    PUSH SECCOPY.004A97C4
004A96FC  |. A1 F4F44C00    MOV EAX,DWORD PTR DS:[4CF4F4]
004A9701  |. 8B00           MOV EAX,DWORD PTR DS:[EAX]
004A9703  |. BA A4974A00    MOV EDX,SECCOPY.004A97A4
004A9708  |. B9 D8974A00    MOV ECX,SECCOPY.004A97D8
004A970D  |. 8B18           MOV EBX,DWORD PTR DS:[EAX]
004A970F  |. FF53 04        CALL DWORD PTR DS:[EBX+4]  
004A9712  |. 81FE 00FA0000  CMP ESI,0FA00
004A9718  |. 75 17          JNZ SHORT SECCOPY.004A9731      //此处跳走。
*略去几行
004A9731  |> 8D55 F0        LEA EDX,DWORD PTR SS:[EBP-10]
004A9734  |. A1 B4EE4C00    MOV EAX,DWORD PTR DS:[4CEEB4]
004A9739  |. E8 96C4F5FF    CALL SECCOPY.00405BD4
004A973E  |. 8B45 F0        MOV EAX,DWORD PTR SS:[EBP-10]   //这里d eax可以看到成功信息。
004A9741  |. 8975 E8        MOV DWORD PTR SS:[EBP-18],ESI
004A9744  |. C645 EC 00     MOV BYTE PTR SS:[EBP-14],0
004A9748  |. 8D55 E8        LEA EDX,DWORD PTR SS:[EBP-18]
004A974B  |. 33C9           XOR ECX,ECX
004A974D  |. E8 C298FBFF    CALL SECCOPY.00463014           //此处显示成功对话框
004A9752  |> A1 ECEC4C00    MOV EAX,DWORD PTR DS:[4CECEC]
004A9757  |. 8B00           MOV EAX,DWORD PTR DS:[EAX]
004A9759  |. 33D2           XOR EDX,EDX
004A975B  |. E8 30E5FFFF    CALL SECCOPY.004A7C90
=======================================================
2. 详细分析上述(1)函数。代码如下:
004A7591   . 8B45 F8        MOV EAX,DWORD PTR SS:[EBP-8]
004A7594   . E8 7FC9F5FF    CALL SECCOPY.00403F18
004A7599   . 83F8 0E        CMP EAX,0E                     //此处比较注册码长度是否为14位。
004A759C   . 0F85 CA000000  JNZ SECCOPY.004A766C           //如果不是则OVER。
004A75A2   . 8B45 F8        MOV EAX,DWORD PTR SS:[EBP-8]  //取假注册码地址送EAX。
004A75A5   . E8 6EC9F5FF    CALL SECCOPY.00403F18
004A75AA   . 8BF0           MOV ESI,EAX
004A75AC   . 85F6           TEST ESI,ESI
004A75AE   . 7E 20          JLE SHORT SECCOPY.004A75D0
004A75B0   . BB 01000000    MOV EBX,1
004A75B5   > 8B45 F8        MOV EAX,DWORD PTR SS:[EBP-8]    //取出每一位注册码
004A75B8   . 807C18 FF 58   CMP BYTE PTR DS:[EAX+EBX-1],58  //与58比较
004A75BD   . 75 0D          JNZ SHORT SECCOPY.004A75CC     //不相同则继续取下一位比较。
004A75BF   . 8D45 F8        LEA EAX,DWORD PTR SS:[EBP-8]
004A75C2   . E8 21CBF5FF    CALL SECCOPY.004040E8            
004A75C7   . C64418 FF 30   MOV BYTE PTR DS:[EAX+EBX-1],30
004A75CC   > 43             INC EBX
004A75CD   . 4E             DEC ESI
004A75CE   .^75 E5          JNZ SHORT SECCOPY.004A75B5     //如果未完,继续循环上去。
004A75D0   > 8D45 F0        LEA EAX,DWORD PTR SS:[EBP-10]
004A75D3   . 50             PUSH EAX
004A75D4   . B9 04000000    MOV ECX,4
004A75D9   . BA 01000000    MOV EDX,1
004A75DE   . 8B45 F8        MOV EAX,DWORD PTR SS:[EBP-8]   //注册码地址送EAX。
004A75E1   . E8 3ACBF5FF    CALL SECCOPY.00404120
004A75E6   . 8D45 EC        LEA EAX,DWORD PTR SS:[EBP-14]
004A75E9   . 50             PUSH EAX
004A75EA   . B9 09000000    MOV ECX,9
004A75EF   . BA 06000000    MOV EDX,6
004A75F4   . 8B45 F8        MOV EAX,DWORD PTR SS:[EBP-8]
004A75F7   . E8 24CBF5FF    CALL SECCOPY.00404120          //复制注册码到另一个地址。
004A75FC   . 8D45 F4        LEA EAX,DWORD PTR SS:[EBP-C]
004A75FF   . 8B4D FC        MOV ECX,DWORD PTR SS:[EBP-4]
004A7602   . 8B55 F0        MOV EDX,DWORD PTR SS:[EBP-10]
004A7605   . E8 5AC9F5FF    CALL SECCOPY.00403F64
004A760A   . 8D55 E8        LEA EDX,DWORD PTR SS:[EBP-18]
004A760D   . 8B45 F4        MOV EAX,DWORD PTR SS:[EBP-C]
004A7610   . E8 93000000    CALL SECCOPY.004A76A8          //这个CALL重要,我们记为(2),下面代码分析。
004A7615   . 8B55 E8        MOV EDX,DWORD PTR SS:[EBP-18]  //计算出来的真注册码地址
004A7618   . 8B45 EC        MOV EAX,DWORD PTR SS:[EBP-14]  //除了前4位,剩余部分假注册码地址
004A761B   . E8 08CAF5FF    CALL SECCOPY.00404028          //后半部分真假注册码进行比较。我们记为(3)。
004A7620   . 75 46          JNZ SHORT SECCOPY.004A7668     //这个JNZ不跳。
004A7622   . 33D2           XOR EDX,EDX
004A7624   . 55             PUSH EBP
=======================================================
3.下面分析(2)处函数功能,下面代码分析。
004A76D4   . 64:8920        MOV DWORD PTR FS:[EAX],ESP
004A76D7   . 8B1D 24E94C00  MOV EBX,DWORD PTR DS:[4CE924]   //注意这个EBX值,EBX内是一个常量14DAF。后面计算用。
004A76DD   . 8D55 E4        LEA EDX,DWORD PTR SS:[EBP-1C]
004A76E0   . 8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]
004A76E3   . E8 AC12F6FF    CALL SECCOPY.00408994           //此函数把用户名变成"大写"字母,并把注册码前4位串接在前面。
004A76E8   . 8B55 E4        MOV EDX,DWORD PTR SS:[EBP-1C]
004A76EB   . 8D45 FC        LEA EAX,DWORD PTR SS:[EBP-4]
004A76EE   . E8 3DC6F5FF    CALL SECCOPY.00403D30
004A76F3   . 8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]
004A76F6   . E8 1DC8F5FF    CALL SECCOPY.00403F18            //取上面这个新构造串长度。
004A76FB   . 85C0           TEST EAX,EAX
*略去几行
004A7709   > 33D2           XOR EDX,EDX
004A770B   . 55             PUSH EBP
004A770C   . 68 50774A00    PUSH SECCOPY.004A7750
004A7711   . 64:FF32        PUSH DWORD PTR FS:[EDX]
004A7714   . 64:8922        MOV DWORD PTR FS:[EDX],ESP
004A7717   . 8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]
004A771A   . 8B55 F4        MOV EDX,DWORD PTR SS:[EBP-C]
004A771D   . 8A4410 FF      MOV AL,BYTE PTR DS:[EAX+EDX-1]
004A7721   . 3C 20          CMP AL,20                        //每一位新串字符与20H(空格)比较。
004A7723   . 75 0C          JNZ SHORT SECCOPY.004A7731       //不是空格则OK。
004A7725   . 64:8F05 000000>POP DWORD PTR FS:[0]
004A772C   . 83C4 08        ADD ESP,8
004A772F   . EB 2E          JMP SHORT SECCOPY.004A775F
004A7731   > 8B55 FC        MOV EDX,DWORD PTR SS:[EBP-4]  
004A7734   . 8B4D F4        MOV ECX,DWORD PTR SS:[EBP-C]
004A7737   . 25 FF000000    AND EAX,0FF                     //取EAX低字节值,对应新串的各个字节。
004A773C   . F7EB           IMUL EBX                        //EAX=EAX*EBX,EBX为上次计算结果。
004A773E   . 0305 24E94C00  ADD EAX,DWORD PTR DS:[4CE924]   //EAX=EAX+14DAF.
004A7744   . 8BD8           MOV EBX,EAX                     //保存计算结果到EBX。如果超过EBX的范围,超出部分舍弃。
004A7746   . 33C0           XOR EAX,EAX     
004A7748   . 5A             POP EDX
004A7749   . 59             POP ECX
004A774A   . 59             POP ECX
004A774B   . 64:8910        MOV DWORD PTR FS:[EAX],EDX
004A774E   . EB 0F          JMP SHORT SECCOPY.004A775F     
004A7750   .^E9 87BCF5FF    JMP SECCOPY.004033DC
004A7755   . BB E7030000    MOV EBX,3E7
004A775A   . E8 D9BFF5FF    CALL SECCOPY.00403738
004A775F   > FF45 F4        INC DWORD PTR SS:[EBP-C]
004A7762   . FF4D E8        DEC DWORD PTR SS:[EBP-18]
004A7765   .^75 A2          JNZ SHORT SECCOPY.004A7709     //新串没有处理完则继续循环上去。
004A7767   > 8D45 F0        LEA EAX,DWORD PTR SS:[EBP-10]
004A776A   . 50             PUSH EAX
004A776B   . 8D4D E0        LEA ECX,DWORD PTR SS:[EBP-20]
004A776E   . BA 08000000    MOV EDX,8
004A7773   . 8BC3           MOV EAX,EBX
004A7775   . E8 AA17F6FF    CALL SECCOPY.00408F24          //保存计算结果。
004A777A   . 8B45 E0        MOV EAX,DWORD PTR SS:[EBP-20]  //结果地址送EAX。
*略去多行
004A779A   . E8 8517F6FF    CALL SECCOPY.00408F24          //复制结果到另外地址。
004A779F   . 8B45 DC        MOV EAX,DWORD PTR SS:[EBP-24]  //结果地址送EAX。
*略去多行
004A77C4   . E8 0FC8F5FF    CALL SECCOPY.00403FD8          // 这个函数重要,记为(4)。下面分析。
004A77C9   . 33C0           XOR EAX,EAX
004A77CB   . 5A             POP EDX
004A77CC   . 59             POP ECX
004A77CD   . 59             POP ECX
004A77CE   . 64:8910        MOV DWORD PTR FS:[EAX],EDX
004A77D1   . 68 00784A00    PUSH SECCOPY.004A7800
004A77D6   > 8D45 DC        LEA EAX,DWORD PTR SS:[EBP-24]
004A77D9   . BA 03000000    MOV EDX,3
004A77DE   . E8 D9C4F5FF    CALL SECCOPY.00403CBC
004A77E3   . 8D45 EC        LEA EAX,DWORD PTR SS:[EBP-14]  //计算结果后四位地址送EAX。
004A77E6   . BA 02000000    MOV EDX,2
004A77EB   . E8 CCC4F5FF    CALL SECCOPY.00403CBC
004A77F0   . 8D45 FC        LEA EAX,DWORD PTR SS:[EBP-4]
004A77F3   . E8 A0C4F5FF    CALL SECCOPY.00403C98
004A77F8   . C3             RETN       //此处返回到4A7615后面。
=======================================================
4.下面分析(4)处函数功能,代码如下:
00403FEE   . E8 69FDFFFF    CALL SECCOPY.00403D5C
00403FF3   . 50             PUSH EAX
00403FF4   . 89C6           MOV ESI,EAX
00403FF6   > 8B449C 14      MOV EAX,DWORD PTR SS:[ESP+EBX*4+14]
00403FFA   . 89F2           MOV EDX,ESI
00403FFC   . 85C0           TEST EAX,EAX
00403FFE   . 74 0A          JE SHORT SECCOPY.0040400A
00404000   . 8B48 FC        MOV ECX,DWORD PTR DS:[EAX-4]
00404003   . 01CE           ADD ESI,ECX
00404005   . E8 BEE8FFFF    CALL SECCOPY.004028C8            //此函数复制得到的注册码结果前4位,后面加一减号"-"。
0040400A   > 4B             DEC EBX
0040400B   .^75 E9          JNZ SHORT SECCOPY.00403FF6       //取下一部分注册码。
*略去多行
0040401F   . 8D2494         LEA ESP,DWORD PTR SS:[ESP+EDX*4]
00404022   . FFE0           JMP EAX                          //此处跳走,经过一番折腾又返回到前面的004A77C9 处。
=======================================================
5.下面分析004A761B 处函数(3)功能, CALL SECCOPY.00404028 代码如下:
00404051  |> 8B0E           /MOV ECX,DWORD PTR DS:[ESI]      //假码前4位送ECX。
00404053  |. 8B1F           |MOV EBX,DWORD PTR DS:[EDI]      //真码前4位送EBX。
00404055  |. 39D9           |CMP ECX,EBX     //比较。
00404057  |. 75 58          |JNZ SHORT SECCOPY.004040B1      //不相等则OVER。
00404059  |. 4A             |DEC EDX
0040405A  |. 74 15          |JE SHORT SECCOPY.00404071   
0040405C  |. 8B4E 04        |MOV ECX,DWORD PTR DS:[ESI+4]
0040405F  |. 8B5F 04        |MOV EBX,DWORD PTR DS:[EDI+4]
00404062  |. 39D9           |CMP ECX,EBX
00404064  |. 75 4B          |JNZ SHORT SECCOPY.004040B1
00404066  |. 83C6 08        |ADD ESI,8
00404069  |. 83C7 08        |ADD EDI,8
0040406C  |. 4A             |DEC EDX
0040406D  |.^75 E2          \JNZ SHORT SECCOPY.00404051     //没有比较完,则继续循环。
0040406F  |. EB 06          JMP SHORT SECCOPY.00404077
00404071  |> 83C6 04        ADD ESI,4
00404074  |. 83C7 04        ADD EDI,4
00404077  |> 5A             POP EDX
00404078  |. 83E2 03        AND EDX,3
0040407B  |. 74 22          JE SHORT SECCOPY.0040409F
0040407D  |. 8B0E           MOV ECX,DWORD PTR DS:[ESI]
0040407F  |. 8B1F           MOV EBX,DWORD PTR DS:[EDI]
00404081  |. 38D9           CMP CL,BL                       //比较剩余的字节
00404083  |. 75 41          JNZ SHORT SECCOPY.004040C6      //不等也OVER。
00404085  |. 4A             DEC EDX
00404086  |. 74 17          JE SHORT SECCOPY.0040409F
=======================================================
总结:

经过1个小时努力,终于写完这篇破文。注册码的算法思路是这样的:把注册码前4位放在用户名前面,然后根据迭代公式计算其结果。超过寄存器的部分

舍弃。形成8个字节的后半部分注册码,注册码每4位之间用短杠隔开。这样包括2个短杠,长度就是14。

结果:
Username: wanggang
Registercode: 7878-FB53-3348

随便写了一个注册机,在TC下通过:

#include "stdio.h"
#include "string.h"
main()
{
char name[20],n[20];
char code1[5],code2[5],code3[5],code[30];
long ebx=0x14dafL,eax,f,m,b;
int i,j,temp,t1,t2;
long c=0x14dafL;
printf("This keygen is for Second Copy [Made by Mr.qduwg. 2006/1/14]\n");
printf("*******please input 4 digits*******\n");
scanf("%s",code1);
printf("====please input your name ====\n");
scanf("%s",name);
j=strlen(name);
strcpy(n,name);
for(i=0;i<j;i++)
{if(name[i]>='a'&&name[i]<='z')
    name[i]-=0x20;}
strcpy(code,code1);
strcat(code,name);
j=strlen(code);
for(i=0;i<j;i++)
{
eax=code[i];
ebx=eax*ebx+c;
}
t1=ebx&0x0000ffff;
t2=ebx>>16;
for(j=3;j>=0;j--)
{temp=t1&0x000f;
if((temp>=0xa )&& (temp<=0xf))
   {temp=temp+0X37;
    code3[j]=temp;}
else
    code3[j]=temp+0x30;
t1>>=4;
temp=t2&0x000f;
if((temp>=0xa)&&(temp<=0xf))
   {temp+=0X37;
    code2[j]=temp;}
else
    code2[j]=temp+0x30;
t2>>=4;
}
code3[4]=code2[4]=0;
printf("your username is %s\n",name);
printf("The Register Code is :\n");
printf("%s-%s-%s\n",code1,code2,code3);

printf("thank you for using this keygen!:)");
}

qduwg

qduwg@163.com

完成时间:2006年1月15日上午

[培训]科锐软件逆向54期预科班、正式班开始火爆招生报名啦!!!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回