概述
脫殼是一項綜合技術,結合PE檔案格式、彙編指令的分析,調試加密的程式并将其還 原的一個過程。
殼一般分為兩種,加密殼和壓縮殼,裡面所使用的技術有,壓縮算法、對代碼加密、 對IAT加密、對資源加密。
我們從簡單入手壓縮殼
關于壓縮算法
- 有損壓縮 一個像素點:RGB 紅綠藍 一個圖檔:(3,4,5),(4,5,3),(5,4,3) 壓縮後:(4,4,4),3
- 無損壓縮 一個檔案:0,0,0,0,0,0,0 壓縮後:0,7
脫殼三步法
- 尋找原始OE
- dump記憶體到檔案
- 修複檔案
脫殼三步法尋址OEP技巧
- 堆棧平衡法(ESP定律) 殼代碼就像一個函數,進入時會開辟堆棧、儲存寄存器環境,退出時會恢複堆 棧、恢複寄存器。是以應該是堆棧平衡的,那我們可以在殼代碼操作了堆棧後對 堆棧設定通路或寫入斷點,然後運作程式,當斷點命中的時候,應該就是退出殼 代碼的時候。在其附近單步幾次,應該就能到達程式的原始OEP。
- 特征定位法 在我們熟悉的程式中,我們可以使用特征來定位程式原始OEP。特征有幾種: ① 二進制特征 比如release版的VS2013是: E8????????E9 ② API特征 比如release版的VS2013的第一個API調用是: GetSystemTimeAsFileTime 比如vc6.0的第一個API調用是: GetVersion 比如Delphi程式第一個API調用是: GetModuleHandleA
- 單步跟蹤法 這種方法一般使用在分析自己加殼的程式或者是練習分析殼時。
脫殼0.aspack.exe
- 用010Editor把重定位關閉
- 尋址OEP ESP定律
- 跑到入口點的位置再dump
- dump記憶體
脫殼1
RVA這個測試程式用的是0.
注意:如果程式有随機基址,脫殼後需要把随機基址标志位置0.
殼代碼的基本流程
① 儲存寄存器環境
② 加載一些必要的API
③ 解密代碼和資料
④ 修複重定位
⑤ 填充IAT
⑥ 恢複寄存器環境
分析殼代碼0.aspack.exe
① 殼OEP
② 加載必要API
③ 解密解壓縮代碼
④ 修複重定位
修複重定位的公式:
重定位表中存儲兩個有用字段:
- 需要重定位的分頁位址
-
需要重定位的分頁偏移
重定位分為兩步:
- 計算出 重定位位址,要重定位的位址=子產品基位址+分頁位址+分頁偏移
- 修複要重定位的位址中資料,[要重定位的位址] 預設子產品基位址 + 目前子產品基 位址
-
填充IAT
原理:
① 從導入表中擷取dll名稱
② 從導入表中的INT,擷取函數名稱或者序号 ③ 通過GetModuleHandleA或者LoadLibraryA擷取子產品基位址 通過GetProcAddress擷取函數位址
④ 将函數位址填充到對應IAT數組中
001D726F 03F2 ADD ESI,EDX ; esi=導 入表結構
001D7271 8B46 0C MOV EAX,DWORD PTR DS:[ESI+0xC] ; 擷取模 塊DLL名稱RVA
001D7274 85C0 TEST EAX,EAX
001D7276 0F84 0D010000 JE 00_aspac.001D7389
001D727C 03C2 ADD EAX,EDX ; 加上基 位址,字元串VA
001D727E 8BD8 MOV EBX,EAX
001D7280 50 PUSH EAX
001D7281 FF95 A90F0000 CALL DWORD PTR SS:[EBP+0xFA9] ; 擷取模 塊基位址
001D7287 85C0 TEST EAX,EAX
001D7289 75 07 JNZ SHORT 00_aspac.001D7292
001D728B 53 PUSH EBX
001D728C FF95 AD0F0000 CALL DWORD PTR SS:[EBP+0xFAD]
001D7292 8985 A9050000 MOV DWORD PTR SS:[EBP+0x5A9],EAX ; 儲存模 塊基位址
001D7298 C785 AD050000>MOV DWORD PTR SS:[EBP+0x5AD],0x0
001D72A2 8B95 88040000 MOV EDX,DWORD PTR SS:[EBP+0x488] ; 擷取基 位址
001D72A8 8B06 MOV EAX,DWORD PTR DS:[ESI] ; 擷取指 向OrignalFirstThunk RVA
001D72AA 85C0 TEST EAX,EAX
001D72AC 75 03 JNZ SHORT 00_aspac.001D72B1
001D72AE 8B46 10 MOV EAX,DWORD PTR DS:[ESI+0x10]
001D72B1 03C2 ADD EAX,EDX ; 計算出 OrignalFirstThunk VA
001D72B3 0385 AD050000 ADD EAX,DWORD PTR SS:[EBP+0x5AD] ; 0
001D72B9 8B18 MOV EBX,DWORD PTR DS:[EAX] ; 擷取 INT中的資料,即指向函數名稱的 RVA
001D72BB 8B7E 10 MOV EDI,DWORD PTR DS:[ESI+0x10] ; 擷取 FirstThunk
001D72BE 03FA ADD EDI,EDX ; 計算得 出 IAT 位址
001D72C0 03BD AD050000 ADD EDI,DWORD PTR SS:[EBP+0x5AD] ; 0
001D72C6 85DB TEST EBX,EBX ; 判斷結 束
001D72C8 0F84 A5000000 JE 00_aspac.001D7373
001D72CE F7C3 00000080 TEST EBX,0x80000000 ; 判斷是 否是序号
001D72D4 75 04 JNZ SHORT 00_aspac.001D72DA
001D72D6 03DA ADD EBX,EDX ; 指向函 數字元串結構=INT[i]+子產品基位址
001D72D8 43 INC EBX ; 減去 2,跳過字元串結構的序号
001D72D9 43 INC EBX
001D72DA 53 PUSH EBX ; 儲存寄 存器環境
001D72DB 81E3 FFFFFF7F AND EBX,0x7FFFFFFF
001D72E1 53 PUSH EBX ; 壓入字 符串或是序号
001D72E2 FFB5 A9050000 PUSH DWORD PTR SS:[EBP+0x5A9]
001D72E8 FF95 A50F0000 CALL DWORD PTR SS:[EBP+0xFA5] ; 擷取函 數位址
001D72EE 85C0 TEST EAX,EAX
001D72F0 5B POP EBX ; 恢複寄 存器環境
⑤ 修改屬性,跳轉原始OEP