1. 程式人生 > >手工脫殼之 未知IAT加密殼 【IAT加密+混淆+花指令】【哈希加密】【OD腳本】

手工脫殼之 未知IAT加密殼 【IAT加密+混淆+花指令】【哈希加密】【OD腳本】

get 並且 size pos targe 特殊 pro 臨界點 post

一、工具及殼介紹

使用工具:Ollydbg,PEID,ImportREC,LoadPE,OllySubScript

未知IAT加密殼

技術分享圖片

技術分享圖片

二、初步脫殼

嘗試用ESP定律。

技術分享圖片

技術分享圖片

疑似OEP,VC6.0特征

技術分享圖片

進第一個CALL查看

技術分享圖片

技術分享圖片

確認是OEP。

OEP地址 = 47148b,RVA = 7148b

技術分享圖片

導入表函數信息出了問題。

技術分享圖片

查看IAT引用。

IAT表被加密。所以ImproREC才檢測失敗。

技術分享圖片

三、解析IAT加密方式

先API方面考慮。

殼修復exe IAT時,需要調用相關API,用LoadPE查看殼的導入表信息。

可見,推測,LoadLibrary 和 GetProAddress 是 隱藏調用 或 自我實現的。

技術分享圖片

采取硬件斷點的方式:

在被加密的IAT表的最頂端,下硬件斷點。

技術分享圖片

首次斷下,執行代碼是在內存地址上,說明殼是在自己申請的內存上執行代碼的。

回溯分析函數。

技術分享圖片

技術分享圖片

進一步分析,確認是memcoy

技術分享圖片

查看memcoy參數,數據窗口跟隨,發現是殼首次調用解密TEXT段

技術分享圖片

技術分享圖片

改換在memcpy下斷點,第二次斷下。

第二次斷下,是往IAT填RVA。

技術分享圖片

技術分享圖片

接下來斷下的每一次,是往IAT填內存地址,內存地址數據窗口跟隨。

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

IAT引用的順序是這樣的:

CALL à 殼的內存代碼 à 真正的API

所以殼是在中間加了一層內存代碼,並且內存代碼裏包含混淆花指令。

三、鎖定IAT加密點

在memcpy進RVA後,依舊在IAT首部下硬件斷點。

得知殼進行內存的操作後,順便在API下斷,VirtualAlloc

技術分享圖片

記錄一下,一共申請了三次內存。

技術分享圖片

技術分享圖片

技術分享圖片

在硬件斷點斷下的地方。

技術分享圖片

由於匯編中摻雜著混淆和花指令,(具體見最後部分)。

確定目標:在殼修復IAT過程,尋 取出的函數地址 和 475000(往IAT填的內存地址)。

操作:多觀察寄存器窗口 和 堆棧窗口

在當前指令下硬件斷點,並開始單步步入(混淆代碼的CALL F8會跑飛)

記錄異樣:

技術分享圖片

DLL基地址

技術分享圖片

查看地址,是遍歷時的RVA

技術分享圖片

技術分享圖片

出現字符串,並在代碼循環中逐步減少,疑似DLL INT取得的函數名。

技術分享圖片

技術分享圖片

查看地址,確認是。

技術分享圖片

技術分享圖片

按經驗,在殼中,比較函數名的匯編代碼有兩種規律:

殼調用比較函數:在字符串完整或全沒時,跟蹤到返回指令,回溯分析函數和函數周圍的函數調用。

殼采用比較循環:純代碼循環比較字符串。找到字符串比較條件的臨界點,一般下一條是條件跳轉指令,跳出循環。

由於代碼是混淆過的,跳來跳出亂跳,很明顯是屬於比較循環。

技術分享圖片

比較字符串,如果采用rep的方式的話,結果一般會設置標誌位跳轉,再返回布爾值。

上面是TEST AL, AL,判斷字符串是否結尾。殼可能進行長度記錄,或是對整個字符串進行了特殊操作。

當比較結束時,跟蹤結果,尋找函數地址

發現殼是對函數名進行哈希加密,並拿哈希值與 要尋函數的哈希值比較,來鎖定函數。

下條件斷點,當匹配正確後,下一步應該就是從DLL IAT取函數地址了

技術分享圖片

技術分享圖片

取出的函數地址:。

技術分享圖片

為後面OD腳本做準備:

跳過CALL,需在下一條指令下硬件斷點:

記錄下一條指令地址:0x002E08D5,RVA = 08D5

接下來找 把函數地址放進exe IAT的指令,觀察475000開始的地址。

中間經過memcpy,應該是把內存代碼往剛申請的內存上填,然後把內存地址賦給IAT。

技術分享圖片

技術分享圖片

尋到IAT的地址:

技術分享圖片

然後就是把內存地址IAT地址上填了

技術分享圖片

為後面OD腳本做準備:

跳過CALL,需在下一條指令下硬件斷點:

記錄下一條指令地址:0x2E1A36,RVA =1A36

由於殼代碼是在申請出來的內存上執行的,需要確定內存基址,就需要確定申請內存的指令。

尋到申請內存的指令:

技術分享圖片

技術分享圖片

為後面OD腳本做準備:

記錄下一條指令地址:0x47A381。

四、OD腳本

前面的準備材料:

OEP 地址 = 0x47148b

得到申請內存地址:0x47A381

取IAT指令地址RVA:08D5

存IAT指令地址RVA:1A36

OD腳本:

//清除所有硬件斷點

BPHWC

//清除所有軟件斷點

BC

//清除所有內存斷點

BPMC


//殼申請內存基地址

VAR BaseAddress

//IAT地址

VAR IATAddress

   
//得到申請內存基地址指令

BPHWS 47A381,"x"

//OEP斷點

BPHWS 47148b,"x"


_LOOP:

RUN

   
//內存基地址判斷

CMP eip,47A381

JNZ _Sign1

   
MOV BaseAddress,eax


//取IAT指令

BPHWS BaseAddress+1A36,"x"

//存IAT指令

BPHWS BaseAddress+08D5,"x"

   
_Sign1:


//取IAT判斷

CMP eip,BaseAddress+1A36

JNZ _Sign2


MOV IATAddress,eax


_Sign2:


//存IAT的地方

CMP eip,BaseAddress+8D5

JNZ _Sign3


MOV [edx],IATAddress


_Sign3:

   
//OEP

CMP eip,47148b

JNZ _LOOP


MSG "到達OEP"

再次Dump,成功解析。

技術分享圖片

成功運行。

技術分享圖片

五、混淆和花指令

代碼中出現很多這樣的指令:

call xxx

xxx    LEA ESP,DWORD PTR SS:[ESP+0x4]

實際上等價於jmp    xxx

很多地方都是 混淆和花指令結合:

技術分享圖片

有關混淆和花指令詳細,可以參考下一篇,下一個殼采用了大量的花指令和混淆:

手工脫殼之 PESpin加密殼【SHE鏈硬件反調試】【IAT重定向】【混淆+花指令】

個人總結:

附件:

未知加密殼

KID

手工脫殼之 未知IAT加密殼 【IAT加密+混淆+花指令】【哈希加密】【OD腳本】