前几天收到一封垃圾邮件叫什么公文写作助手,但是需要注册才能使用,看着挺来气的,
就想把它做了,因为自己本就是菜鸟一个,现学现卖到看雪这里学习了一下,用了俩天
时间终于搞定了。不敢独享,从这里学的再返回到这里,也算是对给和我一样的菜鸟一
些鼓励吧。
【软件名称】:公文写作助手 V1.0
【下载页面】:http://hn-http.skycn.net/down/gongwen.exe
【软件大小】:1647 KB
【软件语言】:简体中文
【应用平台】:WIN9X/WINNT/WIN2K/WINXP
【软件简介】:
办公司,当文秘,一刻也离不开写文章。可是许多人,却因为写不出文章而发愁。其实,
写文章也有很多诀窍,其中最关键的,就是要先学会模仿,而后才能熟中生巧,写出一
手漂亮文章来。 本电子书积累类作者多年写文章的经验,既提供了各种行政、经济、法律、
礼仪、事物、新闻类文章的写作要点,又提供了各种公文的例文和范本。即使你没有任何写
作经验,对着范本来个照本宣科,马上就会写出一手漂亮文章来。特别提示:本书提供了数
百篇例文,对于初学者,可以利用复制、粘帖的办法,快速写出称心的文章.正所谓:有此软
件做助手,从此写作不再愁。
【软件限制】:只有注册后才能使用。
【作者声明】:本人发表这篇文章只是为了学习!!!请不用于商业用途或是将本文方法制作的
注册机任意传播,读者看了文章后所做的事情与我无关,我也不会负责,请读者看了文章后三思
而后行!最后希望大家在经济基础好的时候,支持共享软件!
【破解工具】fileinfo2.45a UnAspack DeDe3.20.04 vc6.0(没办法,水平太菜,softice不太会用)
【破解平台】W2K ADV SERVER
【过 程】:
先说一下此软件的注册方式,它是自己先根据机器信息生成一个每台机器独立的10位代码,然后
经过对其进行运算后生成所谓的解锁码。经过跟踪找出解锁码跟容易,我们的目标就是找出它的
计算解锁码的算法。
先用fi查看是用Aspack加的壳,于是用UnAspack脱掉后再看,是delphi写的。于是用DeDe处理。根
据处理的结果可以看出在注册界面点确定后会进入如下函数调用:
0047876C call dword ptr [edx+0F0h]
所以用VC打开程序,F10进入调试模式,断点下在0047876C。按F5运行程序后,进入注册界面随便输入
一个解锁码,点确定后程序中断,按F11跟进:
-------------------------------------------------------------------------------------
第一步:
00478698 push
ebp
00478699 mov ebp,esp
0047869B push 0
0047869D push 0
0047869F push ebx
004786A0 mov ebx,eax
004786A2 xor eax,eax
004786A4 push ebp
004786A5 push 4786FAh
004786AA push dword ptr fs:[eax]
004786AD mov dword ptr fs:[eax],esp
004786B0 lea edx,[ebp-4]
004786B3 mov eax,ebx
004786B5 mov ecx,dword ptr [eax]
004786B7 call dword ptr [ecx+0E0h]
004786BD mov eax,dword ptr [ebp-4]
004786C0 push eax
<-这里是输入的解锁码压栈
004786C1 lea edx,[ebp-8]
004786C4 mov eax,ebx
004786C6 mov ecx,dword ptr [eax]
004786C8 call dword ptr [ecx+0E4h]
004786CE mov eax,dword ptr [ebp-8] <-这里eax的值是机器生成的10位代码
004786D1 mov ecx,dword ptr [ebx+2F8h]
004786D7 pop edx
004786D8 call 00477DFC <-eax是输入的解锁码,edx是机器算出的10位代码,进入函数
004786DD mov ebx,eax
004786DF xor eax,eax
004786E1 pop edx
004786E2 pop ecx
004786E3 pop ecx
004786E4 mov dword ptr fs:[eax],edx
004786E7 push 478701h
004786EC lea eax,[ebp-8]
004786EF mov edx,2
004786F4 call 00403BC8
004786F9 ret
------------------------------------------------------------------------
第二步: 接上一步的 004786D8 call 00477DFC 调用
00477DFC push
ebp
00477DFD mov ebp,esp
00477DFF add esp,0FFFFFEFCh
00477E05 push ebx
00477E06 push esi
00477E07 push edi
00477E08 xor ebx,ebx
00477E0A mov dword ptr [ebp-4],ebx
00477E0D mov edi,ecx
00477E0F mov esi,edx <-输入的解锁码
00477E11 mov ebx,eax <-机器算出的10位代码
00477E13 xor eax,eax
00477E15 push ebp
00477E16 push 477E63h
00477E1B push dword ptr fs:[eax]
00477E1E mov dword ptr fs:[eax],esp
00477E21 lea ecx,[ebp-104h]
00477E27 mov edx,edi
00477E29 mov eax,ebx
00477E2B call 00477C94 <-eax:机器算出的10位代码,esi:输入的解锁码,进入函数
00477E30 lea edx,[ebp-104h]
00477E36 lea eax,[ebp-4]
00477E39 call 00403DC8
00477E3E mov eax,dword ptr [ebp-4]
00477E41 mov edx,esi
00477E43 call 00403F34
00477E48 sete al
00477E4B mov ebx,eax
00477E4D xor eax,eax
00477E4F pop edx
00477E50 pop ecx
00477E51 pop ecx
00477E52 mov dword ptr fs:[eax],edx
00477E55 push 477E6Ah
00477E5A lea eax,[ebp-4]
00477E5D call 00403BA4
00477E62 ret
-------------------------------------------------------------------------------
第三步:接上一步的00477E2B call 00477C94调用
00477C94 push
ebp
00477C95 mov ebp,esp
00477C97 add esp,0E0h
00477C9A push ebx
00477C9B push esi
00477C9C push edi
00477C9D xor ebx,ebx
00477C9F mov dword ptr [ebp-20h],ebx
00477CA2 mov dword ptr [ebp-1Ch],ebx
00477CA5 mov dword ptr [ebp-18h],ebx
00477CA8 mov edi,ecx
00477CAA mov dword ptr [ebp-8],edx
00477CAD mov dword ptr [ebp-4],eax
00477CB0 mov eax,dword ptr [ebp-4]
00477CB3 call 00403FD8
00477CB8 mov eax,dword ptr [ebp-8]
00477CBB call 00403FD8
00477CC0 xor eax,eax
00477CC2 push ebp
00477CC3 push 477DEDh
00477CC8 push dword ptr fs:[eax]
00477CCB mov dword ptr fs:[eax],esp
00477CCE cmp dword ptr [ebp-4],0
00477CD2 je 00477D43
00477CD4 mov ebx,1
00477CD9 lea esi,[ebp-11h]
00477CDC mov eax,dword ptr [ebp-4]
00477CDF call 00403E24
00477CE4 push eax
00477CE5 mov eax,ebx
00477CE7 dec eax
00477CE8 pop edx
00477CE9 mov ecx,edx
00477CEB cdq
00477CEC idiv eax,ecx
00477CEE mov eax,dword ptr [ebp-4]
00477CF1 mov al,byte ptr [eax+edx]<-分别取出10位机器码放入al中
00477CF4 push eax
00477CF5 mov eax,dword ptr [ebp-4]
00477CF8 call 00403E24
00477CFD pop edx
00477CFE xor dl,al
<-先与al进行xor运算,al值为0x0a
00477D00 xor dl,bl
<-再与bl进行xor运算,bl为从1开始每次递增1
00477D02 mov byte ptr [esi],dl <-运算结果放进ESI
00477D04 inc ebx
00477D05 inc esi
00477D06 cmp ebx,0Ah
<-循环记数
00477D09 jne 00477CDC
00477D0B mov eax,dword ptr [ebp-4]
00477D0E call 00403E24
00477D13 mov esi,eax
00477D15 test esi,esi
00477D17 jle 00477D43
00477D19 mov ebx,1
00477D1E mov eax,dword ptr [ebp-4]
00477D21 call 00403E24
00477D26 sub eax,ebx
00477D28 mov edx,dword ptr [ebp-4]
00477D2B mov cl,byte ptr [edx+eax] <-每次一个反序取出机器码
00477D2E mov eax,ebx
00477D30 dec eax
00477D31 push ecx
00477D32 mov ecx,9
00477D37 cdq
00477D38 idiv eax,ecx
00477D3A pop ecx
00477D3B xor byte ptr [ebp+edx-11h],cl
<-取出的内容与上面的结果进行xor操作
<-循环共9次,所以最后一位要和第一
<-次的计算结果进行运算
00477D3F inc ebx
00477D40 dec esi
00477D41 jne 00477D1E
00477D43 cmp dword ptr [ebp-8],0
00477D47 je 00477D82
00477D49 mov ebx,1
00477D4E lea esi,[ebp-11h]
00477D51 mov eax,dword ptr [ebp-8]
00477D54 call 00403E24
00477D59 push eax
00477D5A mov eax,ebx
00477D5C dec eax
00477D5D pop edx
00477D5E mov ecx,edx
00477D60 cdq
00477D61 idiv eax,ecx
00477D63 mov eax,dword ptr [ebp-8]
00477D66 mov al,byte ptr [eax+edx]
00477D69 xor al,byte ptr [esi]
00477D6B push eax
00477D6C mov eax,dword ptr [ebp-8]
00477D6F call 00403E24
00477D74 pop edx
00477D75 xor dl,al
00477D77 xor dl,bl
00477D79 mov byte ptr [esi],dl
00477D7B inc ebx
00477D7C inc esi
00477D7D cmp ebx,0Ah
00477D80 jne 00477D51
00477D82 lea eax,[ebp-18h]
00477D85 call 00403BA4
00477D8A mov ebx,9
00477D8F lea esi,[ebp-11h]
00477D92 lea eax,[ebp-1Ch]
00477D95 mov dl,byte ptr [esi]
00477D97 call 00403D4C
00477D9C mov edx,dword ptr [ebp-1Ch]
00477D9F lea eax,[ebp-18h]
00477DA2 call 00403E2C
00477DA7 inc esi
00477DA8 dec ebx
00477DA9 jne 00477D92
00477DAB lea edx,[ebp-20h]
00477DAE mov eax,dword ptr [ebp-18h]
00477DB1 call 00477B50
<--10位代码经过运算后进入调用
00477DB6 mov edx,dword ptr [ebp-20h]
00477DB9 mov eax,edi
00477DBB mov ecx,0FFh
00477DC0 call 00403E00
00477DC5 xor eax,eax
00477DC7 pop edx
00477DC8 pop ecx
00477DC9 pop ecx
00477DCA mov dword ptr fs:[eax],edx
00477DCD push 477DF4h
00477DD2 lea eax,[ebp-20h]
00477DD5 mov edx,3
00477DDA call 00403BC8
00477DDF lea eax,[ebp-8]
00477DE2 mov edx,2
00477DE7 call 00403BC8
00477DEC ret
这里对此过程进入调用之前的分析说明,它是这样处理的,假设10位解锁码为c1-c10;
运算如下:
--------------------------------------------------------------
c1 c2 c3 c4 c5
c6 c7 c8 c9 c10
xor 0x0a 0x0a 0x0a 0x0a 0x0a 0x0a 0x0a
0x0a 0x0a 0x0a 分别与0x0a进行xor运算
---------------------------------------------------------------
cc1 cc2 cc3 cc4 cc5 cc6
cc7 cc8 cc9 得到的结果
xor 1 2 3 4
5 6 7 8 9
然后前9个分别从1到9进行xor运算
---------------------------------------------------------------
ccc1 ccc2 ccc3 ccc4 ccc5 ccc6
ccc7 ccc8 ccc9 得到的结果
xor c10 c9 c8 c7 c6
c5 c4 c3 c2
10位解锁码反序与前面结果xor运算
---------------------------------------------------------------
cccc1
最后一位也就是代码的第一个与
xor c1
执行结果的第一项继续运算
---------------------------------------------------------------
b1 b2 b3 b4 b5
b6 b7 b8 b9
这里为最终生成的结果
---------------------------------------------------------------
上面就是对本段进入注名的函数调用之前的分析,其中cc[n],ccc[n],cccc[n]为中间结果,b[n]为最终结果
-------------------------------------------------------------------------------------------
第四步: 接00477DB1 call 00477B50调用
00477B50 push
ebp
00477B51 mov ebp,esp
00477B53 add esp,0F0h
00477B56 push ebx
00477B57 push esi
00477B58 push edi
00477B59 xor ecx,ecx
00477B5B mov dword ptr [ebp-10h],ecx
00477B5E mov edi,edx
00477B60 mov dword ptr [ebp-4],eax
00477B63 mov eax,dword ptr [ebp-4]
00477B66 call 00403FD8
00477B6B xor eax,eax
00477B6D push ebp
00477B6E push 477C84h
00477B73 push dword ptr fs:[eax]
00477B76 mov dword ptr fs:[eax],esp
00477B79 mov eax,edi
00477B7B call 00403BA4
00477B80 jmp 00477C5C
00477B85 mov eax,dword ptr [ebp-4]
00477B88 call 00403E24
00477B8D mov ecx,eax
00477B8F mov eax,ecx
00477B91 mov ebx,3
00477B96 cdq
00477B97 idiv eax,ebx
00477B99 test eax,eax
00477B9B jle 00477BA4
00477B9D mov ebx,3
00477BA2 jmp 00477BA6
00477BA4 mov ebx,ecx
00477BA6 lea eax,[ebp-7]
00477BA9 xor ecx,ecx
00477BAB mov edx,3
00477BB0 call 00402B68
00477BB5 lea eax,[ebp-0Bh]
00477BB8 mov ecx,40h
00477BBD mov edx,4
00477BC2 call 00402B68
00477BC7 lea eax,[ebp-4]
00477BCA call 00403FF4
00477BCF lea edx,[ebp-7]
00477BD2 mov ecx,ebx
00477BD4 call 00402890
00477BD9 cmp ebx,3
00477BDC jl 00477BE6
<-此段代码循环三次,每次都把前面计算出的9个数取出三个
00477BDE mov al,byte ptr [ebp-5]
<-取第三个数
00477BE1 and al,3Fh
<-和3F进行AND运算
00477BE3 mov byte ptr [ebp-8],al
<-保存结果
00477BE6 cmp ebx,2
00477BE9 jl 00477C00
00477BEB mov al,byte ptr [ebp-6]
<-取第二个数
00477BEE shl eax,2
<-左移2位
00477BF1 xor edx,edx
00477BF3 mov dl,byte ptr [ebp-5]
<-取第三个数
00477BF6 shr edx,6
<-右移动6位
00477BF9 or al,dl
<-俩个结果进行or运算
00477BFB and al,3Fh
<-运算结果再与3F进行and运算
00477BFD mov byte ptr [ebp-9],al
<-保存结果
00477C00 mov al,byte ptr [ebp-7]
<-取第一个数
00477C03 mov edx,eax
00477C05 shl edx,4
<-左移4位
00477C08 xor ecx,ecx
00477C0A mov cl,byte ptr [ebp-6]
<-取第二个数
00477C0D shr ecx,4
<-右移4位
00477C10 or dl,cl
<-俩个结果进行or运算
00477C12 and dl,3Fh
<-运算结果再与3F进行and运算
00477C15 mov byte ptr [ebp-0Ah],dl <-保存结果
00477C18 and eax,0FFh
<-第一个数与ff进行and运算
00477C1D shr eax,2
<-结果右移2位
00477C20 and al,3Fh
<-运算结果再与3F进行and运算
00477C22 mov byte ptr [ebp-0Bh],al <-保存结果
00477C25 lea eax,[ebp-4]
00477C28 mov ecx,ebx
00477C2A mov edx,1
00477C2F call 0040406C
00477C34 mov esi,4
00477C39 lea ebx,[ebp-0Bh]
00477C3C lea eax,[ebp-10h]
00477C3F xor edx,edx
00477C41 mov dl,byte ptr [ebx]
<-这里循环四次,就是每此分别取出上面计算出的四个数
00477C43 mov dl,byte ptr [edx+47E49Dh]
<-47e490d处保存了一个用来生成解琐码的长字符串,根据
<-前面计算出的四个数的位置取出四个字符,就是解锁码的
<-四位
00477C49 call 00403D4C
00477C4E mov edx,dword ptr [ebp-10h]
00477C51 mov eax,edi
00477C53 call 00403E2C
00477C58 inc ebx
00477C59 dec esi
00477C5A jne 00477C3C
00477C5C cmp dword ptr [ebp-4],0
00477C60 jne 00477B85
<-此处循环三次,计算出12位的解锁码
00477C66 xor eax,eax
00477C68 pop edx
00477C69 pop ecx
00477C6A pop ecx
00477C6B mov dword ptr fs:[eax],edx
00477C6E push 477C8Bh
00477C73 lea eax,[ebp-10h]
00477C76 call 00403BA4
00477C7B lea eax,[ebp-4]
00477C7E call 00403BA4
00477C83 ret
对本段分析如下:
注:b1-b9为前面生成的结果,m,n,k为计算中间结果,N1-N12为最后的结果
取出三个数:b1 b2 b3
1, b3 and 3f =N1(生成第一个数)
2, b2 shl 2 =m
b3 shr 6 =n
m or n =k
k and 3f =N2(生成第二个数)
3, b1 shl 4 =m
b2 shr 4 =n
m or n =k
k and 3f =N3(生成第三个数)
4, b1 and 0ff =m
m shr 2 =n
n and 3f =N4(生成第四个数)
取三个数:b4 b5 b6
与前面三个数执行同样的运算
取三个数:b7 b8 b9
与前面三个数执行同样的运算
最后生成12个数从N1-N12
现在从47E49Dh处保存的数据分别从N1到N12位置取出12个字符,就是最终的解锁码了。
第一次写这样的东西,可能看起来很乱,看起来步骤很简单,但是实际跟踪的时候乱
七八糟的CALL搞的头都晕,也许对于高手来手很简单,但是谁让咱菜呢,要是表达不
清楚,还请海涵。对于软件作者在这里也说声抱歉,算是对他乱发垃圾邮件的一个小
小的惩罚吧。不知道帖子发完会不会变形,就这些吧。
下面附上注册机代码:
VC的对话框程序:m_machine_code和m_register_code分别为俩个EDIT控件的变量
void CGwxzDlg::OnOK()
{
// TODO: Add extra validation here
char BaseCode[]="此处为生成的解锁码的字串,这里就不给出了";
char MachineCode[10];
char RegisterCode[12];
int MidData[9];
int i,a,b;
UpdateData(true);
strncpy(MachineCode,m_machine_code,10);
MachineCode[10]=0;
for(i=0;i<9;i++)
{
MidData[i]=MachineCode[i]^10;
MidData[i]^=i+1;
MidData[i]^=MachineCode[9-i];
}
MidData[0]^=MachineCode[0];
for(i=1;i<4;i++)
{
a=MidData[3*i-1];
a&=0x3f;
RegisterCode[4*i-1]=a;
a=MidData[3*i-2];
a<<=2;
b=MidData[3*i-1];
b>>=6;
a|=b;
a&=0x3f;
RegisterCode[4*i-2]=a;
a=MidData[3*i-3];
a<<=4;
b=MidData[3*i-2];
b>>=4;
a|=b;
a&=0x3f;
RegisterCode[4*i-3]=a;
a=MidData[3*i-3];
a&=0xff;
a>>=2;
a&=0x3f;
RegisterCode[4*i-4]=a;
}
for(i=0;i<12;i++)
{
RegisterCode[i]=BaseCode[RegisterCode[i]];
}
RegisterCode[12]=0;
m_register_code=RegisterCode;
UpdateData(false);
}