标题:手动脱壳入门第六篇PECompact 1.84

-------------------------------------------------------------------------------------------------------------------------------

时间:2006/8/28 17:11:31

-------------------------------------------------------------------------------------------------------------------------------

内容:

xTiNt
 手动脱壳入门第六篇PECompact 1.84  
手动脱壳入门第六篇PECompact 1.84
【脱文标题】 手动脱壳入门第六篇PECompact 1.84
【脱文作者】 weiyi75[Dfcg] 
【作者邮箱】 weiyi75@sohu.com 
【作者主页】 Dfcg官方大本营 
【使用工具】 Peid,Ollydbg
【脱壳平台】 Win2K/XP
【软件名称】 note_aPlib.exe
【软件简介】 PECompact是一个能压缩可执行文件的工具,通过压缩代码、数据、相关资源使压缩能达到100%,由于在运行时不需要恢复磁盘上压缩后的数据,所以与没有压缩的程序在运行时没有明显的速度差异,在某种程度上还有所改善。
【软件大小】 18KB 
【加壳方式】 PECompact 1.68 - 1.84 -> Jeremy Collake
【保护方式】 PECompact1.84 aPlib方式
【脱壳声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享: 
软件截图
 
我们看到它有aPLib和JCALG1两种压缩引擎,前者对低于64kb的文件压缩效果较好,速度也较快。后者具有更为强劲的压缩效果,对于大文件的压缩效果较好。并有很丰富的各类选项,对普通用户来说,使用其默认设置即可。
原版程序本地下载
汉化版本本地下载

好现在我们来手动脱一个PECompact1.84以aPlib方式加壳的记事本看看它的特性。
本地下载
首先必须的工具要准备好
附件中壳PEiD测壳为PECompact 1.68 - 1.84 -> Jeremy Collake,只能测试出大致版本,其实都差不多。
手动脱壳建议大家用Ollydbg,工作平台Win2000,WinXp,Win9x不推荐。
手动脱壳时,用Olldbg载入程序,脱壳程序里面会有有好多循环。对付循环时,只能让程序往前运行,基本不能让它往回跳,要想法跳出循环圈。不要用Peid查入口,单步跟踪,提高手动找入口能力。
用OD载入程序后。
确定一个入口警告,然后Od提示程序加壳,选不继续分析。
停在这里
0040C000 n> /EB 06 jmp short note_aPl.0040C008 开始地点。
0040C002 |68 CC100000 push 10CC
0040C007 |C3 retn
0040C008 \9C pushfd 注意PECompactd的壳比UPX,Aspack多了这个指令。
0040C009 60 pushad 出口处看到与之对应的语句就应知道入口点就在附近。
0040C00A E8 02000000 call note_aPl.0040C011 一看就应用F7过,变形的Jmp
0040C00F 33C0 xor eax, eax
0040C011 8BC4 mov eax, esp Call这里,很近。
0040C013 83C0 04 add eax, 4
0040C016 93 xchg eax, ebx
0040C017 8BE3 mov esp, ebx
0040C019 8B5B FC mov ebx, dword ptr ds:[ebx-4]
0040C01C 81EB 3F904000 sub ebx, note_aPl.0040903F
0040C022 87DD xchg ebp, ebx
...........................................为节省篇幅,略去一些不重要的代码,今后不再赘述。
0040C06C 8DB5 AC904000 lea esi, dword ptr ss:[ebp+4090AC>
0040C072 B9 40040000 mov ecx, 440
0040C077 F3:A5 rep movs dword ptr es:[edi], dwor>
0040C079 8BFB mov edi, ebx
0040C07B C3 retn 返回。
0040D17B BD CF400000 mov ebp, 40CF 到这里。
0040D180 8BF7 mov esi, edi
0040D182 83C6 54 add esi, 54
0040D185 81C7 FF100000 add edi, 10FF
...........................................
0040D19E F3:A5 rep movs dword ptr es:[edi], dwor>
0040D1A0 03C8 add ecx, eax
0040D1A2 83E1 03 and ecx, 3
0040D1A5 F3:A4 rep movs byte ptr es:[edi], byte >
0040D1A7 EB 26 jmp short note_aPl.0040D1CF 跳走。
0040D1CF 8BB5 E6904000 mov esi, dword ptr ss:[ebp+4090E6>; note_aPl.00400000 到这里。
0040D1D5 56 push esi
0040D1D6 03B5 EE904000 add esi, dword ptr ss:[ebp+4090EE>
0040D1DC 83C6 14 add esi, 14
0040D1DF 03B5 35974000 add esi, dword ptr ss:[ebp+409735>
0040D1E5 8DBD 39974000 lea edi, dword ptr ss:[ebp+409739>
0040D1EB B9 06000000 mov ecx, 6
0040D1F0 F3:A5 rep movs dword ptr es:[edi], dwor>
...........................................
0040D210 8BB5 DE904000 mov esi, dword ptr ss:[ebp+4090DE>
0040D216 80BD 6B9D4000 C>cmp byte ptr ss:[ebp+409D6B], 0C3
0040D21D 74 2E je short note_aPl.0040D24D 跳走。
0040D24D 57 push edi
0040D24E AD lods dword ptr ds:[esi]
0040D24F 85C0 test eax, eax
0040D251 0F84 9B000000 je note_aPl.0040D2F2 这个跳转很大,但是没跳走,先记住,如果下面的语句有往回跳转无法往后继续走,我们再试试这里。
0040D257 8BD0 mov edx, eax
0040D259 0395 E6904000 add edx, dword ptr ss:[ebp+4090E6>
0040D25F AD lods dword ptr ds:[esi]
0040D260 56 push esi
0040D261 8BC8 mov ecx, eax
0040D263 57 push edi
0040D264 52 push edx
0040D265 8DB5 6BA14000 lea esi, dword ptr ss:[ebp+40A16B>
0040D26B 57 push edi
0040D26C 51 push ecx
0040D26D 52 push edx
0040D26E 6A 40 push 40
0040D270 56 push esi
0040D271 FFB5 3D974000 push dword ptr ss:[ebp+40973D]
0040D277 FFB5 39974000 push dword ptr ss:[ebp+409739]
0040D27D E8 B8090000 call note_aPl.0040DC3A
...........................................
0040D2AA /74 07 je short note_aPl.0040D2B3
0040D2AC |8BC8 mov ecx, eax
0040D2AE |5E pop esi
0040D2AF |5F pop edi
0040D2B0 ^|EB 9B jmp short note_aPl.0040D24D 果然往回跳转。
0040D2B2 B9 E8000000 mov ecx, 0E8 F4无法到达这句,程序运行了。
0040D2B7 005D 81 add byte ptr ss:[ebp-7F], bl
0040D2BA ED in eax, dx
Ctrl+F2重新加载程序,重新来到我们刚才发现的0040D251处,回车。
0040D2F2 5F pop edi 到这里,F2下断点,F9运行跳出循环到这里后再F2取消断点。
0040D2F3 8BB5 E2904000 mov esi, dword ptr ss:[ebp+4090E2>
0040D2F9 AD lods dword ptr ds:[esi]
0040D2FA 83F8 FF cmp eax, -1
0040D2FD 74 74 je short note_aPl.0040D373这个跳转很大,但是没跳走,先记住,如果下面的语句有往回跳转无法往后继续走,我们再试试这里。
0040D2FF 0385 E6904000 add eax, dword ptr ss:[ebp+4090E6>
0040D305 8BD8 mov ebx, eax
0040D307 AD lods dword ptr ds:[esi]
0040D308 0385 E6904000 add eax, dword ptr ss:[ebp+4090E6>
...........................................
0040D361 8BD1 mov edx, ecx
0040D363 C1F9 02 sar ecx, 2
0040D366 F3:AB rep stos dword ptr es:[edi]
0040D368 03CA add ecx, edx
0040D36A 83E1 03 and ecx, 3
0040D36D F3:AA rep stos byte ptr es:[edi]
0040D36F 5F pop edi
0040D370 ^ EB 87 jmp short note_aPl.0040D2F9 果然往回跳转。
0040D372 0F6800 punpckhbw mm0, qword ptr ds:[eax] F4无法到达这句,程序运行了。
0040D375 40 inc eax
0040D376 0000 add byte ptr ds:[eax], al
...........................................
Ctrl+F2重新加载程序,重新来到我们刚才发现的0040D2FD处,回车。
0040D373 68 00400000 push 4000 到这里,F2下断点,F9运行跳出循环到这里后再F2取消断点。
0040D378 6A 00 push 0
0040D37A 57 push edi
0040D37B FF95 45974000 call dword ptr ss:[ebp+409745]
0040D381 8BBD 3C964000 mov edi, dword ptr ss:[ebp+40963C>
0040D387 03BD E6904000 add edi, dword ptr ss:[ebp+4090E6>
0040D38D 8B8D 40964000 mov ecx, dword ptr ss:[ebp+409640>
0040D393 51 push ecx
0040D394 57 push edi
0040D395 33D2 xor edx, edx
0040D397 33DB xor ebx, ebx
0040D399 33F6 xor esi, esi
0040D39B 03FE add edi, esi
0040D39D 03DE add ebx, esi
0040D39F 49 dec ecx
0040D3A0 74 72 je short note_aPl.0040D414 可跳出循环。
0040D3A2 78 70 js short note_aPl.0040D414
...........................................
0040D3B5 /75 0A jnz short note_aPl.0040D3C1 跳走。
0040D3B7 |80FC 80 cmp ah, 80
0040D3BA |72 05 jb short note_aPl.0040D3C1
0040D3BC |80FC 8F cmp ah, 8F
0040D3BF |76 05 jbe short note_aPl.0040D3C6
0040D3C1 \47 inc edi
0040D3C2 43 inc ebx
0040D3C3 ^ EB DA jmp short note_aPl.0040D39F 往回跳转。看到0040D3A0可跳出循环。我们在0040D3A0处点一下,然后回车。
0040D414 5F pop edi F2下断点,F9运行跳出循环到这里后再F2取消断点
0040D415 59 pop ecx
0040D416 33C0 xor eax, eax
0040D418 85C9 test ecx, ecx
0040D41A 74 3B je short note_aPl.0040D457
0040D41C 8BF7 mov esi, edi
0040D41E 33C0 xor eax, eax
0040D420 83F9 04 cmp ecx, 4
...........................................
0040D42F 8B1E mov ebx, dword ptr ds:[esi]
0040D431 03C3 add eax, ebx
0040D433 D1E3 shl ebx, 1
0040D435 83D3 01 adc ebx, 1
0040D438 33C3 xor eax, ebx
0040D43A 83C6 04 add esi, 4
0040D43D 83E9 04 sub ecx, 4
0040D440 74 15 je short note_aPl.0040D457
0040D442 83F9 04 cmp ecx, 4
0040D445 ^ 73 E8 jnb short note_aPl.0040D42F往回跳转
0040D447 BA 04000000 mov edx, 4 F4到这里。
0040D44C 2BD1 sub edx, ecx
0040D44E 2BF2 sub esi, edx
0040D450 B9 04000000 mov ecx, 4
0040D455 ^ EB D8 jmp short note_aPl.0040D42F 又往回跳转
0040D457 3B85 67974000 cmp eax, dword ptr ss:[ebp+409767> F4到这里。
0040D45D 74 4D je short note_aPl.0040D4AC 跳走。
0040D45F ^ E9 4FFEFFFF jmp note_aPl.0040D2B3
0040D4AC E8 A1010000 call note_aPl.0040D652 到这里。Call的距离较远,F8过。
0040D4B1 E8 A3000000 call note_aPl.0040D559 Call的距离较远,F8过。
0040D4B6 73 6B jnb short note_aPl.0040D523 跳走。
0040D523 80BD 6B9F4000 C>cmp byte ptr ss:[ebp+409F6B], 0C3
0040D52A 74 22 je short note_aPl.0040D54E 跳。
0040D52C 8D95 6BA14000 lea edx, dword ptr ss:[ebp+40A16B>
0040D532 6A 40 push 40
0040D534 52 push edx
0040D535 FFB5 3D974000 push dword ptr ss:[ebp+40973D]
0040D53B FFB5 39974000 push dword ptr ss:[ebp+409739]
0040D541 E8 F40A0000 call note_aPl.0040E03A
0040D546 85C0 test eax, eax
0040D548 ^ 0F85 9DFDFFFF jnz note_aPl.0040D2EB
0040D54E 61 popad 看到这两个与开始处对应的标志了。
0040D54F 9D popfd 入口点就在附近。
0040D550 50 push eax
0040D551 68 CC104000 push note_aPl.004010CC 
0040D556 C2 0400 retn 4 准备返回到程序入口点,跨段。
004010CC 55 push ebp 入口点,跨段来到这里并且经过了PoPad和popfd两个关键字,我们在这里用Od的 Dump插件直接脱壳。
004010CD 8BEC mov ebp, esp
004010CF 83EC 44 sub esp, 44
004010D2 56 push esi
004010D3 FF15 E4634000 call dword ptr ds:[4063E4] ; kernel32.GetCommandLineA
004010D9 8BF0 mov esi, eax
004010DB 8A00 mov al, byte ptr ds:[eax]
004010DD 3C 22 cmp al, 22
004010DF 75 1B jnz short note_aPl.004010FC
004010E1 56 push esi
004010E2 FF15 F4644000 call dword ptr ds:[4064F4] ; USER32.CharNextA
重建输入表时,插件有两个选项。Method2重建输入表很快,脱壳后运行率高。Method1重建输入表慢,脱壳后运行率较低。不过本程序用Method2重建输入表无法运行,Method1重建输入表后程序可直接运行。
总结:
PECompac加壳程序
入口关键字 有两个。
pushfd 注意PECompactd的壳比UPX,Aspack多了这个指令。
pushad
出口关键字
POPAD 
popfd 和入口关键字对应,过了这两个关键字,要注意程序oep就在附近。
通过Ret返回到程序Oep
经过实践,发现PECompac1.4X-1.8X加壳的程序手动脱壳流程基本相同,这里就不一一列出,大家碰到后请自行参考本文进行练习。
附参考教学。
作者:lordor[BCG] 来源:看雪论坛 加入时间:2003-6-2 
对象:五笔打字通5.0
作者:lordor[BCG]
声明:属技术交流,无其它目的,请不要任意散布或用作商业用途。初学破解,如有不对的地方欢迎批评指出。
工具:ollydbg1.09B,插件ollyDump V2.11.108
基本操作:F8-单步执行,遇到call不进入。F7-单步执行,遇到call进入。F4-执行到光标所在行。F2-设断
手动脱壳要把握两点:
1、单步往前走,不要回头。
2、观察。注意poshad、poshfd,popad、popfd等,注意地址发生大的变化。
程序用PECompact V1.40-45加的壳,没见过的,在这里只好手动脱壳。
0054DC00 > /EB 06 JMP SHORT wb86.0054DC08
0054DC02 |68 84370000 PUSH 3784
0054DC07 |C3 RETN
0054DC08 \9C PUSHFD
0054DC09 60 PUSHAD
0054DC0A E8 02000000 CALL wb86.0054DC11 =>单步走到这里,F8过的话程序就运行,所以要F7跟入
-------------------------------------------------------------------------------
0054DC11 8BC4 MOV EAX,ESP    =>F7后来到这,继续单步运行
0054DC13 83C0 04 ADD EAX,4
0054DC16 93 XCHG EAX,EBX
0054DC17 8BE3 MOV ESP,EBX
0054DC19 8B5B FC MOV EBX,DWORD PTR DS:[EBX-4]
0054DC1C 81EB 0FA04000 SUB EBX,wb86.0040A00F
0054DC22 87DD XCHG EBP,EBX
0054DC24 8B85 A6A04000 MOV EAX,DWORD PTR SS:[EBP+40A0A6]
0054DC2A 0185 03A04000 ADD DWORD PTR SS:[EBP+40A003],EAX
0054DC30 66:C785 00A0400>MOV WORD PTR SS:[EBP+40A000],9090
0054DC39 0185 9EA04000 ADD DWORD PTR SS:[EBP+40A09E],EAX
0054DC3F BB C3110000 MOV EBX,11C3
0054DC44 039D AAA04000 ADD EBX,DWORD PTR SS:[EBP+40A0AA]
0054DC4A 039D A6A04000 ADD EBX,DWORD PTR SS:[EBP+40A0A6]
0054DC50 53 PUSH EBX
0054DC51 53 PUSH EBX
...............(一直往前走,省略).....................
0054F25E 57 PUSH EDI
0054F25F AD LODS DWORD PTR DS:[ESI]
0054F260 0BC0 OR EAX,EAX
0054F262 74 6C JE SHORT wb86.0054F2D0
0054F264 8BD0 MOV EDX,EAX
0054F266 0395 A6A04000 ADD EDX,DWORD PTR SS:[EBP+40A0A6]
0054F26C AD LODS DWORD PTR DS:[ESI]
0054F26D 56 PUSH ESI
0054F26E 8BC8 MOV ECX,EAX
0054F270 57 PUSH EDI
0054F271 52 PUSH EDX
0054F272 8BF2 MOV ESI,EDX
0054F274 8B85 15A64000 MOV EAX,DWORD PTR SS:[EBP+40A615]
0054F27A 8B9D 19A64000 MOV EBX,DWORD PTR SS:[EBP+40A619]
0054F280 E8 910A0000 CALL wb86.0054FD16
0054F285 5A POP EDX
0054F286 5F POP EDI
0054F287 52 PUSH EDX
0054F288 57 PUSH EDI
0054F289 FF95 9EA04000 CALL DWORD PTR SS:[EBP+40A09E]
0054F28F 0BC0 OR EAX,EAX
0054F291 74 07 JE SHORT wb86.0054F29A
0054F293 8BC8 MOV ECX,EAX
0054F295 5E POP ESI
0054F296 5F POP EDI
0054F297 ^ EB C5 JMP SHORT wb86.0054F25E  ==>走到这里会跳到前面,把光标移动到下一行,F4跳过时程序会直接运行,所以还得单步运行,走到上面的0054F262处会跳到后面去了
0054F299 B9 8D9D97A5 MOV ECX,A5979D8D
0054F29E 40 INC EAX
0054F29F 0053 FF ADD BYTE PTR DS:[EBX-1],DL
0054F2A2 95 XCHG EAX,EBP
0054F2A3 15 A640008D ADC EAX,8D0040A6
0054F2A8 9D POPFD
...............(一直往前走,省略).....................
0054F2CF 24 58 AND AL,58  ==>从上面跳到这,继续单步走
0054F2D1 8DB5 C3A64000 LEA ESI,DWORD PTR SS:[EBP+40A6C3]
0054F2D7 AD LODS DWORD PTR DS:[ESI]
0054F2D8 0BC0 OR EAX,EAX
0054F2DA 74 74 JE SHORT wb86.0054F350
0054F2DC 0385 A6A04000 ADD EAX,DWORD PTR SS:[EBP+40A0A6]
...............(一直往前走,省略).....................
0054F36D 49 DEC ECX
0054F36E 74 72 JE SHORT wb86.0054F3E2
0054F370 78 70 JS SHORT wb86.0054F3E2
0054F372 66:8B07 MOV AX,WORD PTR DS:[EDI]
0054F375 2C E8 SUB AL,0E8
0054F377 3C 01 CMP AL,1
0054F379 76 38 JBE SHORT wb86.0054F3B3
0054F37B 66:3D 1725 CMP AX,2517
0054F37F 74 51 JE SHORT wb86.0054F3D2
0054F381 3C 27 CMP AL,27
0054F383 75 0A JNZ SHORT wb86.0054F38F
0054F385 80FC 80 CMP AH,80
0054F388 72 05 JB SHORT wb86.0054F38F
0054F38A 80FC 8F CMP AH,8F
0054F38D 76 05 JBE SHORT wb86.0054F394
0054F38F 47 INC EDI
0054F390 43 INC EBX
0054F391 ^ EB DA JMP SHORT wb86.0054F36D ==>这里又跳到前面,看一下前面那一句会跳到后面的,是JE SHORT 0054F3E2,JS SHORT 0054F3E2,JBE SHORT wb86.0054F3B3,JE SHORT 0054F3D2,依次在其跳往的地方设断。F9运行,会在设断的地方停,最后确定0054F3E2才是正确的设断地方
0054F393 B8 8B47023C MOV EAX,3C02478B
...............(一直往前走,省略).....................
0054F476 8BB5 15A64000 MOV ESI,DWORD PTR SS:[EBP+40A615]
0054F47C 8BBD 19A64000 MOV EDI,DWORD PTR SS:[EBP+40A619]
0054F482 E8 8F0C0000 CALL wb86.00550116
0054F487 61 POPAD ==>看到希望了,继续单步走
0054F488 9D POPFD 
0054F489 50 PUSH EAX
0054F48A 68 84374000 PUSH wb86.00403784
0054F48F C2 0400 RETN 4 ==>走过这里,地址会有很大变化,可以确定,壳已脱完了。
0054F492 8BB5 37A64000 MOV ESI,DWORD PTR SS:[EBP+40A637]
00403781 00 DB 00
00403782 > 0000 ADD BYTE PTR DS:[EAX],AL
00403784 . 68 94FF4300 PUSH wb86.0043FF94  ===>由0054F48F处跳来,在这里运行ollyDump把
程序dump下来。到此手动脱壳结束。
00403789 E8 DB E8
0040378A EE DB EE
0040378B FF DB FF
0040378C FF DB FF
0040378D FF DB FF
0040378E 00 DB 00
0040378F 00 DB 00
00403790 00 DB 00
00403791 00 DB 00
00403792 00 DB 00
脱完后可以用侦壳工具看,是用VB写的。其它壳(如Aspack等)都可以用此法配合OLLYDUMP来手动脱壳.
"手动脱壳入门第六篇"脱壳动画! 

  
 

  

xTiNt
 手动脱壳入门第六篇PECompact 1.84  
手动脱壳入门第六篇PECompact 1.84
【脱文标题】 手动脱壳入门第六篇PECompact 1.84
【脱文作者】 weiyi75[Dfcg] 
【作者邮箱】 weiyi75@sohu.com 
【作者主页】 Dfcg官方大本营 
【使用工具】 Peid,Ollydbg
【脱壳平台】 Win2K/XP
【软件名称】 note_aPlib.exe
【软件简介】 PECompact是一个能压缩可执行文件的工具,通过压缩代码、数据、相关资源使压缩能达到100%,由于在运行时不需要恢复磁盘上压缩后的数据,所以与没有压缩的程序在运行时没有明显的速度差异,在某种程度上还有所改善。
【软件大小】 18KB 
【加壳方式】 PECompact 1.68 - 1.84 -> Jeremy Collake
【保护方式】 PECompact1.84 aPlib方式
【脱壳声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享: 
软件截图
 
我们看到它有aPLib和JCALG1两种压缩引擎,前者对低于64kb的文件压缩效果较好,速度也较快。后者具有更为强劲的压缩效果,对于大文件的压缩效果较好。并有很丰富的各类选项,对普通用户来说,使用其默认设置即可。
原版程序本地下载
汉化版本本地下载

好现在我们来手动脱一个PECompact1.84以aPlib方式加壳的记事本看看它的特性。
本地下载
首先必须的工具要准备好
附件中壳PEiD测壳为PECompact 1.68 - 1.84 -> Jeremy Collake,只能测试出大致版本,其实都差不多。
手动脱壳建议大家用Ollydbg,工作平台Win2000,WinXp,Win9x不推荐。
手动脱壳时,用Olldbg载入程序,脱壳程序里面会有有好多循环。对付循环时,只能让程序往前运行,基本不能让它往回跳,要想法跳出循环圈。不要用Peid查入口,单步跟踪,提高手动找入口能力。
用OD载入程序后。
确定一个入口警告,然后Od提示程序加壳,选不继续分析。
停在这里
0040C000 n> /EB 06 jmp short note_aPl.0040C008 开始地点。
0040C002 |68 CC100000 push 10CC
0040C007 |C3 retn
0040C008 \9C pushfd 注意PECompactd的壳比UPX,Aspack多了这个指令。
0040C009 60 pushad 出口处看到与之对应的语句就应知道入口点就在附近。
0040C00A E8 02000000 call note_aPl.0040C011 一看就应用F7过,变形的Jmp
0040C00F 33C0 xor eax, eax
0040C011 8BC4 mov eax, esp Call这里,很近。
0040C013 83C0 04 add eax, 4
0040C016 93 xchg eax, ebx
0040C017 8BE3 mov esp, ebx
0040C019 8B5B FC mov ebx, dword ptr ds:[ebx-4]
0040C01C 81EB 3F904000 sub ebx, note_aPl.0040903F
0040C022 87DD xchg ebp, ebx
...........................................为节省篇幅,略去一些不重要的代码,今后不再赘述。
0040C06C 8DB5 AC904000 lea esi, dword ptr ss:[ebp+4090AC>
0040C072 B9 40040000 mov ecx, 440
0040C077 F3:A5 rep movs dword ptr es:[edi], dwor>
0040C079 8BFB mov edi, ebx
0040C07B C3 retn 返回。
0040D17B BD CF400000 mov ebp, 40CF 到这里。
0040D180 8BF7 mov esi, edi
0040D182 83C6 54 add esi, 54
0040D185 81C7 FF100000 add edi, 10FF
...........................................
0040D19E F3:A5 rep movs dword ptr es:[edi], dwor>
0040D1A0 03C8 add ecx, eax
0040D1A2 83E1 03 and ecx, 3
0040D1A5 F3:A4 rep movs byte ptr es:[edi], byte >
0040D1A7 EB 26 jmp short note_aPl.0040D1CF 跳走。
0040D1CF 8BB5 E6904000 mov esi, dword ptr ss:[ebp+4090E6>; note_aPl.00400000 到这里。
0040D1D5 56 push esi
0040D1D6 03B5 EE904000 add esi, dword ptr ss:[ebp+4090EE>
0040D1DC 83C6 14 add esi, 14
0040D1DF 03B5 35974000 add esi, dword ptr ss:[ebp+409735>
0040D1E5 8DBD 39974000 lea edi, dword ptr ss:[ebp+409739>
0040D1EB B9 06000000 mov ecx, 6
0040D1F0 F3:A5 rep movs dword ptr es:[edi], dwor>
...........................................
0040D210 8BB5 DE904000 mov esi, dword ptr ss:[ebp+4090DE>
0040D216 80BD 6B9D4000 C>cmp byte ptr ss:[ebp+409D6B], 0C3
0040D21D 74 2E je short note_aPl.0040D24D 跳走。
0040D24D 57 push edi
0040D24E AD lods dword ptr ds:[esi]
0040D24F 85C0 test eax, eax
0040D251 0F84 9B000000 je note_aPl.0040D2F2 这个跳转很大,但是没跳走,先记住,如果下面的语句有往回跳转无法往后继续走,我们再试试这里。
0040D257 8BD0 mov edx, eax
0040D259 0395 E6904000 add edx, dword ptr ss:[ebp+4090E6>
0040D25F AD lods dword ptr ds:[esi]
0040D260 56 push esi
0040D261 8BC8 mov ecx, eax
0040D263 57 push edi
0040D264 52 push edx
0040D265 8DB5 6BA14000 lea esi, dword ptr ss:[ebp+40A16B>
0040D26B 57 push edi
0040D26C 51 push ecx
0040D26D 52 push edx
0040D26E 6A 40 push 40
0040D270 56 push esi
0040D271 FFB5 3D974000 push dword ptr ss:[ebp+40973D]
0040D277 FFB5 39974000 push dword ptr ss:[ebp+409739]
0040D27D E8 B8090000 call note_aPl.0040DC3A
...........................................
0040D2AA /74 07 je short note_aPl.0040D2B3
0040D2AC |8BC8 mov ecx, eax
0040D2AE |5E pop esi
0040D2AF |5F pop edi
0040D2B0 ^|EB 9B jmp short note_aPl.0040D24D 果然往回跳转。
0040D2B2 B9 E8000000 mov ecx, 0E8 F4无法到达这句,程序运行了。
0040D2B7 005D 81 add byte ptr ss:[ebp-7F], bl
0040D2BA ED in eax, dx
Ctrl+F2重新加载程序,重新来到我们刚才发现的0040D251处,回车。
0040D2F2 5F pop edi 到这里,F2下断点,F9运行跳出循环到这里后再F2取消断点。
0040D2F3 8BB5 E2904000 mov esi, dword ptr ss:[ebp+4090E2>
0040D2F9 AD lods dword ptr ds:[esi]
0040D2FA 83F8 FF cmp eax, -1
0040D2FD 74 74 je short note_aPl.0040D373这个跳转很大,但是没跳走,先记住,如果下面的语句有往回跳转无法往后继续走,我们再试试这里。
0040D2FF 0385 E6904000 add eax, dword ptr ss:[ebp+4090E6>
0040D305 8BD8 mov ebx, eax
0040D307 AD lods dword ptr ds:[esi]
0040D308 0385 E6904000 add eax, dword ptr ss:[ebp+4090E6>
...........................................
0040D361 8BD1 mov edx, ecx
0040D363 C1F9 02 sar ecx, 2
0040D366 F3:AB rep stos dword ptr es:[edi]
0040D368 03CA add ecx, edx
0040D36A 83E1 03 and ecx, 3
0040D36D F3:AA rep stos byte ptr es:[edi]
0040D36F 5F pop edi
0040D370 ^ EB 87 jmp short note_aPl.0040D2F9 果然往回跳转。
0040D372 0F6800 punpckhbw mm0, qword ptr ds:[eax] F4无法到达这句,程序运行了。
0040D375 40 inc eax
0040D376 0000 add byte ptr ds:[eax], al
...........................................
Ctrl+F2重新加载程序,重新来到我们刚才发现的0040D2FD处,回车。
0040D373 68 00400000 push 4000 到这里,F2下断点,F9运行跳出循环到这里后再F2取消断点。
0040D378 6A 00 push 0
0040D37A 57 push edi
0040D37B FF95 45974000 call dword ptr ss:[ebp+409745]
0040D381 8BBD 3C964000 mov edi, dword ptr ss:[ebp+40963C>
0040D387 03BD E6904000 add edi, dword ptr ss:[ebp+4090E6>
0040D38D 8B8D 40964000 mov ecx, dword ptr ss:[ebp+409640>
0040D393 51 push ecx
0040D394 57 push edi
0040D395 33D2 xor edx, edx
0040D397 33DB xor ebx, ebx
0040D399 33F6 xor esi, esi
0040D39B 03FE add edi, esi
0040D39D 03DE add ebx, esi
0040D39F 49 dec ecx
0040D3A0 74 72 je short note_aPl.0040D414 可跳出循环。
0040D3A2 78 70 js short note_aPl.0040D414
...........................................
0040D3B5 /75 0A jnz short note_aPl.0040D3C1 跳走。
0040D3B7 |80FC 80 cmp ah, 80
0040D3BA |72 05 jb short note_aPl.0040D3C1
0040D3BC |80FC 8F cmp ah, 8F
0040D3BF |76 05 jbe short note_aPl.0040D3C6
0040D3C1 \47 inc edi
0040D3C2 43 inc ebx
0040D3C3 ^ EB DA jmp short note_aPl.0040D39F 往回跳转。看到0040D3A0可跳出循环。我们在0040D3A0处点一下,然后回车。
0040D414 5F pop edi F2下断点,F9运行跳出循环到这里后再F2取消断点
0040D415 59 pop ecx
0040D416 33C0 xor eax, eax
0040D418 85C9 test ecx, ecx
0040D41A 74 3B je short note_aPl.0040D457
0040D41C 8BF7 mov esi, edi
0040D41E 33C0 xor eax, eax
0040D420 83F9 04 cmp ecx, 4
...........................................
0040D42F 8B1E mov ebx, dword ptr ds:[esi]
0040D431 03C3 add eax, ebx
0040D433 D1E3 shl ebx, 1
0040D435 83D3 01 adc ebx, 1
0040D438 33C3 xor eax, ebx
0040D43A 83C6 04 add esi, 4
0040D43D 83E9 04 sub ecx, 4
0040D440 74 15 je short note_aPl.0040D457
0040D442 83F9 04 cmp ecx, 4
0040D445 ^ 73 E8 jnb short note_aPl.0040D42F往回跳转
0040D447 BA 04000000 mov edx, 4 F4到这里。
0040D44C 2BD1 sub edx, ecx
0040D44E 2BF2 sub esi, edx
0040D450 B9 04000000 mov ecx, 4
0040D455 ^ EB D8 jmp short note_aPl.0040D42F 又往回跳转
0040D457 3B85 67974000 cmp eax, dword ptr ss:[ebp+409767> F4到这里。
0040D45D 74 4D je short note_aPl.0040D4AC 跳走。
0040D45F ^ E9 4FFEFFFF jmp note_aPl.0040D2B3
0040D4AC E8 A1010000 call note_aPl.0040D652 到这里。Call的距离较远,F8过。
0040D4B1 E8 A3000000 call note_aPl.0040D559 Call的距离较远,F8过。
0040D4B6 73 6B jnb short note_aPl.0040D523 跳走。
0040D523 80BD 6B9F4000 C>cmp byte ptr ss:[ebp+409F6B], 0C3
0040D52A 74 22 je short note_aPl.0040D54E 跳。
0040D52C 8D95 6BA14000 lea edx, dword ptr ss:[ebp+40A16B>
0040D532 6A 40 push 40
0040D534 52 push edx
0040D535 FFB5 3D974000 push dword ptr ss:[ebp+40973D]
0040D53B FFB5 39974000 push dword ptr ss:[ebp+409739]
0040D541 E8 F40A0000 call note_aPl.0040E03A
0040D546 85C0 test eax, eax
0040D548 ^ 0F85 9DFDFFFF jnz note_aPl.0040D2EB
0040D54E 61 popad 看到这两个与开始处对应的标志了。
0040D54F 9D popfd 入口点就在附近。
0040D550 50 push eax
0040D551 68 CC104000 push note_aPl.004010CC 
0040D556 C2 0400 retn 4 准备返回到程序入口点,跨段。
004010CC 55 push ebp 入口点,跨段来到这里并且经过了PoPad和popfd两个关键字,我们在这里用Od的 Dump插件直接脱壳。
004010CD 8BEC mov ebp, esp
004010CF 83EC 44 sub esp, 44
004010D2 56 push esi
004010D3 FF15 E4634000 call dword ptr ds:[4063E4] ; kernel32.GetCommandLineA
004010D9 8BF0 mov esi, eax
004010DB 8A00 mov al, byte ptr ds:[eax]
004010DD 3C 22 cmp al, 22
004010DF 75 1B jnz short note_aPl.004010FC
004010E1 56 push esi
004010E2 FF15 F4644000 call dword ptr ds:[4064F4] ; USER32.CharNextA
重建输入表时,插件有两个选项。Method2重建输入表很快,脱壳后运行率高。Method1重建输入表慢,脱壳后运行率较低。不过本程序用Method2重建输入表无法运行,Method1重建输入表后程序可直接运行。
总结:
PECompac加壳程序
入口关键字 有两个。
pushfd 注意PECompactd的壳比UPX,Aspack多了这个指令。
pushad
出口关键字
POPAD 
popfd 和入口关键字对应,过了这两个关键字,要注意程序oep就在附近。
通过Ret返回到程序Oep
经过实践,发现PECompac1.4X-1.8X加壳的程序手动脱壳流程基本相同,这里就不一一列出,大家碰到后请自行参考本文进行练习。
附参考教学。
作者:lordor[BCG] 来源:看雪论坛 加入时间:2003-6-2 
对象:五笔打字通5.0
作者:lordor[BCG]
声明:属技术交流,无其它目的,请不要任意散布或用作商业用途。初学破解,如有不对的地方欢迎批评指出。
工具:ollydbg1.09B,插件ollyDump V2.11.108
基本操作:F8-单步执行,遇到call不进入。F7-单步执行,遇到call进入。F4-执行到光标所在行。F2-设断
手动脱壳要把握两点:
1、单步往前走,不要回头。
2、观察。注意poshad、poshfd,popad、popfd等,注意地址发生大的变化。
程序用PECompact V1.40-45加的壳,没见过的,在这里只好手动脱壳。
0054DC00 > /EB 06 JMP SHORT wb86.0054DC08
0054DC02 |68 84370000 PUSH 3784
0054DC07 |C3 RETN
0054DC08 \9C PUSHFD
0054DC09 60 PUSHAD
0054DC0A E8 02000000 CALL wb86.0054DC11 =>单步走到这里,F8过的话程序就运行,所以要F7跟入
-------------------------------------------------------------------------------
0054DC11 8BC4 MOV EAX,ESP    =>F7后来到这,继续单步运行
0054DC13 83C0 04 ADD EAX,4
0054DC16 93 XCHG EAX,EBX
0054DC17 8BE3 MOV ESP,EBX
0054DC19 8B5B FC MOV EBX,DWORD PTR DS:[EBX-4]
0054DC1C 81EB 0FA04000 SUB EBX,wb86.0040A00F
0054DC22 87DD XCHG EBP,EBX
0054DC24 8B85 A6A04000 MOV EAX,DWORD PTR SS:[EBP+40A0A6]
0054DC2A 0185 03A04000 ADD DWORD PTR SS:[EBP+40A003],EAX
0054DC30 66:C785 00A0400>MOV WORD PTR SS:[EBP+40A000],9090
0054DC39 0185 9EA04000 ADD DWORD PTR SS:[EBP+40A09E],EAX
0054DC3F BB C3110000 MOV EBX,11C3
0054DC44 039D AAA04000 ADD EBX,DWORD PTR SS:[EBP+40A0AA]
0054DC4A 039D A6A04000 ADD EBX,DWORD PTR SS:[EBP+40A0A6]
0054DC50 53 PUSH EBX
0054DC51 53 PUSH EBX
...............(一直往前走,省略).....................
0054F25E 57 PUSH EDI
0054F25F AD LODS DWORD PTR DS:[ESI]
0054F260 0BC0 OR EAX,EAX
0054F262 74 6C JE SHORT wb86.0054F2D0
0054F264 8BD0 MOV EDX,EAX
0054F266 0395 A6A04000 ADD EDX,DWORD PTR SS:[EBP+40A0A6]
0054F26C AD LODS DWORD PTR DS:[ESI]
0054F26D 56 PUSH ESI
0054F26E 8BC8 MOV ECX,EAX
0054F270 57 PUSH EDI
0054F271 52 PUSH EDX
0054F272 8BF2 MOV ESI,EDX
0054F274 8B85 15A64000 MOV EAX,DWORD PTR SS:[EBP+40A615]
0054F27A 8B9D 19A64000 MOV EBX,DWORD PTR SS:[EBP+40A619]
0054F280 E8 910A0000 CALL wb86.0054FD16
0054F285 5A POP EDX
0054F286 5F POP EDI
0054F287 52 PUSH EDX
0054F288 57 PUSH EDI
0054F289 FF95 9EA04000 CALL DWORD PTR SS:[EBP+40A09E]
0054F28F 0BC0 OR EAX,EAX
0054F291 74 07 JE SHORT wb86.0054F29A
0054F293 8BC8 MOV ECX,EAX
0054F295 5E POP ESI
0054F296 5F POP EDI
0054F297 ^ EB C5 JMP SHORT wb86.0054F25E  ==>走到这里会跳到前面,把光标移动到下一行,F4跳过时程序会直接运行,所以还得单步运行,走到上面的0054F262处会跳到后面去了
0054F299 B9 8D9D97A5 MOV ECX,A5979D8D
0054F29E 40 INC EAX
0054F29F 0053 FF ADD BYTE PTR DS:[EBX-1],DL
0054F2A2 95 XCHG EAX,EBP
0054F2A3 15 A640008D ADC EAX,8D0040A6
0054F2A8 9D POPFD
...............(一直往前走,省略).....................
0054F2CF 24 58 AND AL,58  ==>从上面跳到这,继续单步走
0054F2D1 8DB5 C3A64000 LEA ESI,DWORD PTR SS:[EBP+40A6C3]
0054F2D7 AD LODS DWORD PTR DS:[ESI]
0054F2D8 0BC0 OR EAX,EAX
0054F2DA 74 74 JE SHORT wb86.0054F350
0054F2DC 0385 A6A04000 ADD EAX,DWORD PTR SS:[EBP+40A0A6]
...............(一直往前走,省略).....................
0054F36D 49 DEC ECX
0054F36E 74 72 JE SHORT wb86.0054F3E2
0054F370 78 70 JS SHORT wb86.0054F3E2
0054F372 66:8B07 MOV AX,WORD PTR DS:[EDI]
0054F375 2C E8 SUB AL,0E8
0054F377 3C 01 CMP AL,1
0054F379 76 38 JBE SHORT wb86.0054F3B3
0054F37B 66:3D 1725 CMP AX,2517
0054F37F 74 51 JE SHORT wb86.0054F3D2
0054F381 3C 27 CMP AL,27
0054F383 75 0A JNZ SHORT wb86.0054F38F
0054F385 80FC 80 CMP AH,80
0054F388 72 05 JB SHORT wb86.0054F38F
0054F38A 80FC 8F CMP AH,8F
0054F38D 76 05 JBE SHORT wb86.0054F394
0054F38F 47 INC EDI
0054F390 43 INC EBX
0054F391 ^ EB DA JMP SHORT wb86.0054F36D ==>这里又跳到前面,看一下前面那一句会跳到后面的,是JE SHORT 0054F3E2,JS SHORT 0054F3E2,JBE SHORT wb86.0054F3B3,JE SHORT 0054F3D2,依次在其跳往的地方设断。F9运行,会在设断的地方停,最后确定0054F3E2才是正确的设断地方
0054F393 B8 8B47023C MOV EAX,3C02478B
...............(一直往前走,省略).....................
0054F476 8BB5 15A64000 MOV ESI,DWORD PTR SS:[EBP+40A615]
0054F47C 8BBD 19A64000 MOV EDI,DWORD PTR SS:[EBP+40A619]
0054F482 E8 8F0C0000 CALL wb86.00550116
0054F487 61 POPAD ==>看到希望了,继续单步走
0054F488 9D POPFD 
0054F489 50 PUSH EAX
0054F48A 68 84374000 PUSH wb86.00403784
0054F48F C2 0400 RETN 4 ==>走过这里,地址会有很大变化,可以确定,壳已脱完了。
0054F492 8BB5 37A64000 MOV ESI,DWORD PTR SS:[EBP+40A637]
00403781 00 DB 00
00403782 > 0000 ADD BYTE PTR DS:[EAX],AL
00403784 . 68 94FF4300 PUSH wb86.0043FF94  ===>由0054F48F处跳来,在这里运行ollyDump把
程序dump下来。到此手动脱壳结束。
00403789 E8 DB E8
0040378A EE DB EE
0040378B FF DB FF
0040378C FF DB FF
0040378D FF DB FF
0040378E 00 DB 00
0040378F 00 DB 00
00403790 00 DB 00
00403791 00 DB 00
00403792 00 DB 00
脱完后可以用侦壳工具看,是用VB写的。其它壳(如Aspack等)都可以用此法配合OLLYDUMP来手动脱壳.
"手动脱壳入门第六篇"脱壳动画!