爆破多功能时钟日历V2.5(菜鸟第一篇,高手可跳过)
【使用工具】 ollydbg,DeDe3.5
【破解平台】 WinXP
【软件名称】 多功能时钟日历V2.5
【软件主页】 http://www.magic2008.com/
【软件介绍】 <本程序为绿色软件>多功能时钟日历是一个集:时间、日历、节日节气、事务记录、自动提醒、计划制定、自动关机、资料查询、便签记录、桌面提醒、桌面日历等等功能构成的一个软件,其实她已经完全超越了多功能时钟日历软件的概念、逐渐变成了一个强大的多功能事物记录、查询、提醒为一体的,帮助你轻松进行工作、娱乐的得力助手。你会发现她渐渐的成为了你电脑中不可缺少的朋友
【破解原因】 1.快到我表妹的生日了,想确认一下时间,于是下了一个日历。说是破解版的。下了下来后,却有Nag。感觉功能很好,比较喜欢它。但它是以你起动的次数做为让你等的时间(好像是0.1秒当一次吧),每次起动都要确定,而且等的时间越来起长。所以。。。嘿,谁让咱爱干这一行的呢,拿起家伙,爆了它。关于注册的钮是灰的,不知它有没有这个功能,只好先爆了。等以后再看看,如果有的话,再看看它的算法。2.在坛子里泡了也有大半年了,不能光吸收精华,也要做些什么吧。这个还有一定的难度(对菜鸟来说),就写成破文吧,算自己发的第一篇吧,做为对看雪的支持。废话多说,因为我目标是:没有蛀牙!(嘿,说错了,应该是:让最菜的菜鸟都能看懂!所以高手可以跳过。希望对菜菜们有帮助,否则我可是白浪费了不少时间。)难免有不之处,敬请指出!
【破解过程】
1.先查壳。用PEid测出主程序用ASPack 2.12 -> Alexey Solodovnikov加了壳。可以手动(很简单),也可以用AspackDie来脱。脱完后,再测一下,得知是Borland Delphi 4.0 - 5.0,这就应该用DeDe了。但这个程序有AntiDeDe,没加载完就让退出。有时被破软件没退出,则stream read error。改用exescope也看不到对话框。只有用OD载入,也看到有用的字符串,只有没具体目标的调来调去,乱下断点。因此花了半天,也没弄出什么。回宿舍,看了看第二版,才知改DeDe的名就可以躲过Anti,所以改DeDe为CC(任意)。这才能载入。
2.用DeDe载入。载入后,我没选extended analisys。然后选 窗体 ,从下面框中双击TFormR,弹出Nag框和DFM Inspector窗口。从DFM Inspector中点击那些类,就会从Nag框中得到提示是选中的哪个。以闪烁几次表示。从而得知有用的Label和Button。也可以用鼠标指向Nag框中,DFM Inspector中也会改变。从而得到知:立即注册--Button1,输入注册码--Button2,运行的第几次--Label9,同意--Button4,退出--Button5。
3.再选 过程 ,选中TFormR那个类。右边的事件口就会显示对应的事件。可以双击事件,得到汇编代。记下有用的地址。如:Timer1Timer的是00561C84,Timer2Timer的是00561CBC,同意 的是00561C6C。其它的都可以知道。记下地址后,再来到下一步。
4.用OD载入。在你得到的地址处下断点。例如对于Timer1Timer的地址,用Ctrl+G,输入00561C84,点确定,来到00561C84处,按F2下断。
下面是在OD中找到对应处:
00561C56 8BC0 mov eax,eax
00561C58 . 53 push ebx
00561C59 . 8BDA mov ebx,edx
00561C5B . 8BD3 mov edx,ebx
00561C5D . E8 1AE9EEFF call unpacked.0045057C
00561C62 . E8 ED67EAFF call <jmp.&user32.GetDesktopWindow> ; [GetDesktopWindow
00561C67 . 8943 1C mov dword ptr ds:[ebx+1C],eax
00561C6A . 5B pop ebx
00561C6B . C3 retn
00561C6C . A1 70245900 mov eax,dword ptr ds:[592470] ; 退出
00561C71 . 8B00 mov eax,dword ptr ds:[eax]
00561C73 . E8 6406EFFF call unpacked.004522DC
00561C78 . C3 retn
00561C79 8D40 00 lea eax,dword ptr ds:[eax] ; 同意
00561C7C . E8 5B06EFFF call unpacked.004522DC
00561C81 . C3 retn
00561C82 8BC0 mov eax,eax
00561C84 . 53 push ebx ; timer1
00561C85 . 8BD8 mov ebx,eax
00561C87 . B2 01 mov dl,1
00561C89 . 8B83 18030000 mov eax,dword ptr ds:[ebx+318]
00561C8F . 8B08 mov ecx,dword ptr ds:[eax]
00561C91 . FF51 5C call dword ptr ds:[ecx+5C]
00561C94 . 33D2 xor edx,edx
00561C96 . 8B83 20030000 mov eax,dword ptr ds:[ebx+320]
00561C9C . E8 7B78EFFF call unpacked.0045951C
00561CA1 . 5B pop ebx
00561CA2 . C3 retn
00561CA3 90 nop
00561CA4 . 33C0 xor eax,eax
00561CA6 . A3 684E5900 mov dword ptr ds:[594E68],eax
00561CAB . C3 retn
00561CAC . A1 AC235900 mov eax,dword ptr ds:[5923AC] ; 输入注册码
00561CB1 . 8B00 mov eax,dword ptr ds:[eax]
00561CB3 . 8B10 mov edx,dword ptr ds:[eax]
00561CB5 . FF92 D8000000 call dword ptr ds:[edx+D8]
00561CBB . C3 retn
00561CBC 55 push ebp ; timer2
00561CBD 8BEC mov ebp,esp
00561CBF |. 6A 00 push 0
00561CC1 |. 53 push ebx
00561CC2 |. 8BD8 mov ebx,eax
00561CC4 |. 33C0 xor eax,eax
00561CC6 |. 55 push ebp
00561CC7 |. 68 7F1D5600 push unpacked.00561D7F
00561CCC |. 64:FF30 push dword ptr fs:[eax]
00561CCF |. 64:8920 mov dword ptr fs:[eax],esp
00561CD2 |. 813D 684E5900 C>cmp dword ptr ds:[594E68],0C8
00561CDC |. 7D 17 jge short unpacked.00561CF5
00561CDE |. A1 684E5900 mov eax,dword ptr ds:[594E68]
00561CE3 |. B9 98080000 mov ecx,898
00561CE8 |. 99 cdq
00561CE9 |. F7F9 idiv ecx
00561CEB |. 85C0 test eax,eax
00561CED |. 75 06 jnz short unpacked.00561CF5
然后F9运行。来到timer2断点处。Nag框还没有弹出。再F9运行,出Nag框。说明在Nag这次调出。然后Ctrl+F2重来。运行一次。然后再慢慢用F7或F8来找。如果F8过不了,就用F7进入。对于这一步要有耐心,我都不知按了多少次Ctrl+F2。如果你对API函数很了解,知道程序用ShowWindow来显示,你可以直接下断在那。用bp ShowWindow来下断。不过我用的是bp CreateWindowExA。断是断下了,但是不断地retn,一直没有找到关键的地方。这是我花了很长时间的一个原因。最后你会来到以下代码处。
00451C74 55 push ebp
00451C75 . 8BEC mov ebp,esp
00451C77 . 83C4 F8 add esp,-8
00451C7A . 53 push ebx
00451C7B . 56 push esi
00451C7C . 57 push edi
00451C7D . 33C9 xor ecx,ecx
00451C7F . 894D F8 mov dword ptr ss:[ebp-8],ecx
00451C82 . 8945 FC mov dword ptr ss:[ebp-4],eax
00451C85 . 33C0 xor eax,eax
........................................................
00451FB3 > \8B45 FC mov eax,dword ptr ss:[ebp-4] ; here
00451FB6 . C680 18020000 0>mov byte ptr ds:[eax+218],0
00451FBD . 8B45 FC mov eax,dword ptr ss:[ebp-4]
00451FC0 80B8 17020000 0>cmp byte ptr ds:[eax+217],1
00451FC7 0F85 B5000000 jnz unpacked.00452082 跳后就会出Nag
00451FCD 8B45 FC mov eax,dword ptr ss:[ebp-4]
00451FD0 . 80B8 13020000 0>cmp byte ptr ds:[eax+213],2
00451FD7 . 75 36 jnz short unpacked.0045200F
00451FD9 . 6A 00 push 0
00451FDB . 8B45 FC mov eax,dword ptr ss:[ebp-4]
00451FDE . E8 3DB2FEFF call unpacked.0043D220
00451FE3 . 50 push eax ; |wParam
00451FE4 . 68 23020000 push 223 ; |Message = WM_MDIRESTORE
00451FE9 . A1 D4375900 mov eax,dword ptr ds:[5937D4] ; |
00451FEE . 8B40 38 mov eax,dword ptr ds:[eax+38] ; |
00451FF1 . 8B80 3C020000 mov eax,dword ptr ds:[eax+23C] ; |
00451FF7 . 50 push eax ; |hWnd
00451FF8 . E8 0767FBFF call <jmp.&user32.SendMessageA> ; \SendMessageA
00451FFD . 6A 03 push 3
00451FFF . 8B45 FC mov eax,dword ptr ss:[ebp-4]
00452002 . E8 19B2FEFF call unpacked.0043D220
00452007 . 50 push eax ; |hWnd
00452008 . E8 D767FBFF call <jmp.&user32.ShowWindow> ; \ShowWindow
0045200D . EB 51 jmp short unpacked.00452060
0045200F > 8B45 FC mov eax,dword ptr ss:[ebp-4]
00452012 . 0FB680 13020000 movzx eax,byte ptr ds:[eax+213]
00452019 . 8B0485 9C5A5800 mov eax,dword ptr ds:[eax*4+585A9C]
00452020 . 50 push eax
00452021 . 8B45 FC mov eax,dword ptr ss:[ebp-4]
00452024 . E8 F7B1FEFF call unpacked.0043D220
00452029 . 50 push eax ; |hWnd
0045202A . E8 B567FBFF call <jmp.&user32.ShowWindow> ; \ShowWindow
0045202F . 8B45 FC mov eax,dword ptr ss:[ebp-4]
00452032 . 8B40 38 mov eax,dword ptr ds:[eax+38]
00452035 . 8B55 FC mov edx,dword ptr ss:[ebp-4]
00452038 . 8B52 3C mov edx,dword ptr ds:[edx+3C]
0045203B . C1E2 10 shl edx,10
0045203E . 0BC2 or eax,edx
00452040 . 50 push eax
00452041 . 6A 00 push 0
00452043 . 6A 05 push 5
00452045 . 8B45 FC mov eax,dword ptr ss:[ebp-4]
00452048 . E8 D3B1FEFF call unpacked.0043D220
0045204D . 50 push eax ; |hWnd
0045204E . 68 14834000 push <jmp.&user32.DefMDIChildProcA> ; |PrevProc = unpacked.00408314
00452053 . E8 4462FBFF call <jmp.&user32.CallWindowProcA> ; \CallWindowProcA
00452058 . 8B45 FC mov eax,dword ptr ss:[ebp-4]
0045205B . E8 1052FEFF call unpacked.00437270
00452060 > 6A 00 push 0 ; /lParam = 0
00452062 . 6A 00 push 0 ; |wParam = 0
00452064 . 68 34020000 push 234 ; |Message = WM_MDIREFRESHMENU
00452069 . A1 D4375900 mov eax,dword ptr ds:[5937D4] ; |
0045206E . 8B40 38 mov eax,dword ptr ds:[eax+38] ; |
00452071 . 8B80 3C020000 mov eax,dword ptr ds:[eax+23C] ; |
00452077 . 50 push eax ; |hWnd
00452078 . E8 8766FBFF call <jmp.&user32.SendMessageA> ; \SendMessageA
0045207D . E9 2A010000 jmp unpacked.004521AC
00452082 > 8B45 FC mov eax,dword ptr ss:[ebp-4] 从00451FC7跳来
00452085 . 0FB680 13020000 movzx eax,byte ptr ds:[eax+213]
0045208C . 8B0485 9C5A5800 mov eax,dword ptr ds:[eax*4+585A9C]
00452093 . 50 push eax
00452094 . 8B45 FC mov eax,dword ptr ss:[ebp-4]
00452097 . E8 84B1FEFF call unpacked.0043D220 进去看看
0045209C . 50 push eax eax为窗口句柄
0045209D . E8 4267FBFF call <jmp.&user32.ShowWindow> 经过这个,Nag调出
004520A2 . E9 05010000 jmp unpacked.004521AC 然后跳到下面
.................................................
004521AC > \33C0 xor eax,eax 分析上面特点知,
004521AE . 5A pop edx 调用showwindow后
004521AF . 59 pop ecx 都来到这里
004521B0 . 59 pop ecx
004521B1 . 64:8910 mov dword ptr fs:[eax],edx
004521B4 . 68 CB214500 push unpacked.004521CB
004521B9 > 8B45 FC mov eax,dword ptr ss:[ebp-4]
004521BC . 80A0 CC020000 F>and byte ptr ds:[eax+2CC],0FB
004521C3 . C3 retn ; RET used as a jump to 004521CB
知道从哪调出Nag的,Nop掉行不行?如果你不想要这个软件的其它功能的话,好像也可以。经过试验,这个软件的其它功能也用这个Call调用的。(怎么试验?运行后,点其它的窗口,发现没有反应。)eax的句柄是怎样产生的?进入call unpacked.0043D220看看。进入后,没看到什么有用的。看看这个eax的值是什么?记下来后,再次重运行,再来到这里。eax的值改变了,但仍指向Nag框。总有个不变的吧!要不怎样固定句柄?所以,再次进入call unpacked.0043D220:
0043D220 /$ 53 push ebx
0043D221 |. 8BD8 mov ebx,eax
0043D223 |. 8BC3 mov eax,ebx
0043D225 |. E8 D2FFFFFF call unpacked.0043D1FC
0043D22A 8B83 4C010000 mov eax,dword ptr ds:[ebx+14C]
0043D230 5B pop ebx
0043D231 C3 retn
从上面知由mov eax,dword ptr ds:[ebx+14C]把值给eax。记下ebx的值。再次运行,对于弹出Nag时ebx的值不变。而在call unpacked.0043D220前,是从00451FC7跳过来的,到那里去看看。
00451FB3 > \8B45 FC mov eax,dword ptr ss:[ebp-4] ; here
00451FB6 . C680 18020000 0>mov byte ptr ds:[eax+218],0
00451FBD . 8B45 FC mov eax,dword ptr ss:[ebp-4]
00451FC0 80B8 17020000 0>cmp byte ptr ds:[eax+217],1
00451FC7 0F85 B5000000 jnz unpacked.00452082 跳后出Nag
00451FCD 8B45 FC mov eax,dword ptr ss:[ebp-4]
00451FD0 . 80B8 13020000 0>cmp byte ptr ds:[eax+213],2
00451FD7 . 75 36 jnz short unpacked.0045200F
多次试验,对于调出不同窗口时,00451FC7句也跳,也就是说跳时不一定就为Nag口。但eax的值是不同的,但这个eax与0043D22A处的ebx值相同。猜测这就是放句柄的地方。就这样再试试。找了一个一堆0的地方,自己写了些代码来判断。我找的是00581815处。(自己笨,没找到更好的办法。时间有限,也没有继续深入。)代码自己会改吧?在代码区双击或按空格键就会弹出汇编框,打入代码就可以。
00451FB3 > \8B45 FC mov eax,dword ptr ss:[ebp-4] ; here
00451FB6 . C680 18020000 0>mov byte ptr ds:[eax+218],0
00451FBD . 8B45 FC mov eax,dword ptr ss:[ebp-4]
00451FC0 3D 0080B700 cmp eax,0B78000 将原先的改为这个
00451FC5 0F84 E1010000 je ccc.004521AC 相同就跳到结束处
00451FCB E9 45F81200 jmp ccc.00581815 不同,把原来的代 码补上。 0B78000是Nag句柄 的地址吧
00581815 80B8 27010000 0>cmp byte ptr ds:[eax+127],1 补上原来的代码
0058181C ^ 0F85 6008EDFF jnz ccc.00452082
00581822 8B45 FC mov eax,dword ptr ss:[ebp-4]
00581825 ^ E9 A607EDFF jmp ccc.00451FD0 跳回继续执行
这样改完,在代码区选中几行,点右键->复制到可执行文件->全部修正,然后在弹出的另一个框中点右键->保存文件。保存好后,运行,成功了,没有Nag了。可知猜的也许是对的。这样就算把它给爆破了。到现在我还没发现有什么问题。有可能还有问题,但现在还没发现,发现时再说吧。费话说了不少,不知你看懂了吗。第一次写,水平有限,见谅。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)