[轉] 菜鳥手脫VMP,附上脫殼過程和自己寫的腳本,可跨平台


轉載:http://www.52pojie.cn/thread-467703-1-1.html

工作需要要脫一個VMP殼,我是一個從來沒接觸過脫殼的人。瞬間那種心情遇到的人應該都知道!沒辦法硬着頭皮找教程,7天看完了 《天草的殼的世界》嘗試脫殼下面是我的脫殼過程希望大牛多多指正!
1、准備工具,FEID(查殼工具)、DIE(查殼工具)、LordPE(dump工具)、ImpRec(IAT修復工具)、UIF(IAT修復工具)、CFF(文件優化工具)、OD(吾愛破解專版 調試工具)
2、查殼 PEID
 
區段顯示是vmp1,看來是VMP殼編寫語言還是不能確定上DIE
 
顯示編程語言是VC++的,VMP殼
3、開OD准備脫殼、OD設置如下

 

 
打開進程到入口看下
 
4、跑OEP
啥也卡不懂,不過沒關系知道是VMP殼就好辦,直接CTRL+G  輸入 VirtualProtect 下斷 如下圖(如果提示未知,先在內存窗口找到 kernel32.dll代碼段 進去后在轉到就到了)
 
F9跑起來,這是會段下
 
注意NewProtect 這項 等於 PAGE_READONLY 是停下,否則一直F9 按慢點別跑飛了
 
到0401000處看看,代碼是否已經解碼
 
已經解碼, 搜索特征碼 EB0B85F375078BC6C1E0100BF0
 
這是OEP第一個CALL的尾部,根據他找到OEP 
 
OEP 就是 00a6f7c8,不過這才是第一步 這時候DUMP 是沒用的 因為VMP加密了IAT 我們需要還原他
5、還原IAT
隨便找一個IAT調用函數跟一下,剛好OEP下面就有兩個 FF25 型的IAT 調用,跟進去看下
 
還是啥都看不懂,不過沒關系 既然是調用IAT函數,肯定會在某一時刻調到真實函數地址去的 繼續跟下面把整個跟的流程貼上來
 
 
 
 
 
這是整個流程的實際執行的代碼 ,現在分析下
01059D91    53              push ebx                     保護環境
01059D92    66:0FB6DB       movzx bx,bl          垃圾代碼
01059D96    66:BB 5D55      mov bx,0x555D   垃圾代碼
01059D9A    BB 5AC27200     mov ebx,0072C25A   這才是最終對EBX操作所以上面兩條都是沒用的代碼
00F3BBFF    8B9B 25697400   mov ebx,dword ptr ds:[ebx+0x746925]    計算地址
01196B98    8D9B 5071F632   lea ebx,dword ptr ds:[ebx+0x32F67150]  計算地址
00EA9FC2    871C24          xchg dword ptr ss:[esp],ebx   和棧頂交換,並還原EBX的原始值
00F9FC9D    C2 0400         retn 0x4                  還原EBX 並返回函數
這時候看下堆棧 棧頂出現真實函數的地址
<ignore_js_op> 
00F9FC9D    C2 0400         retn 0x4       分析下這條指令的執行流程,先EIP=棧頂的值 也就是真實函數地址,棧頂+4+4 懂匯編的人就會發現,棧頂+8的位置保存是當前CALL的返回地址 那執行了這條指令后返回地址不是沒有了么?因為這個IAT調用 沒加密前是 FF25型的 也就是 jmp [????????] 所以不需要返回地址 ,而調用這個IAT的時候 是有一個CALL的進CALL的時候就會PUSH返回地址到堆棧,所以這個IAT處理的很巧妙!執行完真實函數后直接就返回到調用IATCALL的下面繼續執行了。
看圖片發現 這個CALL 下面有一條 RETN指令 看來這條 是VMP加上去的了,但是不要忽略了這條指令 因為這條指令很重要,VMP在獲取 IAT地址的最后RETN的地址 會隨機JMP到代碼他添加的RETN 上,並不完全是在殼段 所以這個RETN 要留到最后處理。
再找一個FF25 型的IAT調用看看
 
跟進去看下,下面是執行流程代碼
00FB7DC7    90              nop
00FB7DC8    0FB7D6          movzx edx,si        垃圾代碼
00FB7DCB    66:0FBED1       movsx dx,cl       垃圾代碼
00FB7DCF    5A              pop edx                   出棧                
00FB7DD0    871424          xchg dword ptr ss:[esp],edx           交換棧頂的值,還原 EDX原始值
00FB7DD3    52              push edx                              保護環境
00FB7DD4    66:0FBED1       movsx dx,cl     垃圾
00FB7DD8    0FB7D6          movzx edx,si      垃圾
00FB7DDB    BA B7757D00     mov edx,007D75B7     計算地址
010DFDAD    8B92 3D036900   mov edx,dword ptr ds:[edx+0x69033D]    計算地址
0102B837    8D92 B52FE512   lea edx,dword ptr ds:[edx+0x12E52FB5]     計算地址
00EACB30    871424          xchg dword ptr ss:[esp],edx   函數真實地址給棧頂 並還原環境          
0115D36E    C2 0400         retn 0x4 
這個FF25 CALL 的第四行 有個POP  edx 而進這個CALL之前  有一個push edx ,可以看出 這個push edx 也是垃圾代碼是 VMP自己添加上去的,看來VMP 會隨機在上下 填充一個字節,在上面就是 PUSH 一個寄存器,在下面就是 retn
找一個 FF15型的CALL看看
 
跟進去看下流程
010B27B9    BE B34E6E0B     mov esi,0xB6E4EB3    垃圾代碼
00EFFC5B    5E              pop esi               出棧
00EEB9B0    873424          xchg dword ptr ss:[esp],esi    交換棧頂的值,還原 ESI原始值
00F437BB    56              push esi   保存環境
00F8D827    BE 4B084800     mov esi,0048084B    計算地址
00FA55B3    8BB6 C005B900   mov esi,dword ptr ds:[esi+0xB905C0]  計算地址
010E8053    8DB6 3F68AD31   lea esi,dword ptr ds:[esi+0x31AD683F] 計算地址
00F44191    873424          xchg dword ptr ss:[esp],esi   真實函數地址給棧頂,還原環境
0057A761    C3              retn 
第二行 pop esi  看來這個CALL 的push esi 是垃圾指令了,但是 發現這個 是retn 為什么不是,retn 04 呢?因為這個是 FF15 型調用,也就是 call [????????]  需要執行完后返回到call 下面繼續執行
再找一個FF15型調用看看
 
跟進去看下流程
00E77D14    90              nop
00E77D15    51              push ecx            保存環境              
00E77D16    66:F7D1         not cx           垃圾代碼
00E77D19    8B4C24 04       mov ecx,dword ptr ss:[esp+0x4]    棧頂+4(調用CALL的返回地址)給ECX,
00FB7CFF    8D49 01         lea ecx,dword ptr ds:[ecx+0x1]   取 返回地址+1的值 給ECX
01013FB5    894C24 04       mov dword ptr ss:[esp+0x4],ecx  重新寫入到返回處
01013FB9    B9 A1598A00     mov ecx,008A59A1 計算地址
010566B2    8B89 94C36C00   mov ecx,dword ptr ds:[ecx+0x6CC394] 計算地址
00E95200    8D89 19378077   lea ecx,dword ptr ds:[ecx+0x77803719] 計算地址
00FEA363    870C24          xchg dword ptr ss:[esp],ecx  真實函數地址給棧頂,還原環境       
010ABADE    C3              retn
這個 有點不一樣啊,很簡單 看調用CALL 的下面有一個 RETN啊,這要是正常返回 程序還不得跑飛啊,VMP巧妙的利用 4 5 6三行代碼 就搞定了,這寫殼的人真是腦洞大開啊!
所有的IAT加密就這樣完了嗎??? NO  還有更腦洞大開的 往下看
 
跟進去看看
0119D768    90              nop
0106B2C9    872C24          xchg dword ptr ss:[esp],ebp           交換棧頂的值,還原棧頂
00F3E26F    55              push ebp                              保存返回地址
00F3E270    F7D5            not ebp                               垃圾代碼
00F3E272    50              push eax                              保存環境
00F3E273    B8 D41D4300     mov eax,00431DD4  計算地址
00F3E278    66:8BEB         mov bp,bx  垃圾代碼
00F3E27B    8B80 41F7BE00   mov eax,dword ptr ds:[eax+0xBEF741]  計算地址
00F3E281    66:0F4FE8       cmovg bp,ax  垃圾代碼
00F3E285    66:8BE8         mov bp,ax   垃圾代碼
00F3E288    8D80 903F170C   lea eax,dword ptr ds:[eax+0xC173F90]  計算地址
00F3E28E    0FB7E8          movzx ebp,ax 垃圾代碼
00F3E291    8BE8            mov ebp,eax     真實函數地址給 EBP
00F3E293    58              pop eax   還原 寄存器
011B5D71    C3              retn
這是在干啥呢?? 咋把真實函數地址 給了 EBP呢? 看調用處的下面 有一個 call ebp 明白了吧 這是把   mov xx,[????????]  整成了一個CALL哦,再來看下堆棧 調用處pop  EBP , CALL內 第2行 有把棧頂的值還原了,然后把函數的返回地址重新PUSH進去,這里處理的很巧妙,所有 調用處的 pop ebp也是垃圾指令,這就完了???NO還有往下看
 
跟進去看下
00E97E5D    90              nop
00E97E5E    0FBFDB          movsx ebx,bx  垃圾代碼
010C1083    50              push eax                    保存環境     
010C1084    8B4424 04       mov eax,dword ptr ss:[esp+0x4]      獲取當前CALL的返回地址給EAX
00E2EB3F    8D40 01         lea eax,dword ptr ds:[eax+0x1]   獲取當前CALL返回地址+1給EAX
00E2EB42    0F45DB          cmovne ebx,ebx    垃圾代碼
00E2EB45    66:0FB6DB       movzx bx,bl  垃圾代碼
00E2EB49    894424 04       mov dword ptr ss:[esp+0x4],eax  保存返回地址
00E2EB4D    B8 012C4300     mov eax,00432C01 計算地址
00E2EB52    66:0FBEDB       movsx bx,bl 垃圾代碼
00E2EB56    66:8BDF         mov bx,di 垃圾代碼
01170378    8B80 F58CC000   mov eax,dword ptr ds:[eax+0xC08CF5] 計算地址
0117037E    0FB7DC          movzx ebx,sp 垃圾代碼
01170381    0F41DE          cmovno ebx,esi      垃圾代碼
01170384    F6D7            not bh 垃圾代碼
01170386    8D80 145A2C32   lea eax,dword ptr ds:[eax+0x322C5A14] 計算地址
0117038C    B3 85           mov bl,0x85 垃圾代碼
0117038E    8ADE            mov bl,dh 垃圾代碼
01170390    8BD8            mov ebx,eax   真實函數地址給 EBX              
01170392    0FBFC2          movsx eax,dx 垃圾代碼
01170395    C6C4 E2         mov ah,0xE2 垃圾代碼
01170398    0FC8            bswap eax             垃圾代碼            
0117039A    58              pop eax      還原環境                    
0117039B    C3              retn
認真看 了上面的部分,這里不難理解了吧, 4 5 8行處理調用處的 下面 retn 的,函數是獲取 EBX的調用值的

一共6種 IAT相關的處理,所以我是 一邊寫腳本一邊罵寫 VMP殼的人,要不要這么坑啊,我要的脫的程序特別大 跑一遍要 1個小時,我也不記得我跑了多少遍了!哎!說來都是淚,新手就是這樣啊!不多說了下面貼上腳本!需要的自己去下!

6、用UIf 修復IAT 
7、用lodepe dump
8、用imprec 修復IAT
9、用cff 去掉殼段
至此VMP脫殼完成!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM