-
-
[原创]Second Copy 2000注册码算法分析及注册机
-
发表于: 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日上午
软件介绍:这是一款美国人写的程序,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期预科班、正式班开始火爆招生报名啦!!!
赞赏
他的文章
赞赏
雪币:
留言: