欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

Advanced SystemCare离线算法分析

程序员文章站 2022-04-22 10:51:37
【文章作者】: 红绡枫叶 【作者邮箱】: a474528738@163.com 【作者主页】: ------- 【作者QQ号】: 474528738 【软件名称】: Advanced...
【文章作者】: 红绡枫叶
【作者邮箱】: a474528738@163.com
【作者主页】: -------
【作者QQ号】: 474528738
【软件名称】: Advanced SystemCare 3.7.0
【软件大小】: 8.44M
【下载地址】: 自己搜索下载
【加壳方式】: 无
【编写语言】: Delphi
【使用工具】: OD,PEID,MD5计算器等
【操作平台】: XP
【软件介绍】: 功能比较齐全,很不错的一款系统维护软件
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  写这篇文章主要是为了照顾新手(其实我也算是菜鸟),给新手一些鼓励:像Advanced SystemCare这种正规的软件也很容易知道他的算法。(软件版本:3.7.0)
  不多说了,开始吧。
  在它的安装文件夹里看见了Registration.exe,不用想(英文你应该看得懂吧),这就是注册程序。
  PEID:Delphi,无壳,OD载入,输入假注册码:用户名:fng,注册码:123456789。出现错误提示。
  可是却查不到任何有用字符串。好吧,下MessageboxW断点。为什么要下这个断点?因为 右击-->查找--->搜索当前模块名称 中看见了,
  于是,断在了:
  00480723   .  50            push eax                                 ; |hOwner
  00480724   .  E8 A312F8FF   call <jmp.&user32.MessageBoxW>           ; \MessageBoxW    <---从系统返回到此
  00480729   .  E9 A20C0000   jmp Registra.004813D0
  向上到该段代码头下断点:
  00480502   .  55            push ebp     ----下断在此处
  00480503   .  68 7E154800   push Registra.0048157E
  00480508   .  64:FF30       push dword ptr fs:[eax]
  0048050B   .  64:8920       mov dword ptr fs:[eax],esp
  0048050E   .  8B45 FC       mov eax,dword ptr ss:[ebp-4]
  00480511   .  8B80 90030000 mov eax,dword ptr ds:[eax+390]
  00480517   .  E8 B82DF8FF   call <jmp.&vcl70.Comctrls::TPageControl:>
  0048051C   .  85C0          test eax,eax
  0048051E   .  0F85 AC0E0000 jnz Registra.004813D0
  00480524   .  8D45 DC       lea eax,dword ptr ss:[ebp-24]
  00480527   .  E8 A40CF8FF   call <jmp.&rtl70.System::LStrClr>
  0048052C   .  8D95 DCFEFFFF lea edx,dword ptr ss:[ebp-124]
  00480532   .  8B45 FC       mov eax,dword ptr ss:[ebp-4]
  00480535   .  8B80 A0030000 mov eax,dword ptr ds:[eax+3A0]
  0048053B   .  E8 441BF9FF   call Registra.00412084
  00480540   .  8B85 DCFEFFFF mov eax,dword ptr ss:[ebp-124]------取得用户名fng
  00480546   .  8D95 E0FEFFFF lea edx,dword ptr ss:[ebp-120]
  0048054C   .  E8 CF17F8FF   call <jmp.&rtl70.Sysutils::Trim>
  00480551   .  8B95 E0FEFFFF mov edx,dword ptr ss:[ebp-120]
  00480557   .  8D85 E4FEFFFF lea eax,dword ptr ss:[ebp-11C]
  0048055D   .  E8 D60CF8FF   call <jmp.&rtl70.System::LStrFromWStr>
  00480562   .  8B85 E4FEFFFF mov eax,dword ptr ss:[ebp-11C]
  00480568   .  8D95 E8FEFFFF lea edx,dword ptr ss:[ebp-118]
  0048056E   .  E8 5517F8FF   call <jmp.&rtl70.Sysutils::LowerCase>
  00480573   .  8B85 E8FEFFFF mov eax,dword ptr ss:[ebp-118]
  00480579   .  8D55 F8       lea edx,dword ptr ss:[ebp-8]           
  0048057C   .  E8 C7E7FFFF   call Registra.0047ED48             ; 对用户名进行一系列操作后,出现了这个CALL,很可疑啊
  00480581   .  8D95 D4FEFFFF lea edx,dword ptr ss:[ebp-12C]
  00480587   .  8B45 FC       mov eax,dword ptr ss:[ebp-4]
  0048058A   .  8B80 A0030000 mov eax,dword ptr ds:[eax+3A0]
  00480590   .  E8 EF1AF9FF   call Registra.00412084             ;这个也很可疑
  00480595   .  8B85 D4FEFFFF mov eax,dword ptr ss:[ebp-12C]
  0048059B   .  8D95 D8FEFFFF lea edx,dword ptr ss:[ebp-128]
  004805A1   .  E8 7A17F8FF   call <jmp.&rtl70.Sysutils::Trim>
  004805A6   .  8B85 D8FEFFFF mov eax,dword ptr ss:[ebp-128]
  004805AC   .  33D2          xor edx,edx
  004805AE   .  E8 8D0DF8FF   call <jmp.&rtl70.System::WStrCmp>
  004805B3   .  0F85 8A000000 jnz Registra.00480643                    ;  不跳则出现无效的账户名错误
  紧接着跳到:
  00480643   > \8D95 C8FEFFFF lea edx,dword ptr ss:[ebp-138]
  00480649   .  8B45 FC       mov eax,dword ptr ss:[ebp-4]
  0048064C   .  8B80 A4030000 mov eax,dword ptr ds:[eax+3A4]
  00480652   .  E8 2D1AF9FF   call Registra.00412084                   ;取注册码
  00480657   .  8B95 C8FEFFFF mov edx,dword ptr ss:[ebp-138]
  0048065D   .  B8 94154800   mov eax,Registra.00481594                ;  - <------注意这个
  00480662   .  E8 F90CF8FF   call <jmp.&rtl70.System::WStrPos>        ;  出现了'-'符号后,又出现了这样一个CALL,后面又有一个je,那这个CALL很关键了
  00480667   .  85C0          test eax,eax
  00480669   .  74 39         je short Registra.004806A4               ;  跳向无效序列号错误
 
  如果你还不知道'-'是搞什么的----
  那就进入这个关键CALL看看吧----->  00480662   .  E8 F90CF8FF   call <jmp.&rtl70.System::WStrPos>        ;  出现了'-'符号后,又出现了这样一个CALL,后面又有一个je,那这个CALL很关键了
  进入来到:
 
  40007758 >  85C0            test eax,eax                                       ; Registra.00481594
  4000775A    74 4B           je short rtl70.400077A7
  4000775C    85D2            test edx,edx
  4000775E    74 3A           je short rtl70.4000779A
  40007760    53              push ebx
  40007761    56              push esi
  40007762    57              push edi
  40007763    89C6            mov esi,eax
  40007765    89D7            mov edi,edx
  40007767    8B4F FC         mov ecx,dword ptr ds:[edi-4]
  4000776A    D1E9            shr ecx,1
  4000776C    57              push edi
  4000776D    8B56 FC         mov edx,dword ptr ds:[esi-4]
  40007770    D1EA            shr edx,1
  40007772    4A              dec edx
  40007773    78 20           js short rtl70.40007795
  40007775    66:8B06         mov ax,word ptr ds:[esi]
  40007778    83C6 02         add esi,2
  4000777B    29D1            sub ecx,edx
  4000777D    7E 16           jle short rtl70.40007795
  4000777F    F2:66:AF        repne scas word ptr es:[edi]  <------关键语句,意思:串搜索指令.它可用来在字符串中查找关键字相同的的数据位置,此时ecx=00000009 (十进制9.);ax=002D ;es:[edi]=[001CB1B4]=0031
  40007782    75 11           jnz short rtl70.40007795
  40007784    89CB            mov ebx,ecx
  40007786    56              push esi
  40007787    57              push edi
  40007788    89D1            mov ecx,edx
  4000778A    F3:66:A7        repe cmps word ptr es:[edi],word ptr ds:[esi]
  4000778D    5F              pop edi
  4000778E    5E              pop esi
  4000778F    74 0C           je short rtl70.4000779D
  40007791    89D9            mov ecx,ebx
  40007793  ^ EB EA           jmp short rtl70.4000777F
  40007795    5A              pop edx
  40007796    31C0            xor eax,eax
  40007798    EB 0A           jmp short rtl70.400077A4
  4000779A    31C0            xor eax,eax
  4000779C    C3              retn
  4000779C    C3              retn
  在上面关键代码处,ECX=9,不就是我们注册码长度?ax=2D,是'-'的ASCII--16进制,es:[edi]=[001CB1B4]=0031,这不就是我们假码的第一位‘1’的ASCII的16进制嘛!
  哦,我们明白了,这段代码是在我们的假码里寻找'-',找不到就跳向:xor eax,eax语句,导致出现无效序列号错误。
 
  明白了这些,我们修改注册码:1234-56789123456789(为什么改为这个长度,看后面就知道了)
  于是从关键CALL后面到了:
  0048065D   .  B8 94154800   mov eax,Registra.00481594                          ;  -
  00480662   .  E8 F90CF8FF   call <jmp.&rtl70.System::WStrPos>                  ;  have a '-'
  00480667   .  85C0          test eax,eax
  00480669   .  74 39         je short Registra.004806A4                         ; 跳向无效序列号错误
  0048066B   .  8D95 C0FEFFFF lea edx,dword ptr ss:[ebp-140]             <------到了这里
  00480671   .  8B45 FC       mov eax,dword ptr ss:[ebp-4]
  00480674   .  8B80 A4030000 mov eax,dword ptr ds:[eax+3A4]
  0048067A   .  E8 051AF9FF   call Registra.00412084               ;取注册码
  0048067F   .  8B85 C0FEFFFF mov eax,dword ptr ss:[ebp-140]
  00480685   .  8D95 C4FEFFFF lea edx,dword ptr ss:[ebp-13C]
  0048068B   .  E8 9016F8FF   call <jmp.&rtl70.Sysutils::Trim>
  00480690   .  8B85 C4FEFFFF mov eax,dword ptr ss:[ebp-13C]
  00480696   .  E8 850CF8FF   call <jmp.&rtl70.System::WStrLen>     取注册码长度
  0048069B   .  83F8 13       cmp eax,13                            ;lenghth=19,注册码必须是这个长度
  0048069E   .  0F84 8A000000 je Registra.0048072E                 ;要跳转了才不会出现无效序列号错误            
  004806A4   >  8B45 FC       mov eax,dword ptr ss:[ebp-4]
  成功跳向:Registra.0048072E
  0048072E   > \8D85 B4FEFFFF lea eax,dword ptr ss:[ebp-14C]
  00480734   .  50            push eax
  00480735   .  8D95 A4FEFFFF lea edx,dword ptr ss:[ebp-15C]
  0048073B   .  8B45 FC       mov eax,dword ptr ss:[ebp-4]
  0048073E   .  8B80 A4030000 mov eax,dword ptr ds:[eax+3A4]
  00480744   .  E8 3B19F9FF   call Registra.00412084
  00480749   .  8B85 A4FEFFFF mov eax,dword ptr ss:[ebp-15C]
  0048074F   .  8D95 A8FEFFFF lea edx,dword ptr ss:[ebp-158]
  00480755   .  E8 C615F8FF   call <jmp.&rtl70.Sysutils::Trim>
  0048075A   .  8B95 A8FEFFFF mov edx,dword ptr ss:[ebp-158]
  00480760   .  8D85 ACFEFFFF lea eax,dword ptr ss:[ebp-154]
  00480766   .  E8 CD0AF8FF   call <jmp.&rtl70.System::LStrFromWStr>
  0048076B   .  8B85 ACFEFFFF mov eax,dword ptr ss:[ebp-154]
  00480771   .  8D95 B0FEFFFF lea edx,dword ptr ss:[ebp-150]
  00480777   .  E8 4415F8FF   call <jmp.&rtl70.Sysutils::UpperCase>
  0048077C   .  8B85 B0FEFFFF mov eax,dword ptr ss:[ebp-150]
  00480782   .  B9 09000000   mov ecx,9
  00480787   .  BA 01000000   mov edx,1
  0048078C   .  E8 EF0AF8FF   call <jmp.&rtl70.System::LStrCopy>  复制注册码前九位---"1234-5678"
  00480791   .  8B85 B4FEFFFF mov eax,dword ptr ss:[ebp-14C]        把"1234-5678"放到EAX
  00480797   .  8B55 F8       mov edx,dword ptr ss:[ebp-8]          把--堆栈ss:[0012F3F8]=00C59EF4, (ASCII "2498-2498")--放到EDX
  0048079A   .  E8 C10AF8FF   call <jmp.&rtl70.System::LStrCmp>     比较EAX,EDX中的字符串,相等则跳向成功!
  0048079F   .  0F84 8A000000 je Registra.0048082F
 
  我们这个时候就奇怪了,dword ptr ss:[ebp-8]中的数据是哪里来的呢?
  我们想到开始时候对用户名处理的那一段代码中的可疑CALL,于是看到了:
 
  00480562   .  8B85 E4FEFFFF mov eax,dword ptr ss:[ebp-11C]
  00480568   .  8D95 E8FEFFFF lea edx,dword ptr ss:[ebp-118]
  0048056E   .  E8 5517F8FF   call <jmp.&rtl70.Sysutils::LowerCase>
  00480573   .  8B85 E8FEFFFF mov eax,dword ptr ss:[ebp-118]
  00480579   .  8D55 F8       lea edx,dword ptr ss:[ebp-8]   <------哈哈,原来那里面的数据是从这里来的!           
  0048057C   .  E8 C7E7FFFF   call Registra.0047ED48             ; 对用户名进行一系列操作后,出现了这个CALL,很可疑啊
  00480581   .  8D95 D4FEFFFF lea edx,dword ptr ss:[ebp-12C]
  00480587   .  8B45 FC       mov eax,dword ptr ss:[ebp-4]
  0048058A   .  8B80 A0030000 mov eax,dword ptr ds:[eax+3A0]
  00480590   .  E8 EF1AF9FF   call Registra.00412084             ;这个也很可疑
  00480595   .  8B85 D4FEFFFF mov eax,dword ptr ss:[ebp-12C]
  进入第一个可疑CALL;来到
  0047ED48  /$  55            push ebp
  0047ED49  |.  8BEC          mov ebp,esp
  0047ED4B  |.  B9 04000000   mov ecx,4
  ……省略一段代码....
  0047EDB6  |.  E8 2D24F8FF   call <jmp.&rtl70.System::LStrLAsg>
  0047EDBB  |>  8D45 F8       lea eax,[local.2]
  0047EDBE  |.  50            push eax
  0047EDBF  |.  6A 00         push 0
  0047EDC1  |.  8B45 FC       mov eax,[local.1]
  0047EDC4  |.  50            push eax
  0047EDC5  |.  E8 F6FEFFFF   call <jmp.&Routine.HandleDec>  此句后出现"2498A77F5BB5244F432173FBF065B7FF0",这又是什么东东?注意到调用了Routine.HandleDec函数
  ……
  在它的安装文件里看见了Routine.dll,PEID插件KANAL V2.9查到算法
  DES [pbox] [char] :: 0000296C :: 0040416C
  MD5 :: 000017A9 :: 004023A9
  哈哈,那十有八九是计算了用户名的MD5,用自己的MD5计算器验证,果然是的!
  跟着看0047EDC5  |.  E8 F6FEFFFF   call <jmp.&Routine.HandleDec>下面的代码:
  0047EDCA  |.  8BD0          mov edx,eax
  0047EDCC  |.  8D45 E4       lea eax,[local.7]
  0047EDCF  |.  E8 3C24F8FF   call <jmp.&rtl70.System::LStrFromPChar> 
  0047EDD4  |.  8B45 E4       mov eax,[local.7]
  0047EDD7  |.  B9 04000000   mov ecx,4
  0047EDDC  |.  BA 01000000   mov edx,1
  0047EDE1  |.  E8 9A24F8FF   call <jmp.&rtl70.System::LStrCopy>
  0047EDE6  |.  8D45 F4       lea eax,[local.3]
  0047EDE9  |.  50            push eax
  0047EDEA  |.  6A 00         push 0
  0047EDEC  |.  8B45 F0       mov eax,[local.4]
  0047EDEF  |.  50            push eax
  0047EDF0  |.  E8 CBFEFFFF   call <jmp.&Routine.HandleDec>
  0047EDF5  |.  8BD0          mov edx,eax
  0047EDF7  |.  8D45 E0       lea eax,[local.8]
  0047EDFA  |.  E8 1124F8FF   call <jmp.&rtl70.System::LStrFromPChar>;所有字母转换为大写
  0047EDFF  |.  8B45 E0       mov eax,[local.8]
  0047EE02  |.  B9 04000000   mov ecx,4       ----System::LStrCopy的参数
  0047EE07  |.  BA 01000000   mov edx,1       ----System::LStrCopy的参数
  0047EE0C  |.  E8 6F24F8FF   call <jmp.&rtl70.System::LStrCopy> ;由参数易知,它复制了"2498A77F5BB5244F432173FBF065B7FF0"的前四位字符
  0047EE11  |.  FF75 F8       push [local.2]
  0047EE14  |.  68 88EE4700   push Registra.0047EE88                             ;  -  <------看到这个'-'了?
  0047EE19  |.  FF75 F4       push [local.3]
  0047EE1C  |.  8D45 DC       lea eax,[local.9]
  0047EE1F  |.  BA 03000000   mov edx,3
  0047EE24  |.  E8 2F24F8FF   call <jmp.&rtl70.System::LStrCatN>      将字符串前四位用'-'重复连接,即----> "2498-2498"
  0047EE29  |.  8B45 DC       mov eax,[local.9]
  0047EE2C  |.  8BD3          mov edx,ebx
  0047EE2E  |.  E8 8D2EF8FF   call <jmp.&rtl70.Sysutils::UpperCase>  ;字母转换为大写
  0047EE33  |.  33C0          xor eax,eax
  到此,算法就分析完了。
  算法总结:
  计算用户名的MD5,用'-'重复连接MD5前四位,即XXXX-XXXX的形式,后面10位注册码随便写。
  注册机源码就不放上来了,除了MD5的代码难写之外,其他写出来很简单。
 
--------------------------------------------------------------------------------
【经验总结】
  对于初学者,我想说,不要退缩,分析软件时要细心,要有耐心,能持之以恒,那么你进步一定很快。
 
--------------------------------------------------------------------------------
【版权声明】: 转载请注明作者并保持文章的完整, 谢谢!
 
                                                       2012年08月03日 下午11:15:41