天天看點

脫殼1

概述

脫殼是一項綜合技術,結合PE檔案格式、彙編指令的分析,調試加密的程式并将其還 原的一個過程。

殼一般分為兩種,加密殼和壓縮殼,裡面所使用的技術有,壓縮算法、對代碼加密、 對IAT加密、對資源加密。

我們從簡單入手­壓縮殼

關于壓縮算法

  1. 有損壓縮 一個像素點:RGB 紅綠藍 一個圖檔:(3,4,5),(4,5,3),(5,4,3) 壓縮後:(4,4,4),3
  2. 無損壓縮 一個檔案:0,0,0,0,0,0,0 壓縮後:0,7

脫殼三步法

  1. 尋找原始OE
  2. dump記憶體到檔案
  3. 修複檔案

脫殼三步法­尋址OEP技巧

  1. 堆棧平衡法(ESP定律) 殼代碼就像一個函數,進入時會開辟堆棧、儲存寄存器環境,退出時會恢複堆 棧、恢複寄存器。是以應該是堆棧平衡的,那我們可以在殼代碼操作了堆棧後對 堆棧設定通路或寫入斷點,然後運作程式,當斷點命中的時候,應該就是退出殼 代碼的時候。在其附近單步幾次,應該就能到達程式的原始OEP。
  2. 特征定位法 在我們熟悉的程式中,我們可以使用特征來定位程式原始OEP。特征有幾種: ① 二進制特征 比如release版的VS2013是: E8????????E9 ② API特征 比如release版的VS2013的第一個API調用是: GetSystemTimeAsFileTime 比如vc6.0的第一個API調用是: GetVersion 比如Delphi程式第一個API調用是: GetModuleHandleA
  3. 單步跟蹤法 這種方法一般使用在分析自己加殼的程式或者是練習分析殼時。

脫殼­0.aspack.exe

  1. 用010Editor把重定位關閉
  2. 尋址OEP ESP定律
  3. 跑到入口點的位置再dump
  4. dump記憶體
    脫殼1
脫殼1

RVA這個測試程式用的是0.

注意:如果程式有随機基址,脫殼後需要把随機基址标志位置0.

殼代碼的基本流程

① 儲存寄存器環境

② 加載一些必要的API

③ 解密代碼和資料

④ 修複重定位

⑤ 填充IAT

⑥ 恢複寄存器環境

分析殼代碼­0.aspack.exe

① 殼OEP

脫殼1

② 加載必要API

脫殼1

③ 解密解壓縮代碼

脫殼1

④ 修複重定位

脫殼1

修複重定位的公式:

重定位表中存儲兩個有用字段:

  1. 需要重定位的分頁位址
  2. 需要重定位的分頁偏移

    重定位分為兩步:

  3. 計算出 重定位位址,要重定位的位址=子產品基位址+分頁位址+分頁偏移
  4. 修複要重定位的位址中資料,[要重定位的位址] ­ 預設子產品基位址 + 目前子產品基 位址
  5. 填充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

脫殼1