【破解作者】 clide2000[DFCG][OCN]
【作者邮箱】 54arma@sina.com
【作者主页】 www.chinadfcg.com
【使用工具】 Ollydbg;LoadPe;ImportREC;WinHex;topo12
【破解平台】 Win9x/NT/2000/XP
【软件名称】 家庭VCD相册制作系统 标准版 2.0
【下载地址】 http://www.jcok.com/soft/VCDAlbumDIYB.exe
【软件简介】 《家庭VCD相册制作系统》是制作VCD相册的最佳选择。可轻松将您喜欢的图片,数码相机拍出的照片和扫描的相片进行数码变换处理,配上音乐、图象特效、文字等,在数分钟之内制造出一流的专业效果的家庭VCD数码相册。
【软件大小】 2.39M
【加壳方式】 未知壳
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
【破解内容】
一寻找OEP和dump:
经调试分析,发现此壳会先申请一段内存空间,然后把部分代码解压到新申请的空间,而且以后会经常调用。所以我们要在原文件尾部新建一个大小一样的区段,用于存放这部分代码:
1 寻找申请内存空间的大小:
首先设置OD忽略所在异常。OD载入后,停在:
006DE000 > E8 AA000000 call VCDAlbum.006DE0AF
006DE005 2D E02D0000 sub eax, 2DE0
006DE00A 0000 add byte ptr ds:[eax], al
006DE00C 0000 add byte ptr ds:[eax], al
006DE00E 0000 add byte ptr ds:[eax], al
006DE010 003D E02D002D add byte ptr ds:[2D002DE0], bh
006DE016 E0 2D loopdne short VCDAlbum.006DE045
006DE018 0000 add byte ptr ds:[eax], al
下bp VirtualAlloc断点,f9运行,会中断在:
77E5AC72 > 55 push ebp ; VCDAlbum.<ModuleEntryPoint>
77E5AC73 8BEC mov ebp, esp
77E5AC75 FF75 14 push dword ptr ss:[ebp+14]
77E5AC78 FF75 10 push dword ptr ss:[ebp+10]
77E5AC7B FF75 0C push dword ptr ss:[ebp+C]
77E5AC7E FF75 08 push dword ptr ss:[ebp+8]
77E5AC81 6A FF push -1
77E5AC83 E8 9CFFFFFF call kernel32.VirtualAllocEx
77E5AC88 5D pop ebp
77E5AC89 C2 1000 retn 10
看看现在的堆栈内容,记住加****一行中的Size的大小,然后Ctrl+f9后,eax中,放的就是申请到的内存的起始地址了,即370000:
0012FFB0 006DE0E3 /CALL to VirtualAlloc from VCDAlbum.006DE0DD
0012FFB4 00000000 |Address = NULL
0012FFB8 000068B0 |Size = 68B0 (26800.) ****************************
0012FFBC 00001000 |AllocationType = MEM_COMMIT
0012FFC0 00000004 \Protect = PAGE_READWRITE
此时我们记住68b0H这个十六进制数什么,就可以先关闭OD加载的进程
2,给原程序增加新的区段(就是加个新区段,用来存放原来放入370000段的代码)
1)用WinHew之类的工具先在程序的尾部增加7000H的空间(原文件大小是B41FF,增加7000H(十进制应该是28672)空间后大小为BB1FF.
2)用topo12.exe工具增加一个新的区段,大小为28672H。成功后信息如下:
28672 bytes added at:
-memory address: 006E1000h
-file offset: 000b4200h
不放心的话,可以用loadPe载入刚修改完的程序看看
正常的话会看到最下面多出一个名为.topo0的区段,其具体信息是(只列出了新加段的信息)
Name VOffset VSize ROffset RSize Flags
.topo0 002E1000 00007000 000B4200 00007000 E0000020
3好,下面可以寻找OEP和dump了
1)OD重新加载这个程序
下bp VirtualAlloc断点,f9运行,会中断在:
77E5AC72 > 55 push ebp ; VCDAlbum.<ModuleEntryPoint>
77E5AC73 8BEC mov ebp, esp
77E5AC75 FF75 14 push dword ptr ss:[ebp+14]
77E5AC78 FF75 10 push dword ptr ss:[ebp+10]
77E5AC7B FF75 0C push dword ptr ss:[ebp+C]
77E5AC7E FF75 08 push dword ptr ss:[ebp+8]
77E5AC81 6A FF push -1
77E5AC83 E8 9CFFFFFF call kernel32.VirtualAllocEx
77E5AC88 5D pop ebp
77E5AC89 C2 1000 retn 10 ;直接在这一行上按F4
取消断点,然后直接在 77E5AC89一行上按F4,之后,把eax中的00370000修改成006E1000
下bp VirtualFree 中断两次后,Ctrl+f9返回到这:
00372FBD 5B pop ebx
00372FBE 83C3 0C add ebx, 0C
00372FC1 ^ EB B3 jmp short 00372F76
00372FC3 8B85 B8020000 mov eax, dword ptr ss:[ebp+2B8]
00372FC9 0BC0 or eax, eax
00372FCB 0F85 81000000 jnz 00373052
00372FD1 8BBD C0020000 mov edi, dword ptr ss:[ebp+2C0]
清除断点:现在Ctrl+s搜索:
mov edx, dword ptr ds:[edx+4]
mov dword ptr ds:[edx+50], 1000
mov dword ptr ss:[ebp+258], ebp
mov eax, dword ptr ss:[ebp+2C8]
add eax, dword ptr ss:[ebp+2B4]
jmp eax
找到:
00373126 8B52 04 mov edx, dword ptr ds:[edx+4]
00373129 C742 50 00100000 mov dword ptr ds:[edx+50], 1000
00373130 89AD 58020000 mov dword ptr ss:[ebp+258], ebp
00373136 8B85 C8020000 mov eax, dword ptr ss:[ebp+2C8]
0037313C 0385 B4020000 add eax, dword ptr ss:[ebp+2B4]
00373142 - FFE0 jmp eax ;在这里F2下断点,中断后,eax中就是OEP
在上面00373142 - FFE0 jmp eax中断后,按一下F7后来到OEP
0050BE3C 55 push ebp ;这里就是OEP了
0050BE3D 8BEC mov ebp, esp
0050BE3F 83C4 F0 add esp, -10
0050BE42 B8 ECB95000 mov eax, VCDAlbum.0050B9EC
0050BE47 E8 A4AEEFFF call VCDAlbum.00406CF0
0050BE4C A1 3CF55000 mov eax, dword ptr ds:[50F53C]
0050BE51 8B00 mov eax, dword ptr ds:[eax]
0050BE53 E8 3097F7FF call VCDAlbum.00485588
0050BE58 A1 3CF55000 mov eax, dword ptr ds:[50F53C]
0050BE5D 8B00 mov eax, dword ptr ds:[eax]
0050BE5F BA 9CBE5000 mov edx, VCDAlbum.0050BE9C
0050BE64 E8 1793F7FF call VCDAlbum.00485180
0050BE69 8B0D 00F45000 mov ecx, dword ptr ds:[50F400] ; VCDAlbum.00510FD8
现在可以可以用LoadPe来dump了,右击该进程后,首先执行一下"correct ImageSize",然后dump full出文件。
二寻找IAT的Rav和Size(不知道如果不用ImportREC来修复,还请大家指点)
再次从新载入程序,下bp GetProcAddress断点,F9运行,中断第三次后,Ctrl+f9返回到:
003730B5 8907 mov dword ptr ds:[edi], eax ;注意这里的[edi]地址中的内空,就是IAT的Rva了,此时[edi]地址是511208
003730B7 5A pop edx
003730B8 0FB642 FF movzx eax, byte ptr ds:[edx-1]
003730BC 03D0 add edx, eax
003730BE 42 inc edx
003730BF 83C7 04 add edi, 4
003730C2 59 pop ecx
003730C3 ^ E2 CA loopd short 0037308F
003730C5 ^ EB 93 jmp short 0037305A
由003730C5 ^ EB 93 jmp short 0037305A来到上面看一下
0037305A 8B3A mov edi, dword ptr ds:[edx]
0037305C 0BFF or edi, edi
0037305E 75 02 jnz short 00373062 ;注意这里,当jnz不跳时,表示IAT表处理完毕
00373060 EB 65 jmp short 003730C7 ;可以直接在这里下断。
00373062 03BD B4020000 add edi, dword ptr ss:[ebp+2B4]
00373068 83C2 05 add edx, 5
0037306B 8BF2 mov esi, edx
当程序中断在00373060 EB 65 jmp short 003730C7里,可以看到IAT是的大小是从511208~511B08
现在可以请出ImportREC,OEP为:10BE3C RVA为:111208,Size:用1000即可
修复后可以正常运行。但还需要解决跨平台问题。
方法很简单(在此对fly的指点表示衷心的感谢,方法是会了,但原理不清楚,可以是不同平台下同一功能的函数名字不一样?还请大家指点)
具体方法是在修复前,先手动在ImportREC里,把kernel32.dll中的RestoreLastError修改为SetLastError这个函数
这样就可以解决跨平台问题了(在xp_sp1和win2000_sp4下测试通过)
--------------------------------------------------------------------------------
【破解总结】
第一次脱这样的壳,上面只是我的笔记,有点乱,有哪些不对的地方,请大家指点。
在此对帮助和指们我们这样小菜瓜大侠们表示由衷的感谢
另:此软件脱壳后还有两处暗桩,有兴趣的可以玩玩,不在不这里公布了
--------------------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课