【破解作者】 lee
【作者邮箱】 cracker_lee@126.com
【使用工具】 OD,PEID,IDA
【破解平台】 WinXP
【软件名称】 PC定时执行专家
【软件简介】   PC定时执行专家( PCTimerExpert )是一个Visual C++ 制作,简单易用的“定时器”软件。有“定时关机”、“定时日程提醒”等功能。除了具有“PC定时关机精灵( PCTaskTimer )”的全部功能之外,还将会有更多的新功能加入。它是绿色的共享软件,无需安装,欢迎下载试用。注意未注册用户不能使用全部功能,需要注册才能使用的功能请参考本页的“主要功能和特点”。付费用户可享受技术支持和升级服务。

Unicode 版主要针对使用外文环境的用户,这个版本可是让你在英文、日文等外文的 Windows 系统下能正常地同时显示、输入外文和中文。

PC定时执行专家( PCTimerExpert )的由来:一直用着一个别人写的一个自动关机小程序,觉得界面有些难看,而且在日文的环境下有乱码的问题。索性自己写了一个完全英文的PCTimer小工具。只有3 个功能:注销、重启系统、关机。后来,觉得还可以加些功能,就成了现在的PC定时执行专家( PCTimerExpert )。

【软件大小】 132k
【加壳方式】 无
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
【破解内容】
  peid查知道该软件无壳Microsoft Visual C++ 6.0编写,OD载入:
  bp GetWindowTextA
0040410C    .  68 0A040000 push 40A
00404111    .  C74424 20 0>mov dword ptr ss:[esp+20],0 
0404119    .  E8 F24A0000 call <jmp.&MFC42.#3097>             // 中断后返回到这里
0040411E    .  8B4424 08   mov eax,dword ptr ss:[esp+8]
00404122    .  8B48 F8     mov ecx,dword ptr ds:[eax-8]       // 取得输入的长度放入ECX
00404125    .  85C9        test ecx,ecx  
00404127    .  75 0B       jnz short PCTimerE.00404134        //判断是否为空,如果不为空的话,就跳到00404134出将字符串转化为对应的整数
00404129    .  6A FF       push -1
0040412B    .  6A 40       push 40
0040412D    .  6A 78       push 78
0040412F    .  E9 C5000000 jmp PCTimerE.004041F9             //如果字符为空就直接跳到注册失败出
00404134    >  50          push eax                           ; /s
00404135    .  FF15 B0B540>call dword ptr ds:[<&MSVCRT.atol>] ; \atol
0040413B    .  8BF0        mov esi,eax                       //将转化的结果放入ESI中,以便后面做比较
0040413D    .  83C4 04     add esp,4
00404140    .  85F6        test esi,esi
00404142    .  0F84 AB0000>je PCTimerE.004041F3
00404148    .  6A 00       push 0                             ; /pFileSystemNameSize = NULL
0040414A    .  6A 00       push 0                             ; |pFileSystemNameBuffer = NULL
0040414C    .  6A 00       push 0                             ; |pFileSystemFlags = NULL
0040414E    .  8D4C24 18   lea ecx,dword ptr ss:[esp+18]      ; |
00404152    .  6A 00       push 0                             ; |pMaxFilenameLength = NULL
00404154    .  51          push ecx                           ; |pVolumeSerialNumber
00404155    .  6A 00       push 0                             ; |MaxVolumeNameSize = 0
00404157    .  6A 00       push 0                             ; |VolumeNameBuffer = NULL
00404159    .  68 D4F24000 push PCTimerE.0040F2D4             ; |RootPathName = "c:\"
0040415E    .  C74424 2C 0>mov dword ptr ss:[esp+2C],0        ; |
00404166    .  FF15 70B040>call dword ptr ds:[<&KERNEL32.Ge; \GetVolumeInformationA                                       //取序号
0040416C    .  85C0        test eax,eax
0040416E    .  75 11       jnz short PCTimerE.00404181
00404170    .  50          push eax
00404171    .  6A 30       push 30
00404173    .  68 B0F24000 push PCTimerE.0040F2B0
00404178    .  E8 AB4A0000 call <jmp.&MFC42.#1200>            ;  AfxMessageBox
0040417D    .  33C0        xor eax,eax
0040417F    .  EB 15       jmp short PCTimerE.00404196
00404181    >  8B4C24 0C   mov ecx,dword ptr ss:[esp+C]      //取序号成功后就跳到这里,并将序号放入ECX
00404185    .  8BD1        mov edx,ecx   
00404187    .  8BC1        mov eax,ecx                      //将结果放入同时放入到EDX和EAX方便后面的取高16位和低16位
00404189    .  C1EA 10     shr edx,10                       //取高16位
0040418C    .  2BC2        sub eax,edx                      //减去高16位的值
0040418E    .  81E1 FFFF00>and ecx,0FFFF                    //取低16位
00404194    .  2BC1        sub eax,ecx                      //减去低16位的值
00404196    >  8B15 94C740>mov edx,dword ptr ds:[40C794]    //在取一个常数34D944EA
0040419C    .  8BC8        mov ecx,eax                      //上面的结果也保存到ECX中
0040419E    .  C1E9 10     shr ecx,10                       //取结果的高16位
004041A1    .  33D0        xor edx,eax                      //将34D944EA与上面的结果异或
004041A3    .  25 FFFF0000 and eax,0FFFF                    //取结果的低16位
004041A8    .  2BD1        sub edx,ecx                      //在减去高16位
004041AA    .  2BD0        sub edx,eax                      //在减去低16位,此时EDX就是注册码
004041AC    .  33C0        xor eax,eax
004041AE    .  3BD6        cmp edx,esi                     //关键比较将用户输入的注册码与正确的注册码比较
004041B0    .  0F94C0      sete al
004041B3    .  85C0        test eax,eax
004041B5    .  74 3C       je short PCTimerE.004041F3    //如果前面的不相等的话,就跳到注册失败的地方
004041B7    .  E8 32480000 call <jmp.&MFC42.#1168>            ;AfxGetModuleState(void)
004041BC    .  8B40 04     mov eax,dword ptr ds:[eax+4]
004041BF    .  56          push esi
004041C0    .  68 8CF24000 push PCTimerE.0040F28C             ;  ASCII "REGCODE"
004041C5    .  68 7CF24000 push PCTimerE.0040F27C             ;  ASCII "Registration"
004041CA    .  8BC8        mov ecx,eax
004041CC    .  E8 5D4A0000 call <jmp.&MFC42.#6402>            ;WriteProfileInt(char const *,char const *,int)
004041D1    .  85C0        test eax,eax
004041D3    .  74 15       je short PCTimerE.004041EA
004041D5    .  6A FF       push -1
004041D7    .  6A 40       push 40
004041D9    .  6A 79       push 79
004041DB    .  E8 D8470000 call <jmp.&MFC42.#1199>            ;AfxMessageBox(“注册成功”)
004041E0    .  C705 30FB40>mov dword ptr ds:[40FB30],1
004041EA    >  8BCB        mov ecx,ebx
004041EC    .  E8 194A0000 call <jmp.&MFC42.#4853>            ;CDialog::OnOK(void)
004041F1    .  EB 0B       jmp short PCTimerE.004041FE
004041F3    >  6A FF       push -1
004041F5    .  6A 40       push 40
004041F7    .  6A 7A       push 7A
004041F9    >  E8 BA470000 call <jmp.&MFC42.#1199>            ;  AfxMessageBox("注册失败")
004041FE    >  8D4C24 08   lea ecx,dword ptr ss:[esp+8]
00404202    .  C74424 18 F>mov dword ptr ss:[esp+18],-1
0040420A    .  E8 B5470000 call <jmp.&MFC42.#800>
0040420F    .  8B4C24 10   mov ecx,dword ptr ss:[esp+10]
00404213    .  5E          pop esi
00404214    .  5B          pop ebx
00404215    .  64:890D 000>mov dword ptr fs:[0],ecx
0040421C    .  83C4 14     add esp,14
0040421F    .  C3          retn
-------------------------------------------------------------------
总结一下:
系统首先GetWindowText取到假注册码并转化为对应的整数后放入ESI中,接着用
GetVolumeInformationA取到序号后,我的为421E3A6F,接着用这个值减去它的高16位和低16位,即421E3A6F-421E-3A6F=421DBDE2。
接着用一个常数(34D944EA)与上面的结果异或,在减去上面结果的高16位和低16位,即34D944EA^421DBDE2-421D-BDE2=76C3F909(十进制为1992554761)。

所以我的电脑上注册码就是1992554761。

----------------------------------------------------------------------
注册机的大致编写过程:

DWORD m_sumber;
CString str;
GetVolumeInformation("c:\\",NULL,0,&m_sumber,NULL,NULL,NULL,NULL);
将m_sumber(10进制整型)转化为16进制整型
__asm
{
     push eax
     push ecx
     push edx
     mov ecx,m_sumber
     mov edx,ecx
     mov eax,ecx
     shr edx,10H
     sub eax,edx
     and ecx,0FFFFH
     sub eax,ecx
     mov edx,34D944EAH
     mov ecx,eax
     shr ecx,10H
     xor edx,eax
     and eax,0FFFFH
     sub edx,ecx
     mov m_sumber,edx
     pop edx
     pop ecx
     pop eax
}
将m_sumber(16进制整型)转化为10进制整型
str.Format("%ld",m_sumber);
m_edit.SetWindowText(str);
}

----------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!