【文章标题】: History Sweeper 2.82破解
【文章作者】: wadic
【作者邮箱】: wadicracke@126.com
【作者主页】: 无
【作者QQ号】: 无
【软件名称】: History Sweeper 2.82
【软件大小】: 333KB
【下载地址】: http://www.itcompany.com/sweeper.htm
【加壳方式】: 无壳
【保护方式】: 注册表检测
【编写语言】: Microsoft Visual C++ 6.0
【使用工具】: PEiD、OD
【操作平台】: XP
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
【软件介绍】: History Sweeper 是一个可以清除你计算机中无用文件和历史记录的一个非常小巧的软件,如注册表无用项,文档、运行、查找记录。清理的非常快速、安全。
--------------------------------------------------------------------------------
【详细过程】
1、信息收集:
未注册版本有15天使用限制,将日期改后,软件无法使用。
没有注册码输入框。
查壳:Microsoft Visual C++ 6.0,无壳。
加密算法:MD5 :: 000088D9 :: 004088D9
2、破解:
(1)OD载入,查超级字串参考,找到:
Ultra String Reference, 条目 184
Address=0040C1F3
Disassembly=push 00423AD4
Text String=history sweeper (%d day(s) left) ;这是未注册版在标题条上显示的信息。
Ultra String Reference, 条目 185
Address=0040C382
Disassembly=mov edi, 00423AB4
Text String=history sweeper (registered)
(2)来到0040C382 > \BF B43A4200 mov edi, 00423AB4 ; history sweeper (registered)
发现跳转来自0040C150,看看:
0040C130 . 8D4C24 10 lea ecx, dword ptr [esp+10]
0040C134 . C68424 FC0200>mov byte ptr [esp+2FC], 2
0040C13C . E8 83DE0000 call <jmp.&MFC42.#800_CString::~CString>
0040C141 . 68 F83A4200 push 00423AF8 ; xywy
0040C146 . E8 0594FFFF call 00405550
0040C14B . 83C4 04 add esp, 4
0040C14E . 84C0 test al, al
0040C150 . 0F85 2C020000 jnz 0040C382 ;关键跳
(3)初步判断CALL 405550为关键CALL,在40C141处下断,F9运行。
F7跟进CALL 405550
...
0040556B |. 68 0C334200 push 0042330C ; software\classes\{b3cb56e0-cbdb-22ca-15bf-8858-00aa0070fd48}
00405570 |. 8D4C24 04 lea ecx, dword ptr [esp+4]
00405574 |. E8 934A0100 call <jmp.&MFC42.#537_CString::CString>
00405579 |. 8D4424 00 lea eax, dword ptr [esp]
0040557D |. 68 01000080 push 80000001
...
///这一段就是读取注册表了,定位主键后,就应该是打开子项了:
004055F9 |. 51 push ecx
004055FA |. 52 push edx
004055FB |. 50 push eax
004055FC |. 8D8C24 A80000>lea ecx, dword ptr [esp+A8]
00405603 |. C74424 10 000>mov dword ptr [esp+10], 400
0040560B |. E8 30570000 call 0040AD40
//F7跟进,
...
0040AD57 |. FF15 18D04100 call dword ptr [<&ADVAPI32.RegQueryValueE>; \RegQueryValueExA 读子项
0040AD5D |. 85C0 test eax, eax
0040AD5F |. 0F94C0 sete al ;没有子项就是假
0040AD62 \. C2 0C00 retn 0C
//此时看堆栈窗:
0012F4E4 0000005C \... |hKey = 5C
0012F4E8 00376E48 Hn7. |ValueName = "Data1"
0012F4EC 00000000 .... |Reserved = NULL
0012F4F0 00000000 .... |pValueType = NULL
0012F4F4 0012F7F0 瘅. |Buffer = 0012F7F0
0012F4F8 0012F510 ?. \pBufSize = 0012F510
//要读一个Data1的子项。打开注册表看看,发现没有这个子项,如果没有,sete al就是假了。
//手动添加一个字串型子项,值就随意给吧,我给的是"123456"
//F8走到返回
00405610 |. 84C0 test al, al
00405612 |. 75 2E jnz short 00405642 ;如果没有Data1子项,没有跳,就是未注册版本了。
00405614 |. 8D8C24 9C0000>lea ecx, dword ptr [esp+9C]
0040561B |. C78424 EC0600>mov dword ptr [esp+6EC], -1
00405626 |. E8 E5560000 call 0040AD10
0040562B |. 32C0 xor al, al
0040562D |. 8B8C24 E40600>mov ecx, dword ptr [esp+6E4]
00405634 |. 64:890D 00000>mov dword ptr fs:[0], ecx
0040563B |. 81C4 F0060000 add esp, 6F0
00405641 |. C3 retn ;没跳在这里返回,al清0了
00405642 |> 53 push ebx
00405643 |. 8D4C24 0C lea ecx, dword ptr [esp+C]
00405647 |. E8 643C0000 call 004092B0
//F7跟进这个CALL,我们看到了MD5的四个常数:
00408720 /$ 8B4424 04 mov eax, dword ptr [esp+4]
00408724 |. 33C9 xor ecx, ecx
00408726 |. 8948 14 mov dword ptr [eax+14], ecx
00408729 |. 8948 10 mov dword ptr [eax+10], ecx
0040872C |. C700 01234567 mov dword ptr [eax], 67452301
00408732 |. C740 04 89ABC>mov dword ptr [eax+4], EFCDAB89
00408739 |. C740 08 FEDCB>mov dword ptr [eax+8], 98BADCFE
00408740 |. C740 0C 76543>mov dword ptr [eax+C], 10325476
00408747 \. C3 retn
0040564C |. 8B9424 F80600>mov edx, dword ptr [esp+6F8]
00405653 |. 8D8C24 E80200>lea ecx, dword ptr [esp+2E8]
0040565A |. 51 push ecx ; /Arg2
0040565B |. 52 push edx ; |Arg1
0040565C |. 8D4C24 14 lea ecx, dword ptr [esp+14] ; |
00405660 |. C68424 F80600>mov byte ptr [esp+6F8], 3 ; |
00405668 |. E8 633F0000 call 004095D0 ; \sweeper.004095D0
//看来CALL 4095D0就是MD5运算了,走到这里,堆栈窗如下:
0012F500 00423AF8 ?B. |Arg1 = 00423AF8 ASCII "XYWY"
0012F504 0012F7F0 瘅. \Arg2 = 0012F7F0 ASCII "123456"
//参数一是常数"XYWY",参数二是刚建的假值,MD5运算需要两个字串吗?难道是合并后再作运算?抖擞精神,咬把牙,跟进:)
004095D0 /$ 8B15 8C364200 mov edx, dword ptr [42368C] ; sweeper.00423698
004095D6 |. 83EC 40 sub esp, 40
004095D9 |. 33C0 xor eax, eax
004095DB |. 56 push esi
004095DC |. 8BF1 mov esi, ecx
004095DE |. 57 push edi
004095DF |. 8BFA mov edi, edx
004095E1 |. 83C9 FF or ecx, FFFFFFFF
004095E4 |. F2:AE repne scas byte ptr es:[edi]
004095E6 |. A1 90364200 mov eax, dword ptr [423690]
004095EB |. 8BFA mov edi, edx
004095ED |. F7D1 not ecx
004095EF |. 49 dec ecx
004095F0 |. 8B15 94364200 mov edx, dword ptr [423694]
004095F6 |. 89440C 08 mov dword ptr [esp+ecx+8], eax
004095FA |. 83C9 FF or ecx, FFFFFFFF
004095FD |. 33C0 xor eax, eax
004095FF |. F2:AE repne scas byte ptr es:[edi]
00409601 |. 8B4424 4C mov eax, dword ptr [esp+4C]
00409605 |. F7D1 not ecx
00409607 |. 49 dec ecx
00409608 |. 50 push eax
00409609 |. 89540C 10 mov dword ptr [esp+ecx+10], edx
0040960D |. 8BCE mov ecx, esi
0040960F |. E8 FCFCFFFF call 00409310
00409614 |. 8BCE mov ecx, esi
00409616 |. E8 15FDFFFF call 00409330
0040961B |. 8B7C24 50 mov edi, dword ptr [esp+50]
0040961F |. B9 08000000 mov ecx, 8
00409624 |. 8BF0 mov esi, eax
00409626 |. 33D2 xor edx, edx
00409628 |. F3:A7 repe cmps dword ptr es:[edi], dword ptr [>
0040962A |. 5F pop edi
0040962B |. 5E pop esi
0040962C |. 0F94C0 sete al
0040962F |. 83C4 40 add esp, 40
00409632 \. C2 0800 retn 8
//大致一看,并不长,这里有几个关键点:
1、004095E1 |. 83C9 FF or ecx, FFFFFFFF ;串扫描前奏,得到串长
004095E4 |. F2:AE repne scas byte ptr es:[edi] ;扫描串
2、两个CALL
3、00409628 |. F3:A7 repe cmps dword ptr es:[edi], dword ptr [> ;串比较
4、0040962C |. 0F94C0 sete al ;关键!真与假,注册与未注册...
(4)这两个CALL就省略了,我粗跟了一下,前一个CALL做些MD5运算前的准备,后一个CALL非常冗长,N多的xor/or/not...我是大段大段的F4过。
有一点很重要,我跟的时候,发现"123456"这个假码并没有参与运算!
说明程序只是将XYWY进行了运算,得到的结果再和假码"123456"比较而已。
这样就好办了,直接在串比较的409628处下断,F9过来,嘿嘿,EAX和ESI同时指向一串字符,而EDI则指向了假码:
EAX 0012F529 ASCII "c18da8dc4814f8fc7089fe2e7042b3fd"
ECX 00000008
EDX 00000000
EBX 00426700 sweeper.00426700
ESP 0012F4B4
EBP 00000000
ESI 0012F529 ASCII "c18da8dc4814f8fc7089fe2e7042b3fd"
EDI 0012F7F0 ASCII "123456"
//至此,不管MD5运算多么复杂,都不用管了,来到堆栈12F7F0处,改吧...
//懒得改的话就把sete al改成mov al,1吧,让al带着1一路返回...
3、结论:
在HKEY_CURRENT_USER\Software\Classes\{B3CB56E0-CBDB-22CA-15BF-8858-00AA0070FD48}下新建子项Data1,值为c18da8dc4814f8fc7089fe2e7042b3fd,即可成为正式版。
4、一点体会:刚拿到这个软件时,发现竟没有注册码输入框,有点不知从何入手。幸好在字串参考中找到了点头绪,才能很快定位到关键处。
如果没有这点提示呢?嘿嘿,不知怎么办了,能想到的办法是从开始一步步跟了...
本人新手,第一次写破文,失误之处,还请指教,谢谢。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!