【破文标题】:PowerPoint to Flash 1.6.7 脱壳+破解
【破文作者】:KuNgBiM[DFCG]
【作者邮箱】:gb_1227@163.com
【软件名称】:PowerPoint to Flash 1.6.7
【软件大小】:734 KB
【软件语言】:英文
【下载地址】:http://www.dreamingsoft.com/download/pfsetup.exe
【软件简介】:PowerPoint to Flash 是第一个能够将 PowerPoint 的 *.ppt 档转换为 Flash 的 *.swf 文件的软件,它支持大量转档,可一次将多个演示文稿档案转换成目前最受欢迎的 Flash 格式,方便发布于网页,因为 Flash 只要浏览器就可以开启了,而 *.ppt 文件需要安装 PowerPoint 或检视程序。
【保护方式】:注册码 + 30次试用限制 + 启动NAG提示框
【加密保护】:Armadillo 1.xx - 2.xx -> Silicon Realms Toolworks
【编译语言】:Microsoft Visual C++ 7.0 [Debug]
【调试环境】:WinXP、PEiD、Ollydbg、LordPE、ImportREC
【破解日期】:2005-08-18
【破解目的】:推广使用Ollydbg手动脱壳
【作者声明】:初学Crack,只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
—————————————————————————————————
【脱壳过程】:
一、准备工作
侦壳:用PEiD查壳,Armadillo 1.xx - 2.xx -> Silicon Realms Toolworks 加壳,打开LordPE看见该程序有2个进程,证明该软件具有双进程特征,下面我们就必须先分离父进程,要程序把自己当成子进程运行。
试运行:启动时出现了NAG提示框,很明显,这个使用次数限制是Armadillo壳所添加的。
—————————————————————————————————
二、脱壳
1.分离父进程,使程序把自己当成子进程运行
设置Ollydbg忽略所有其它异常选项。老规矩:用IsDebug 1.4插件去掉Ollydbg的调试器标志。
Ollydbg载入主程序:
00483914 > 55 push ebp // OD载入后停在这里
00483915 8BEC mov ebp,esp
00483917 6A FF push -1
00483919 68 D0D54800 push pptFlash.0048D5D0
0048391E 68 34344800 push pptFlash.00483434
00483923 64:A1 00000000 mov eax,dword ptr fs:[0]
00483929 50 push eax
0048392A 64:8925 00000000 mov dword ptr fs:[0],esp
00483931 83EC 58 sub esp,58
00483934 53 push ebx
00483935 56 push esi
00483936 57 push edi
00483937 8965 E8 mov dword ptr ss:[ebp-18],esp
0048393A FF15 68A14800 call dword ptr ds:[<&KERNEL32.GetVersion>] ; kernel32.GetVersion
00483940 33D2 xor edx,edx
命令行下断:BP OpenMutexA 然后F9运行:
77E62391 > 55 push ebp // 注意观察堆栈
77E62392 8BEC mov ebp,esp
77E62394 51 push ecx
77E62395 51 push ecx
77E62396 837D 10 00 cmp dword ptr ss:[ebp+10],0
77E6239A 56 push esi
77E6239B 0F84 C2E30100 je kernel32.77E80763
77E623A1 64:A1 18000000 mov eax,dword ptr fs:[18]
77E623A7 FF75 10 push dword ptr ss:[ebp+10]
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
注意看BP OpenMutexA 时的堆栈:
0012F5B8 0047E85D /CALL 到 OpenMutexA 来自 pptFlash.0047E857
0012F5BC 001F0001 |Access = 1F0001
0012F5C0 00000000 |Inheritable = FALSE
0012F5C4 0012FBF8 \MutexName = "7A4::DA3935EA83" ★注意这个地址:0012FBF8
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
Ctrl+G:401000 键入以下代码:
00401000 60 pushad
00401001 9C pushfd
00401002 68 F8FB1200 push 12FBF8 ★ 堆栈里看到的值
00401007 33C0 xor eax,eax
00401009 50 push eax
0040100A 50 push eax
0040100B E8 B5A6A577 call kernel32.CreateMutexA
00401010 9D popfd
00401011 61 popad
00401012 - E9 7A13A677 jmp kernel32.OpenMutexA
在401000处新建起源,F9运行,再次中断在OpenMutexA处,此时Ctrl+G:401000 撤销刚才的修改的代码,使代码还原。OK,父进程分离完毕!把这段代码以二进制保存起来,下次用时直接粘贴,修改00401002处push的值就OK了。
二进制代码:60 9C 68 F8 FB 12 00 33 C0 50 50 E8 B5 A6 A5 77 9D 61 E9 7A 13 A6 77
—————————————————————————————————
2、寻找Magic Jump,避开IAT加密
取消以前所有的断点,下断:BP GetModuleHandleA 然后F9运行:
77E5AD86 > 837C24 04 00 cmp dword ptr ss:[esp+4],0 // 断在这,注意看堆栈
77E5AD8B 0F84 37010000 je kernel32.77E5AEC8
77E5AD91 FF7424 04 push dword ptr ss:[esp+4]
77E5AD95 E8 F8050000 call kernel32.77E5B392
77E5AD9A 85C0 test eax,eax
77E5AD9C 74 08 je short kernel32.77E5ADA6
77E5AD9E FF70 04 push dword ptr ds:[eax+4]
77E5ADA1 E8 27060000 call kernel32.GetModuleHandleW
77E5ADA6 C2 0400 retn 4
在这里中断N次,然后Alt+F9返回程序。其实很好判断返回程序的时机。
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
注意看BP GetModuleHandleA 时的堆栈变化:
0012ED04 77C059FC /CALL 到 GetModuleHandleA 来自 msvcrt.77C059F6
0012ED08 77BE31AC \pModule = "kernel32.dll"
0012EDC8 772A8663 /CALL 到 GetModuleHandleA 来自 772A865D
0012EDCC 772AF8FC \pModule = "KERNEL32.DLL"
0012ECF0 770FB124 /CALL 到 GetModuleHandleA 来自 OLEAUT32.770FB11E
0012ECF4 771722E4 \pModule = "KERNEL32.DLL"
0012ECEC 770FB124 /CALL 到 GetModuleHandleA 来自 OLEAUT32.770FB11E
0012ECF0 771722E4 \pModule = "KERNEL32.DLL"
0012F570 0047DDD9 /CALL 到 GetModuleHandleA 来自 pptFlash.0047DDD3
0012F574 00000000 \pModule = NULL
0012E00C 003D60DB /CALL 到 GetModuleHandleA 来自 003D60D5
0012E010 003EB808 \pModule = "kernel32.dll"
0012E00C 003D60DB /CALL 到 GetModuleHandleA 来自 003D60D5
0012E010 003EB7FC \pModule = "user32.dll"
0012E048 003E0375 /CALL 到 GetModuleHandleA 来自 003E036F
0012E04C 00C52008 \pModule = "SHLWAPI.dll"
0012E02C 003D653E /CALL 到 GetModuleHandleA 来自 003D6538 ★注意!在这里Alt+F9返回程序
0012E030 00000000 \pModule = NULL
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
当堆栈如上变化后,就可以Alt+F9返回程序代码了。
003D6522 55 push ebp
003D6523 8BEC mov ebp,esp
003D6525 53 push ebx
003D6526 56 push esi
003D6527 57 push edi
003D6528 33FF xor edi,edi
003D652A 33DB xor ebx,ebx
003D652C 66:F745 0E FFFF test word ptr ss:[ebp+E],0FFFF
003D6532 75 03 jnz short 003D6537
003D6534 8B5D 0C mov ebx,dword ptr ss:[ebp+C]
003D6537 57 push edi
003D6538 FF15 CC903E00 call dword ptr ds:[3E90CC] ; kernel32.GetModuleHandleA
003D653E 8B4D 08 mov ecx,dword ptr ss:[ebp+8] // 返回到这里
003D6541 3BC8 cmp ecx,eax
003D6543 75 07 jnz short 003D654C
003D6545 B8 A8B33E00 mov eax,3EB3A8
003D654A EB 2F jmp short 003D657B
003D654C 393D D8B73E00 cmp dword ptr ds:[3EB7D8],edi
003D6552 B8 D8B73E00 mov eax,3EB7D8
003D6557 74 0C je short 003D6565 ★ Magic Jump ★ // 改为 :jmp 003D6565
003D6559 3B48 08 cmp ecx,dword ptr ds:[eax+8]
003D655C 74 1A je short 003D6578
003D655E 83C0 0C add eax,0C
003D6561 3938 cmp dword ptr ds:[eax],edi
003D6563 ^ 75 F4 jnz short 003D6559
003D6565 FF75 0C push dword ptr ss:[ebp+C]
003D6568 FF75 08 push dword ptr ss:[ebp+8]
003D656B FF15 F8903E00 call dword ptr ds:[3E90F8] ; kernel32.GetProcAddress
003D6571 5F pop edi
003D6572 5E pop esi
003D6573 5B pop ebx
003D6574 5D pop ebp
003D6575 C2 0800 retn 8
以前脱 Armadillo 3.60 以上的壳时总是在Magic Jump处下 硬件执行 断点,每次断下后改标志Z=1,使其JMP。如果直接改为JMP,程序会异常出错!主要是程序自校验问题,但对付这种Armadillo旧版壳时,就可以直接修改的!
—————————————————————————————————
3、第2区段内存断点大法,直达OEP
Alt+M 查看内存,在401000区段上下“内存访问断点”,F9运行,直接中断在OEP处:
00438570 6A 60 push 60 // 在这儿用LordPE纠正ImageSize后完全Dump这个进程
00438572 68 98534600 push pptFlash.00465398
00438577 E8 30230000 call pptFlash.0043A8AC
0043857C BF 94000000 mov edi,94
00438581 8BC7 mov eax,edi
00438583 E8 A8FAFFFF call pptFlash.00438030
00438588 8965 E8 mov dword ptr ss:[ebp-18],esp
0043858B 8BF4 mov esi,esp
0043858D 893E mov dword ptr ds:[esi],edi
0043858F 56 push esi
00438590 FF15 B4C14500 call dword ptr ds:[45C1B4] ; kernel32.GetVersionExA
00438596 8B4E 10 mov ecx,dword ptr ds:[esi+10]
00438599 890D 14794700 mov dword ptr ds:[477914],ecx
0043859F 8B46 04 mov eax,dword ptr ds:[esi+4]
004385A2 A3 20794700 mov dword ptr ds:[477920],eax
004385A7 8B56 08 mov edx,dword ptr ds:[esi+8]
004385AA 8915 24794700 mov dword ptr ds:[477924],edx
004385B0 8B76 0C mov esi,dword ptr ds:[esi+C]
004385B3 81E6 FF7F0000 and esi,7FFF
004385B9 8935 18794700 mov dword ptr ds:[477918],esi
004385BF 83F9 02 cmp ecx,2
004385C2 74 0C je short pptFlash.004385D0
运行ImportREC 1.6,选择这个进程。把OEP改为00038570,点IT AutoSearch,函数全部有效。FixDump,正常运行!
优化:用LordPE删除区段“.text1”、“.data1”、“.pdata”然后“重建PE”!程序由脱壳后的2.18MB变为1.59MB!嘿嘿~~!!
————————————————————————
三、破解
程序采用了Armadillo的注册模块,脱壳后自然就不必注册了,30次的试用限制也不存在了。
但是,在某些无用户名的机器上出现注册非法,下面我就来搞定它!使它变成“永久注册版”,嘿嘿~~~
再次打开Ollydbg,载入我们脱壳优化后的文件“dumped_1.exe”,右键使用 Ultra String Reference 插件的 Find ASCII 功能项,查找我们需要的相关信息:
———————————————————————————————————————————————————————
00401A7B push 复件_dum.0045C848 Unregistered Copy
00401AD3 push 复件_dum.0045C828 This copy is licensed to:\n\n%s
00401BF0 push 复件_dum.0045C85C open
00401FE8 push 复件_dum.0045C8B4 ArmAccess.DLL
00402004 push 复件_dum.0045C89C System Error! 0X0E01
0040200B push 复件_dum.0045C890 CheckCode
0040201E push 复件_dum.0045C878 System Error! 0X0E02
00402068 push 复件_dum.0045C868 Invalid Key!
00402155 push 复件_dum.0045C8E0 USERNAME ★读取用户名,双击这里★
0040220A push 复件_dum.0045C8D8 DEFAULT
0040224C push 复件_dum.0045C8D0 EXPIRED
0040229A push 复件_dum.0045C8C4 USESLEFT
004024A8 push 复件_dum.0045C8EC %d uses left
........
———————————————————————————————————————————————————————
程序代码:
0040214F 68 FF000000 push 0FF // 读取用户名 ★从这里修改★
00402154 50 push eax
00402155 68 E0C84500 push 复件_dum.0045C8E0 // 双击来到这里
0040215A FFD5 call ebp
0040215C 85C0 test eax,eax
0040215E 8B16 mov edx,dword ptr ds:[esi] // 这就是保存注册名的位置
00402160 75 78 jnz short 复件_dum.004021DA
00402162 85D2 test edx,edx
00402164 74 19 je short 复件_dum.0040217F
00402166 8BC2 mov eax,edx
00402168 8D78 01 lea edi,dword ptr ds:[eax+1]
0040216B EB 03 jmp short 复件_dum.00402170
0040216D 8D49 00 lea ecx,dword ptr ds:[ecx]
00402170 8A08 mov cl,byte ptr ds:[eax]
00402172 40 inc eax
00402173 84C9 test cl,cl
00402175 ^ 75 F9 jnz short 复件_dum.00402170
00402177 2BC7 sub eax,edi
00402179 0F88 9B020000 js 复件_dum.0040241A
0040217F 3B42 F8 cmp eax,dword ptr ds:[edx-8]
00402182 0F8F 92020000 jg 复件_dum.0040241A
00402188 8942 F4 mov dword ptr ds:[edx-C],eax
0040218B 8B0E mov ecx,dword ptr ds:[esi]
0040218D C60408 00 mov byte ptr ds:[eax+ecx],0
00402191 8D4C24 24 lea ecx,dword ptr ss:[esp+24]
00402195 E8 46040000 call 复件_dum.004025E0
0040219A 6A 10 push 10
0040219C 68 661B0000 push 1B66
004021A1 8D4C24 2C lea ecx,dword ptr ss:[esp+2C]
004021A5 C74424 24 00000000 mov dword ptr ss:[esp+24],0 // 比较注册名是否为0
004021AD E8 4E040000 call 复件_dum.00402600 // 为0则死!★这里可以nop掉,但没注册名看起不太爽!★
004021B2 8D4C24 24 lea ecx,dword ptr ss:[esp+24]
004021B6 C74424 1C FFFFFFFF mov dword ptr ss:[esp+1C],-1
004021BE E8 2D040000 call 复件_dum.004025F0
004021C3 5F pop edi
004021C4 5E pop esi
004021C5 5D pop ebp
004021C6 33C0 xor eax,eax
004021C8 5B pop ebx
004021C9 8B4C24 04 mov ecx,dword ptr ss:[esp+4]
004021CD 64:890D 00000000 mov dword ptr fs:[0],ecx
004021D4 83C4 10 add esp,10
004021D7 C2 0400 retn 4
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
0040214F 处修改代码:
0040214F C700 204B754E mov dword ptr ds:[eax],4E754B20
00402155 C740 04 6742694D mov dword ptr ds:[eax+4],4D694267
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
修改后保存即可!永久注册版诞生咯~~~~
--------------------------------------------------------------------------------------------
版权所有(C)2005 KuNgBiM[DFCG] Copyright (C) 2005 KuNgBiM[DFCG]
--------------------------------------------------------------------------------------------
Cracked By KuNgBiM[DFCG]
2005-08-18
14:29:18 PM