脫殼——UPX脫殼原理(脫殼helloworld)

脫殼——UPX脫殼原理

 

 

脫殼步驟

1 找到OEP

2 dump(導出)內存文件

3 修復

1 找到OEP

1 程序運行先從殼代碼運行,殼代碼執行完之後會跳轉到真正的OEP,也就是是說第一步,首先要找到真正的OEP

如何找到OEP

大部分情況下,殼代碼會在一個單獨的區段裏面,殼代碼執行完一定會跳轉到原來的.text段去執行,跳轉之後的地址就是這個程序原始的OEP

根據OEP特徵碼來判斷是否是原始的OEP

不同程序、不同版本編譯器編譯出來的程序OEP各不相同,但是大致有共同的特點:

例如:

vc6.0的OEP處的第一個API調用是GetVersion

VS2013是GetSystemTimeAsFileTime

Delphi是GetModuleHandleA

2 dump內存文件

就是把得到的新的源文件給它保存下來,可以採用從頭到最後一個區段的手動複製下來,也可以用工具

3 修復

對於手動扒拉下來的內存文件,肯定還有一些問題,這裡需要對PE文件進行修復

第一次脫殼

加殼程序下載鏈接:

//download.csdn.net/download/weixin_43916597/18353951?spm=1001.2014.3001.5503

使用到的軟件:

Peid:(吾愛破解上可以下載)

查看程序信息

首先先查看程序的信息,先了解敵人:

採用PEID來查看程序的信息:

將程序拖進PEID後:

 

 

這裡很明顯是一個UPX加殼後的程序,採用的是UPX殼代碼

連接器版本6.0 也就是vc6.0的

開始脫殼

1 找到OEP

首先採用od加載exe

 

 

這裡跟之前我們想的加殼是一樣的,就是先pushad,然後再處理自己想處理的,最後popad,再跳轉回到真正的OEP裏面

    pushad 

//殼代碼

popad

jmp xxxx

但是這裡沒有popad,所以需要找一下popad,在pushad執行完之後,esp指向的是棧頂的位置,popad的話會讓esp移動,所以可以直接給esp打一個斷點

 

 

這裡來一個esp斷點,也可以通過別的,比如在command中訪問到esp的地址,然後選擇,來一個硬件斷點

 

 

需要注意的是在esp往上兩個來一個硬件訪問的dword斷點才行

然後把這個程序跑起來,就會停在我們打的斷點這裡了

 

 

這裡的話是停在了這裡,這裡恰好有一個popad(註:硬件訪問是在這個斷點運行了之後再停下來)

 

這裡popad完之後就可以尋找jmp指令了,但是如何判斷這個jmp是不是真正的jmp到oep呢

 

 

可以看到這裡的jmp跳轉到了非常遠的距離,那麼到底是不是跳轉到真正的OEP呢?

 

 

點擊od的m這個按鈕來查看PE文件的各種屬性

 

 

431B7C肯定是在這個區段裏面的從這裡跳轉到了402680也就是上一個區段,這裡就可以知道了,這裡其實是跳轉到了第一個區段也是加殼最常用的.text區段

然後跟入跳轉到402680

 

 

可以看到這裡的第一個api確實是GetVersion,所以這裡肯定就是真正的OEP了

2 dump(導出)內存文件

需要再剛進入OEP的第一條指令就dump出來,因為不知道後面的代碼邏輯是什麼,萬一有什麼修改呢

od中可以直接調用OllyDump脫殼調試進程

手動dump:利用M按鈕裏面的PE文件加載情況,將主程序.exe文件的內存文件一點一點複製粘貼出來

利用010Editor創建一個hex文本類型文件

 

 

然後從od 的m按鈕裏面一塊一塊的複製文件過來

首先處理PE頭

 

 

雙擊進入,然後修改為16進制類型

 

 

對整個內容進行二進制複製

然後再到010Editor中採用Ctrl+shift+v複製,不要採用Ctrl+v複製,這樣才能直接複製16進制的內容進去

然後就是UPX0和UPX1還有.rsrc三個字段也複製進去

最後保存下來,隨便一個文件然後以.exe結尾就好

3 修復

dump出來的exe文件不能使用的,因為還有一些PE文件的內容沒有修復,這個時候再用010Editor來加載dump出來的pe文件進行修復

 

 

它裏面就會有一些PE的提示

需要修改的信息:

區段頭信息

導入表

 

修復區段頭

 

 

這裡裏面很多區段頭的信息都沒有,因為這裡應該是PE文件來處理的,但是我們是dump複製出來的,所以這裡我們需要自己添加沒有的信息

Name不用改

Misc表示未對齊的真實內存中的大小也不用改

VirtualAddress內存中的一個rva也不用改

SizeOfRawData文件中的對齊大小這個由於我們是從加載到內存中再Dump出來的,所以文件和內存已經沒有必要區分開了,直接和Msic值一樣就好

PointerToRawData表示foa,這裡也直接用rva就好了

後面的可以不用處理

這樣把三個區段頭都修改好

修復好了三個區段頭後,可以很清楚得看到程序的變化

 

 

圖標回來了!雖然這個時候還無法運行

修復導入表

 

 

 

上面修復了PE文件的區段頭,但是由於導入表沒有修復還是無法使用,這裡用LordPE查看該exe的導入表就可以看到dll的導入表是錯的

正常的導入表是通過操作系統對字符串來處理然後得到該字符串的函數名稱對應的函數地址變成地址給exe使用

但是這裡由於我們是把exedump出來了,所以就是把操作系統變成的函數地址給弄了出來,而不是函數名稱字符串,所以這裡還需要修復,把地址修復改成函數名稱

手動修復導入表:從od裏面把原來的導入表地址函數名稱全部提出來,然後再在dump出來的exe裏面開闢一個字段來存儲導入表,再把PE文件裏面的導入表指向指到開闢的導入表裏面就好了

在硬編碼裏面,有幾種對於call函數的編碼,但是如果編碼的開始是FF15 xxx的就表明是對導入表裏面的函數調用

 

 

這裡可以很明顯的看出來

然後再進入到FF15的call的地址裏面查看

 

 

可以很明顯得看到各種各種的導入表函數,拿到之後再按照前面的方式添加進去就好了

根據導入表的性質來修復

這裡採用一個工具來處理

//down.52pojie.cn/Tools/PEtools/ImportREConstructor%201.7e.zip 解壓密碼:www.52pojie.cn

 

 

 

添加進程,修改OEP和大小,然後獲取導入表,同時還需要進入OD用剛剛的辦法查看是否把所有的dll都包含了,這裡是確實只有兩個dll,如果沒有可以嘗試修改大小來處理

 

 

然後使用轉存到我們剛剛弄的.exe文件就好了,正常的話下面會出現一個保存成功

這次再查看導入表

 

 

就是很正常的了

再查看它的區段

 

 

可以看到多了個區段,和我們前面想的一樣手動添加了一個區段來專門修復導入表.

 

總結 UPX脫殼

首先採取找到OEP,然後呢對整個PE文件進行dump出來,然後再修復,修復需要修復PE的區段頭和導入表