PESHiELD V0.25完美脱壳——PESHIELD.eXe主程序
            
           
             
下载地址:  http://protools.reverse-engineering.net/files/packers/peshield.zip
软件大小:  32 KB  
软件简介:  PE-SHiELD is a program, which encrypts 32-bit Windows EXE files, leaving them still executable. The previous version was over a year in the wild and there is still no unpacker for it. 
             
【作者声明】:只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教
             
【调试环境】:WinXP、OllyDbg、PEiD、LordPE
             
————————————————————————————————— 
【脱壳过程】:
          
         
PESHiELD是ANAKiN在2000年发布的壳,虽然比较老,但是依旧有值得研究的地方。
2003年我曾经写过脱PESHiELD加壳记事本的记录,当时应该没有使用-ip、-api参数加壳,使得脱壳很简单。现在回过头来重新脱一下PESHiELD V0.25主程序,算是一点补充吧。
—————————————————————————————————
一、点过第一层壳
             

PESHIELD.eXe主程序加了两层壳,所以我们直接去脱第2层PESHiELD就行了。            
设置OllyDbg忽略所有异常选项。用IsDebug插件去掉OllyDbg的调试器标志。

0040B000    60              pushad
//进入OllyDbg后暂停在这
0040B001    E8 2B000000     call 0040B031
0040B006    0D 0A0D0A0D     or eax,0D0A0D0A

Alt+M打开内存察看窗口,在401000第2区段设置“内存访问断点”
Shift+F9,中断在解码的地方,清除这个断点

0040B99A    3107            xor dword ptr ds:[edi],eax
//中断在这里
0040B99C    EB 02           jmp short 0040B9A0

Ctrl+F在当前位置下搜索命令:jmp eax    找到0040BC3B处,下断

0040BC3B    FFE0            jmp eax  ; PESHIELD.00408000
//Shift+F9中断后取消断点,进入第2层PESHiELD壳


—————————————————————————————————
二、去掉重定位处理


PESHiELD是较早通过重定位表对跳转地址动“手脚”的壳。
00402C59    FF25 98003C00   jmp dword ptr ds:[3C0098]
00402C5F    FF25 9C003C00   jmp dword ptr ds:[3C009C]
00402C65    FF25 A0003C00   jmp dword ptr ds:[3C00A0]
00402C6B    FF25 A4003C00   jmp dword ptr ds:[3C00A4]
如果不处理的话,地址被重定位无法修复,所以要想办法去掉壳对其的重定位处理。

00408000    60              pushad
//第2层PESHiELD入口
00408001    E8 2B000000     call 00408031

Alt+M打开内存察看窗口,在401000第2区段设置“内存访问断点”
Shift+F9,中断在解码的地方,清除这个断点

0040899A    3107            xor dword ptr ds:[edi],eax
//中断在这里
0040899C    EB 02           jmp short 004089A0

Ctrl+F在当前位置下搜索命令:or esi,esi
找到在00408A72处,在其上的00408A54处下断,Shift+F9中断后清除断点

00408A54    8B95 27120000   mov edx,dword ptr ss:[ebp+1227]
//[ebp+1227]=003C0000      壳重定位后的ImPort Table VA
00408A5A    2B95 1F120000   sub edx,dword ptr ss:[ebp+121F]
//[ebp+121F]=00406000      原来的ImPort Table VA  ★
00408A60    0395 A7120000   add edx,dword ptr ss:[ebp+12A7]
00408A66    8995 2B120000   mov dword ptr ss:[ebp+122B],edx
00408A6C    8BB5 67120000   mov esi,dword ptr ss:[ebp+1267]
//[ebp+1267]=00007000      重定位表的偏移
00408A72    0BF6            or esi,esi
//找到这里
00408A74    74 33           je short 00408AA9
/修改标志位Z=1让这里跳转,强制其不进行重定位处理  ★
00408A76    03B5 A7120000   add esi,dword ptr ss:[ebp+12A7]
00408A7C    83C6 10         add esi,10
00408A7F    8B95 27120000   mov edx,dword ptr ss:[ebp+1227]
00408A85    2B95 A3120000   sub edx,dword ptr ss:[ebp+12A3]
00408A8B    0BD2            or edx,edx
00408A8D    74 05           je short 00408A94
00408A8F    E8 54040000     call 00408EE8
//重定位处理
00408A94    8B95 A7120000   mov edx,dword ptr ss:[ebp+12A7]
00408A9A    2B95 AF120000   sub edx,dword ptr ss:[ebp+12AF]
00408AA0    0BD2            or edx,edx
00408AA2    74 05           je short 00408AA9
00408AA4    E8 3F040000     call 00408EE8
//重定位处理


—————————————————————————————————
三、完美修复输入表


00408AD6    8B8D A7120000   mov ecx,dword ptr ss:[ebp+12A7]
00408ADC    8B95 27120000   mov edx,dword ptr ss:[ebp+1227]
00408AE2    8B42 0C         mov eax,dword ptr ds:[edx+C]
00408AE5    0BC0            or eax,eax
00408AE7    0F84 F3000000   je 00408BE0
//输入表处理完毕则挑转
00408AED    894A 0C         mov dword ptr ds:[edx+C],ecx
//修改①: NOP掉填充
00408AF0    0385 2B120000   add eax,dword ptr ss:[ebp+122B]
00408AF6    52              push edx
00408AF7    51              push ecx
00408AF8    50              push eax
00408AF9    50              push eax
00408AFA    C685 1D120000 0>mov byte ptr ss:[ebp+121D],0
00408B01    8B18            mov ebx,dword ptr ds:[eax]
00408B03    81E3 DFDFDF00   and ebx,0DFDFDF
00408B09    81FB 4D464300   cmp ebx,43464D
00408B0F    75 18           jnz short 00408B29
00408B11    8B58 05         mov ebx,dword ptr ds:[eax+5]
00408B14    81E3 FFDFDFDF   and ebx,DFDFDFFF
00408B1A    81FB 2E444C4C   cmp ebx,4C4C442E
00408B20    75 07           jnz short 00408B29
00408B22    C685 1D120000 0>mov byte ptr ss:[ebp+121D],1
00408B29    8BD8            mov ebx,eax
00408B2B    E8 DDFBFFFF     call 0040870D
//GetModuleHandleA
00408B30    5B              pop ebx
00408B31    59              pop ecx
00408B32    5A              pop edx
00408B33    0BC0            or eax,eax
00408B35    75 12           jnz short 00408B49
00408B37    52              push edx
00408B38    51              push ecx
00408B39    53              push ebx
00408B3A    E8 D9FBFFFF     call 00408718
00408B3F    0BC0            or eax,eax
00408B41    0F84 42FCFFFF   je 00408789
00408B47    59              pop ecx
00408B48    5A              pop edx
00408B49    E8 EF000000     call 00408C3D
//清除使用过的DLL名    进入修改
00408B4E    8985 AE0B0000   mov dword ptr ss:[ebp+BAE],eax
00408B54    8B32            mov esi,dword ptr ds:[edx]
00408B56    890A            mov dword ptr ds:[edx],ecx
//修改②: NOP掉填充
00408B58    8B7A 10         mov edi,dword ptr ds:[edx+10]
00408B5B    894A 10         mov dword ptr ds:[edx+10],ecx
//修改③: NOP掉填充
00408B5E    0BF6            or esi,esi
00408B60    75 02           jnz short 00408B64
00408B62    8BF7            mov esi,edi
00408B64    03B5 2B120000   add esi,dword ptr ss:[ebp+122B]
00408B6A    03BD 2B120000   add edi,dword ptr ss:[ebp+122B]
00408B70    8B06            mov eax,dword ptr ds:[esi]
00408B72    0BC0            or eax,eax
00408B74    74 62           je short 00408BD8
00408B76    890E            mov dword ptr ds:[esi],ecx
//修改④: NOP掉填充
00408B78    79 05           jns short 00408B7F
00408B7A    0FB7C0          movzx eax,ax
00408B7D    EB 26           jmp short 00408BA5
00408B7F    0385 2B120000   add eax,dword ptr ss:[ebp+122B]
00408B85    66:C700 0000    mov word ptr ds:[eax],0
//修改⑤: NOP掉函数序号清零
00408B8A    40              inc eax
00408B8B    40              inc eax
00408B8C    53              push ebx
00408B8D    56              push esi
00408B8E    50              push eax
00408B8F    8B9D 87120000   mov ebx,dword ptr ss:[ebp+1287]
00408B95    8BF0            mov esi,eax
00408B97    E8 A8030000     call 00408F44
//解码出函数名
00408B9C    899D 87120000   mov dword ptr ss:[ebp+1287],ebx
00408BA2    58              pop eax
00408BA3    5E              pop esi
00408BA4    5B              pop ebx
00408BA5    50              push eax
00408BA6    52              push edx
00408BA7    56              push esi
00408BA8    57              push edi
00408BA9    51              push ecx
00408BAA    53              push ebx
00408BAB    50              push eax
00408BAC    50              push eax
00408BAD    68 78563412     push 12345678
00408BB2    E8 6CFBFFFF     call 00408723
//GetProcAddress
00408BB7    5B              pop ebx
00408BB8    0BC0            or eax,eax
00408BBA    0F84 12FCFFFF   je 004087D2
00408BC0    E8 78000000     call 00408C3D
//清除使用过的函数名    进入修改
00408BC5    5B              pop ebx
00408BC6    59              pop ecx
00408BC7    5F              pop edi
00408BC8    E8 87000000     call 00408C54
//填充系统函数地址或者加密地址    进入修改
00408BCD    5E              pop esi
00408BCE    5A              pop edx
00408BCF    5B              pop ebx
00408BD0    83C6 04         add esi,4
00408BD3    83C7 04         add edi,4
00408BD6    EB 98           jmp short 00408B70
00408BD8    83C2 14         add edx,14
00408BDB    E9 02FFFFFF     jmp 00408AE2
//循环处理
00408BE0    EB 01           jmp short 00408BE3
//这里下断

————————————————————————
1、清除使用过的DLL名、函数名

00408C3D    C1CB 10         ror ebx,10
00408C40    66:0BDB         or bx,bx
00408C43    74 0E           je short 00408C53
00408C45    C1CB 10         ror ebx,10
00408C48    803B 00         cmp byte ptr ds:[ebx],0
00408C4B    74 06           je short 00408C53
//修改⑥:jmp 00408C53
00408C4D    C603 43         mov byte ptr ds:[ebx],43
00408C50    43              inc ebx
00408C51    EB F5           jmp short 00408C48
00408C53    C3              retn

————————————————————————
2、填充系统函数地址或者加密地址

00408C54    80BD 1D120000 0>cmp byte ptr ss:[ebp+121D],1
00408C5B    74 09           je short 00408C66
00408C5D    80BD 1A120000 0>cmp byte ptr ss:[ebp+121A],0
00408C64    75 03           jnz short 00408C69
00408C66    8907            mov dword ptr ds:[edi],eax
//修改⑦:NOP     填充系统函数地址或者加密地址
00408C68    C3              retn

修改完毕后在00408BE0处下断,Shift+F9中断后输入表处理完毕
现在我们直接在OllyDbg里面复制003C0000-003C0264处的2进制代码,粘贴进原来的ImPort Table VA=00406000处。


—————————————————————————————————
四、结局:OEP、PE修正、完成脱壳


搞定输入表后下面就开始走OEP了

00408BE3    8B85 47120000   mov eax,dword ptr ss:[ebp+1247]
00408BE9    EB 02           jmp short 00408BED
00408BED    3385 9F120000   xor eax,dword ptr ss:[ebp+129F]
//EAX=11362854 XOR 113602DC=00002A88   计算出OEP RVA  ★
00408BF3    EB 02           jmp short 00408BF7
00408BF7    0385 A7120000   add eax,dword ptr ss:[ebp+12A7]
00408BFD    EB 01           jmp short 00408C00
00408C00    894424 1C       mov dword ptr ss:[esp+1C],eax
00408C04    EB 03           jmp short 00408C09
00408C09    8DBD 3D0C0000   lea edi,dword ptr ss:[ebp+C3D]
00408C0F    EB 03           jmp short 00408C14
00408C14    B9 07070000     mov ecx,707
00408C19    EB 01           jmp short 00408C1C
00408C1C    32C0            xor al,al
00408C1E    EB 02           jmp short 00408C22
00408C22    F3:AA           rep stos byte ptr es:[edi]
//清扫战场
00408C24    EB 01           jmp short 00408C27
00408C27    8BFD            mov edi,ebp
00408C29    EB 02           jmp short 00408C2D
00408C2D    B9 350C0000     mov ecx,0C35
00408C32    EB 01           jmp short 00408C35
00408C35    F3:AA           rep stos byte ptr es:[edi]
//清扫战场
00408C37    61              popad
00408C38    EB 01           jmp short 00408C3B
00408C3B    FFE0            jmp eax  ; PESHIELD.00402A88
//飞向光明之巅


00402A88    E8 1EE7FFFF     call 004011AB
//OEP
00402A8D    E8 4BE7FFFF     call 004011DD
00402A92    E8 69E5FFFF     call 00401000

运行LordPE纠正ImageSize后完全Dump这个进程存为dumped.exe
修正其OEP RVA=00002A88、ImPort Table RVA=00006000
再删掉壳区段,清除壳数据。主程序没有资源,其它有的一般要恢复几个图标资源。
马马虎虎算是一个“完美脱壳”吧。
               
             
—————————————————————————————————                                    
         ,     _/ 
        /| _.-~/            \_     ,        青春都一晌
       ( /~   /              \~-._ |\
       `\\  _/                \   ~\ )          忍把浮名 
   _-~~~-.)  )__/;;,.          \_  //'
  /'_,\   --~   \ ~~~-  ,;;\___(  (.-~~~-.        换了脱壳轻狂
 `~ _( ,_..--\ (     ,;'' /    ~--   /._`\ 
  /~~//'   /' `~\         ) /--.._, )_  `~
  "  `~"  "      `"      /~'`\    `\\~~\   
                         "     "   "~'  ""
    
              UnPacKed By :  fly
               2005-05-17 18:00