Advanced SystemCare离线算法分析
程序员文章站
2022-09-30 09:47:03
【文章作者】: 红绡枫叶
【作者邮箱】: 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
【作者邮箱】: 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