【作者邮箱】: a474528738@163.com
【作者QQ号】: 474528738
【软件名称】: Advanced SystemCare 5.4.0.257
【软件大小】: 26.3
【下载地址】: http://download.cnet.com/Advanced-SystemCare/3000-2086_4-10407614.html?part=dl-6271865&subj=dl&tag=button
【加壳方式】: 无
【编写语言】: Borland Delphi 6.0 - 7.0 [Overlay]
【操作平台】: xp sp3
【软件介绍】: 这是一款很不错的系统维护软件,国外iobit的
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
注:所有分析均在断网情况下,包括注册机的编写. 注册机也请在断网的情况下使用
注册时会出现无法连接服务器的错误,不要管他,点击完成即可正常使用
-------------------------------------------------------------------------------------
【详细过程】
这款软件的算法还是比较清晰的,只是我找它的算法用了很久,这也是它的一个特点吧....其实我技术也不咋的
但这篇文章若能起到抛砖引玉的作用,那就是我最大的欣慰了。看它的截图:
我分析这个软件花了2天,很累,所以写的很简单, 难免有纰漏,到时请指出。
废话不多说,开始吧。
PEID查到:Borland Delphi 6.0 - 7.0 [Overlay],用DD发现它用运行时间包编译--这是什么东东?,求指教。
看来它使用较新的编译器编的,单独打开安装文件夹里的Register.exe却无法运行。OD载入
在TerminateProcess的所有输入函数参考上下断点(Ctrl+N查到的),运行,断在:
0047F6C6 . B8 01000000 mov eax,1
0047F6CB . E8 6819F8FF call <jmp.&rtl120.System::ParamStr>
0047F6D0 . 8B85 50FFFFFF mov eax,dword ptr ss:[ebp-B0]
0047F6D6 . BA A0FB4700 mov edx,Register.0047FBA0 ; UNICODE "/trail"
0047F6DB . E8 D028F8FF call <jmp.&rtl120.Sysutils::CompareText>
0047F6E0 . 85C0 test eax,eax
0047F6E2 . 75 13 jnz short Register.0047F6F7
0047F6E4 . C783 78060000>mov dword ptr ds:[ebx+678],1
0047F6EE . C683 70060000>mov byte ptr ds:[ebx+670],0
0047F6F5 . EB 0D jmp short Register.0047F704
0047F6F7 > 6A 00 push 0 ; /ExitCode = 0
0047F6F9 . E8 EA1DF8FF call <jmp.&kernel32.GetCurrentProcess> ; |[GetCurrentProcess
0047F6FE . 50 push eax ; |hProcess
0047F6FF . E8 581FF8FF call <jmp.&kernel32.TerminateProcess> ; \TerminateProcess <----断在此处
0047F704 > 8D95 4CFFFFFF lea edx,dword ptr ss:[ebp-B4]
0047F70A . 8BC3 mov eax,ebx
0047F70C . E8 63100000 call Register.00480774
向上翻看,看到了:
0047F4F0 . E8 1B25F8FF call <jmp.&vcl120.Forms::TCustomForm::SetFormStyle>
0047F4F5 . C783 78060000>mov dword ptr ds:[ebx+678],3
0047F4FF . E9 00020000 jmp Registes.0047F704
0047F504 > 8D95 60FFFFFF lea edx,dword ptr ss:[ebp-A0]
0047F50A . B8 01000000 mov eax,1
0047F50F . E8 241BF8FF call <jmp.&rtl120.System::ParamStr>
0047F514 . 8B85 60FFFFFF mov eax,dword ptr ss:[ebp-A0]
0047F51A . 8D95 64FFFFFF lea edx,dword ptr ss:[ebp-9C]
0047F520 . E8 732AF8FF call <jmp.&rtl120.Sysutils::UpperCase>
0047F525 . 8B85 64FFFFFF mov eax,dword ptr ss:[ebp-9C]
0047F52B . BA 18FB4700 mov edx,Registes.0047FB18 ; UNICODE "/REG"
0047F530 . E8 F31DF8FF call <jmp.&rtl120.System::UStrEqual>
0047F535 . 75 1B jnz short Registes.0047F552 <-------不跳,则调出注册窗口,于是,我们NOP---
0047F537 . 33D2 xor edx,edx
0047F539 . A1 34474900 mov eax,dword ptr ds:[494734]
0047F53E . E8 CD24F8FF call <jmp.&vcl120.Forms::TCustomForm::SetFormStyle>
0047F543 . C783 78060000>mov dword ptr ds:[ebx+678],4
0047F54D . E9 B2010000 jmp Registes.0047F704
0047F552 > 8D95 5CFFFFFF lea edx,dword ptr ss:[ebp-A4]
0047F558 . B8 01000000 mov eax,1
0047F55D . E8 D61AF8FF call <jmp.&rtl120.System::ParamStr>
保存后再次OD载入运行,出错,提示:the file "Register.exe" seems to be corrupt!
哈,还有自效验!?好吧,F12暂停程序,查看堆栈:
调用堆栈:
0012FCCC 00000000 hOwner = NULL
0012FCD0 00D2335C Text = "The file "Register.exe" se
0012FCD4 00000000 Title = NULL
0012FCD8 00000010 Style = MB_OK|MB_ICONHAND|MB_APPLM
0012FCDC 00000000 LanguageID = 0 (LANG_NEUTRAL)
0012FCE4 5983F1BF ? <jmp.&user32.MessageBoxA> madexcep.5983F1BA <---出错的地址
0012FCE8 00000000 hOwner = NULL
0012FCEC 00D2335C Text = "The file "Register.exe" se
0012FCF0 00000000 Title = NULL
0012FCF4 00000010 Style = MB_OK|MB_ICONHAND|MB_APPLM
0012FE38 5983F712 ? madexcep.5983F080 madexcep.5983F70D
0012FF50 598440D2 ? madexcep.5983F5D0 madexcep.598440CD
于是,来到 madexcep.5983F1BA:
5983F186 E8 1925FCFF call <jmp.&kernel32.CloseHandle>
5983F18B 56 push esi
5983F18C E8 1325FCFF call <jmp.&kernel32.CloseHandle>
5983F191 84DB test bl,bl
5983F193 74 71 je short madexcep.5983F206 <----注意:改为Jmp
5983F195 6A 10 push 10
5983F197 6A 00 push 0
5983F199 8D95 E0FEFFFF lea edx,dword ptr ss:[ebp-120]
5983F19F A1 2C588459 mov eax,dword ptr ds:[5984582C]
5983F1A4 8B08 mov ecx,dword ptr ds:[eax]
5983F1A6 FF91 48020000 call dword ptr ds:[ecx+248]
5983F1AC 8B85 E0FEFFFF mov eax,dword ptr ss:[ebp-120]
5983F1B2 E8 6920FCFF call <jmp.&rtl120.System::LStrToPChar>
5983F1B7 50 push eax
5983F1B8 6A 00 push 0
5983F1BA E8 C12BFCFF call <jmp.&user32.MessageBoxA> <-------看到这个了吗?---错误对话框
5983F1BF 6A 00 push 0
5983F1C1 E8 9E26FCFF call <jmp.&kernel32.GetModuleHandleW>
5983F1C6 3B05 04608459 cmp eax,dword ptr ds:[59846004] ; madexcep.59800000
5983F1CC 74 31 je short madexcep.5983F1FF
5983F1CE B8 2C588459 mov eax,madexcep.5984582C
5983F1D3 E8 D821FCFF call <jmp.&rtl120.System::IntfClear>
5983F1D8 8D85 DCFEFFFF lea eax,dword ptr ss:[ebp-124]
更改之后,程序正常运行,弹出注册窗口。这里我又要罗嗦了。解决自效验,一般下creatfile断点的,我是为了不要让文章太长,才如此做的。
从出错的地方往上翻,可以看到 CreatFileA函数....所以说,这才是根本的解决办法....请参考"laomms-常见自校检分析实例"等大侠的文章。
现在,可以分析算法了。OD载入,Ctrl+N,找到了:
名称位于 Register, 条目 261
地址=00497364
区段=.idata
类型=输入
名称=vcl120.Controls::TControl::GetText
于是,在其输入函数参考上下断点,随便输入序列号,断在:
0047E674 . 55 push ebp <---在此下断点
0047E675 . 8BEC mov ebp,esp
0047E677 . 6A 00 push 0
0047E679 . 6A 00 push 0
0047E67B . 6A 00 push 0
0047E67D . 53 push ebx
0047E67E . 56 push esi
0047E67F . 57 push edi
0047E680 . 8945 FC mov dword ptr ss:[ebp-4],eax
0047E683 . 33C0 xor eax,eax
0047E685 . 55 push ebp
0047E686 . 68 D8E74700 push Register.0047E7D8
0047E68B . 64:FF30 push dword ptr fs:[eax]
0047E68E . 64:8920 mov dword ptr fs:[eax],esp
0047E691 . 8B45 FC mov eax,dword ptr ss:[ebp-4]
0047E694 . C780 74060000>mov dword ptr ds:[eax+674],1
0047E69E . 8D55 F8 lea edx,dword ptr ss:[ebp-8]
0047E6A1 . 8B45 FC mov eax,dword ptr ss:[ebp-4]
0047E6A4 . 8B80 A4030000 mov eax,dword ptr ds:[eax+3A4]
0047E6AA . E8 A13FF8FF call <jmp.&vcl120.Controls::TControl::GetText> <----断在此处
0047E6AF . 8B55 F8 mov edx,dword ptr ss:[ebp-8]
下好断点后,按照它的提示,我们输入:12365-87459-65789-85478,来到
0047E68B . 64:FF30 push dword ptr fs:[eax]
0047E68E . 64:8920 mov dword ptr fs:[eax],esp
0047E691 . 8B45 FC mov eax,dword ptr ss:[ebp-4]
0047E694 . C780 74060000>mov dword ptr ds:[eax+674],1
0047E69E . 8D55 F8 lea edx,dword ptr ss:[ebp-8]
0047E6A1 . 8B45 FC mov eax,dword ptr ss:[ebp-4]
0047E6A4 . 8B80 A4030000 mov eax,dword ptr ds:[eax+3A4]
0047E6AA . E8 A13FF8FF call <jmp.&vcl120.Controls::TControl::GetText>
0047E6AF . 8B55 F8 mov edx,dword ptr ss:[ebp-8]
0047E6B2 . 8B45 FC mov eax,dword ptr ss:[ebp-4]
0047E6B5 . E8 CA6D0000 call Register.00485484 <----计算是否已经失效的序列号
0047E6BA . 84C0 test al,al
0047E6BC . 74 72 je short Register.0047E730
0047E6BE . 8B45 FC mov eax,dword ptr ss:[ebp-4]
0047E6C1 . 8B80 A4030000 mov eax,dword ptr ds:[eax+3A4]
0047E6C7 . BA E08A8A00 mov edx,8A8AE0
0047E6CC . E8 CF3FF8FF call <jmp.&vcl120.Controls::TControl::SetColor>
0047E6D1 . 33C0 xor eax,eax
0047E6D3 . 55 push ebp
0047E6D4 . 68 FAE64700 push Register.0047E6FA
0047E6D9 . 64:FF30 push dword ptr fs:[eax]
0047E6DC . 64:8920 mov dword ptr fs:[eax],esp
0047E6DF . 8B45 FC mov eax,dword ptr ss:[ebp-4]
0047E6E2 . 8B80 A4030000 mov eax,dword ptr ds:[eax+3A4]
0047E6E8 . 8B10 mov edx,dword ptr ds:[eax]
0047E6EA . FF92 D8000000 call dword ptr ds:[edx+D8]
0047E6F0 . 33C0 xor eax,eax
0047E6F2 . 5A pop edx
0047E6F3 . 59 pop ecx
0047E6F4 . 59 pop ecx
0047E6F5 . 64:8910 mov dword ptr fs:[eax],edx
0047E6F8 . EB 0A jmp short Register.0047E704
0047E6FA .^ E9 612AF8FF jmp <jmp.&rtl120.System::HandleAnyException>
0047E6FF . E8 8C2AF8FF call <jmp.&rtl120.System::DoneExcept>
0047E704 > 8B45 FC mov eax,dword ptr ss:[ebp-4]
0047E707 . 8B90 08070000 mov edx,dword ptr ds:[eax+708]
0047E70D . 8B45 FC mov eax,dword ptr ss:[ebp-4]
0047E710 . 8B80 20050000 mov eax,dword ptr ds:[eax+520]
0047E716 . E8 3D3FF8FF call <jmp.&vcl120.Controls::TControl::SetText>
0047E71B . 8B45 FC mov eax,dword ptr ss:[ebp-4]
0047E71E . 8B80 20050000 mov eax,dword ptr ds:[eax+520]
0047E724 . B2 01 mov dl,1
0047E726 . E8 0D3FF8FF call <jmp.&vcl120.Controls::TControl::SetVisible>
0047E72B . E9 8D000000 jmp Register.0047E7BD
0047E730 > 8D55 F4 lea edx,dword ptr ss:[ebp-C]
0047E733 . 8B45 FC mov eax,dword ptr ss:[ebp-4]
0047E736 . 8B80 A4030000 mov eax,dword ptr ds:[eax+3A4]
0047E73C . E8 0F3FF8FF call <jmp.&vcl120.Controls::TControl::GetText>
0047E741 . 8B55 F4 mov edx,dword ptr ss:[ebp-C]
0047E744 . 8B45 FC mov eax,dword ptr ss:[ebp-4]
0047E747 . E8 ECE2FFFF call Register.0047CA38 <--------关键call
0047E74C . 84C0 test al,al
0047E74E . 75 6D jnz short Register.0047E7BD
0047E750 . 8B45 FC mov eax,dword ptr ss:[ebp-4]
… …… …
进入关键call,来到:
0047CA38 /$ 55 push ebp
0047CA39 |. 8BEC mov ebp,esp
0047CA3B |. 51 push ecx
0047CA3C |. 53 push ebx
0047CA3D |. 8955 FC mov [local.1],edx
0047CA40 |. 8BD8 mov ebx,eax
0047CA42 |. 8B45 FC mov eax,[local.1]
0047CA45 |. E8 3648F8FF call <jmp.&rtl120.System::UStrAddRef>
0047CA4A |. 33C0 xor eax,eax
0047CA4C |. 55 push ebp
0047CA4D |. 68 D2CA4700 push Register.0047CAD2
0047CA52 |. 64:FF30 push dword ptr fs:[eax]
0047CA55 |. 64:8920 mov dword ptr fs:[eax],esp
0047CA58 |. 33D2 xor edx,edx
0047CA5A |. 8B83 D0030000 mov eax,dword ptr ds:[ebx+3D0]
0047CA60 |. E8 D35BF8FF call <jmp.&vcl120.Controls::TControl::SetVisible>
0047CA65 |. 33D2 xor edx,edx
0047CA67 |. 8B83 88050000 mov eax,dword ptr ds:[ebx+588]
0047CA6D |. E8 C65BF8FF call <jmp.&vcl120.Controls::TControl::SetVisible>
0047CA72 |. 8B55 FC mov edx,[local.1]
0047CA75 |. 8BC3 mov eax,ebx
0047CA77 |. E8 6C760000 call Register.004840E8 <---往rtl120.Classes::TStringList 里面添加字符串
0047CA7C |. 84C0 test al,al
0047CA7E |. 74 04 je short Register.0047CA84
0047CA80 |. 33DB xor ebx,ebx
0047CA82 |. EB 38 jmp short Register.0047CABC
0047CA84 |> 8B55 FC mov edx,[local.1]
0047CA87 |. 8BC3 mov eax,ebx
0047CA89 |. E8 F6890000 call Register.00485484
0047CA8E |. 84C0 test al,al
0047CA90 |. 74 04 je short Register.0047CA96
0047CA92 |. 33DB xor ebx,ebx
0047CA94 |. EB 26 jmp short Register.0047CABC
0047CA96 |> 8B45 FC mov eax,[local.1]
0047CA99 |. E8 F2FEFFFF call Register.0047C990 <-----计算假序列号长度
0047CA9E |. 84C0 test al,al
0047CAA0 |. 74 0E je short Register.0047CAB0
0047CAA2 |. 8B55 FC mov edx,[local.1]
0047CAA5 |. 8BC3 mov eax,ebx
0047CAA7 |. E8 68060000 call Register.0047D114
0047CAAC |. 8BD8 mov ebx,eax
0047CAAE |. EB 0C jmp short Register.0047CABC
0047CAB0 |> 8B55 FC mov edx,[local.1]
0047CAB3 |. 8BC3 mov eax,ebx
0047CAB5 |. E8 E60F0000 call Register.0047DAA0 <----关键call
0047CABA |. 8BD8 mov ebx,eax
0047CABC |> 33C0 xor eax,eax
0047CABE |. 5A pop edx
0047CABF |. 59 pop ecx
0047CAC0 |. 59 pop ecx
进入关键call:
0047DAA0 /$ 55 push ebp
0047DAA1 |. 8BEC mov ebp,esp
0047DAA3 |. B9 07000000 mov ecx,7
0047DAA8 |> 6A 00 /push 0
0047DAAA |. 6A 00 |push 0
0047DAAC |. 49 |dec ecx
0047DAAD |.^ 75 F9 \jnz short Register.0047DAA8
0047DAAF |. 51 push ecx
0047DAB0 |. 53 push ebx
0047DAB1 |. 56 push esi
0047DAB2 |. 8955 FC mov [local.1],edx
0047DAB5 |. 8BF0 mov esi,eax
0047DAB7 |. 8B45 FC mov eax,[local.1]
0047DABA |. E8 C137F8FF call <jmp.&rtl120.System::UStrAddRef>
0047DABF |. 33C0 xor eax,eax
0047DAC1 |. 55 push ebp
0047DAC2 |. 68 8CDF4700 push Register.0047DF8C
0047DAC7 |. 64:FF30 push dword ptr fs:[eax]
0047DACA |. 64:8920 mov dword ptr fs:[eax],esp
0047DACD |. 8B55 FC mov edx,[local.1]
0047DAD0 |. 8BC6 mov eax,esi
0047DAD2 |. E8 857D0000 call Register.0048585C <------关键call
0047DAD7 |. 84C0 test al,al
0047DAD9 |. 0F84 6E040000 je Register.0047DF4D
0047DADF |. 8B86 74060000 mov eax,dword ptr ds:[esi+674]
0047DAE5 |. 85C0 test eax,eax
进入关键call,
0048585C /$ 55 push ebp
0048585D |. 8BEC mov ebp,esp
0048585F |. 33C9 xor ecx,ecx
00485861 |. 51 push ecx
00485862 |. 51 push ecx
00485863 |. 51 push ecx
00485864 |. 51 push ecx
00485865 |. 53 push ebx
00485866 |. 8955 FC mov [local.1],edx
00485869 |. 8BD8 mov ebx,eax
0048586B |. 8B45 FC mov eax,[local.1]
0048586E |. E8 0DBAF7FF call <jmp.&rtl120.System::UStrAddRef>
00485873 |. 33C0 xor eax,eax
00485875 |. 55 push ebp
00485876 |. 68 52594800 push Register.00485952
0048587B |. 64:FF30 push dword ptr fs:[eax]
0048587E |. 64:8920 mov dword ptr fs:[eax],esp
00485881 |. 8B45 FC mov eax,[local.1]
00485884 |. E8 1FBAF7FF call <jmp.&rtl120.System::UStrToPWChar>
00485889 |. E8 5E0D0000 call Register.004865EC -----关键call
0048588E |. 85C0 test eax,eax ; Switch (cases 0..1)
00485890 |. 75 07 jnz short Register.00485899
进入关键call:
004865EC $ 55 push ebp
004865ED . 8BEC mov ebp,esp
004865EF . 51 push ecx
004865F0 . 53 push ebx
004865F1 . 56 push esi
004865F2 . 57 push edi
004865F3 . 8BD8 mov ebx,eax
004865F5 . 33D2 xor edx,edx
004865F7 . 55 push ebp
004865F8 . 68 5B664800 push Register.0048665B
004865FD . 64:FF32 push dword ptr fs:[edx]
00486600 . 64:8922 mov dword ptr fs:[edx],esp
00486603 . 68 70664800 push Register.00486670 ; /FileName = "OFCommon.dll"
00486608 . E8 FFAFF7FF call <jmp.&kernel32.LoadLibraryW> ; \LoadLibraryW
0048660D . 8945 FC mov dword ptr ss:[ebp-4],eax
00486610 . 33D2 xor edx,edx
00486612 . 55 push ebp
00486613 . 68 3B664800 push Register.0048663B
00486618 . 64:FF32 push dword ptr fs:[edx]
0048661B . 64:8922 mov dword ptr fs:[edx],esp
0048661E . 68 8C664800 push Register.0048668C ; UNICODE "IsTaskValidEx"
00486623 . 8B45 FC mov eax,dword ptr ss:[ebp-4]
00486626 . 50 push eax
00486627 . E8 ECAEF7FF call Register.00401518
0048662C . 53 push ebx
0048662D . FFD0 call eax ------------------关键call ; OFCommon.IsTaskValidEx
0048662F . 8BD8 mov ebx,eax
00486631 . 33C0 xor eax,eax
进入关键call:
0310D810 >/$ 55 push ebp
0310D811 |. 8BEC mov ebp,esp
0310D813 |. 8B45 08 mov eax,[arg.1]
0310D816 |. 50 push eax
0310D817 |. E8 50F1FFFF call OFCommon.0310C96C <------进去
0310D81C |. 5D pop ebp
0310D81D \. C2 0400 retn 4
来到:
0310C96C /$ 55 push ebp
0310C96D |. 8BEC mov ebp,esp
0310C96F |. 53 push ebx
0310C970 |. 8B5D 08 mov ebx,[arg.1]
0310C973 |. 53 push ebx
0310C974 |. E8 B3F9FFFF call OFCommon.0310C32C <----真正的算法call
0310C979 |. 84C0 test al,al
0310C97B |. 74 04 je short OFCommon.0310C981 ; no jump
0310C97D |. 33C0 xor eax,eax
0310C97F |. EB 15 jmp short OFCommon.0310C996
0310C981 |> 8BC3 mov eax,ebx
0310C983 |. E8 70F3FFFF call OFCommon.0310BCF8 <-----经过分析,他是判断序列号是否为 ***杀毒软件的序列号
0310C988 |. 84C0 test al,al
0310C98A |. 74 07 je short OFCommon.0310C993
0310C98C |. B8 01000000 mov eax,1
0310C991 |. EB 03 jmp short OFCommon.0310C996
0310C993 |> 83C8 FF or eax,FFFFFFFF
0310C996 |> 5B pop ebx
0310C997 |. 5D pop ebp
0310C998 \. C2 0400 retn 4
现在是不是觉得找到算法CALL很麻烦了?,我分析了1天,找他,实在是很烦~~.
这时候我们到了OFCommon.dll的领空,PEID插件KANAL2.9查到 MD5算法----与3.7.0版本的算法很相似,都用到了MD5
如果你看了我对ASC3.7.0版本软件的分析,就很快知道此版本的算法用了什么加密算法了---人是有惰性的,既然上个版本用了MD5,这次应该还会用的~~
算法的具体分析就留给你吧,很简单的。
还有一个问题,注册程序不能多开,经分析,找到关键跳转:
00488D40 |. 6A 00 push 0
00488D42 |. E8 6187F7FF call Register.004014A8
00488D47 |. E8 B487F7FF call <jmp.&kernel32.GetLastError> ; [GetLastError
00488D4C |. 3D B7000000 cmp eax,0B7
00488D51 |. 0F85 63010000 jnz Register.00488EBA <-----将此处改为jmp即可
00488D57 |. 6A 00 push 0 ; /Title = NULL
好了,我没有具体分析一下算法,但还是要总结一下算法:
1,将序列号(不包含"-")第10位至第14位(已转换为大写)MD5值计算出来,取前五位与第5至第9位序列号比较
2,将序列号(不包含"-")第15位至第18位(已转换为大写)MD5值计算出来,取最后4位与第1至第4位序列号比较
3,最后1位序列号为 0,1,3,5,7,9,B,C,D,.....
4,最后第2位序列号为 D,.....
注册机源码就不放上来了,MD5比较难写之外,其他的都很简单。
---------------其实,最后两位序列号为"DB","D9"才可以正常使用,其他序列号最多过一天后就失效了,这是为什么?
我实在不想再分析了,很累。哪位有兴趣分析一下吧,把过程贴上来,完善分析。--在此感谢
--------------------------------------------------------------------------------
【版权声明】: 转载请注明作者并保持文章的完整, 谢谢!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)