天天看點

脫殼筆記-手工脫UPX壓縮殼

本文示例程式及upx加殼工具

一、基本概念的了解

殼的脫殼:如果我們将一個應用程式比喻成一個雞蛋,程式中對我們有用的程式代碼為雞蛋清,而我們需要擷取雞蛋清的時候,就必須打破雞蛋外面的雞蛋殼,也就是進行脫殼的處理。

脫殼的方式:不同的殼對應的脫殼方式會不一樣,甚至相同的殼但是不同的版本,脫殼的方式也會可能不同。

二、示例程式示範

示例程式為win7自帶的notepad.exe ,該程式原本沒有加殼

脫殼筆記-手工脫UPX壓縮殼

對該應用程式notepad-UPX.exe進行UPX加殼

脫殼筆記-手工脫UPX壓縮殼

壓縮之後查殼

脫殼筆記-手工脫UPX壓縮殼

進行upx加殼前後對比

脫殼筆記-手工脫UPX壓縮殼

三、脫UPX殼

1、脫殼的基本過程

手動跟蹤到程式的OEP(程式原始入口點),将程式和資料dump下來,然後再進行IAT的相關修複即可。

2、如可查找OEP

(1)需要熟悉各種編譯器生成的程式的入口點的指令。例如vs 程式的入口點一般為:

push ebp

mov ebp,esp

(2)殼進行解壓縮的代碼通常在一個自己的區段裡面運作,解壓縮完成後通常會跳轉到原始程式入口點進行運作,此時跳轉到OEP往往需要一個JMP或CALL,保證EIP指針指向了原始的OEP位址。注:原始的OEP與解壓縮的代碼通常不在一個區段内,是以JMP與CALL往往實作的是跨區段的跳轉。

3、手動的跟蹤脫UPX殼

OD載入程式後,先運作的是殼的解壓縮代碼,逐漸F8往下跟蹤,跟蹤完解壓縮代碼後,跳轉到OEP。

(1)UPX殼所用到的API:LoadLibraryA和GetProcAddress,這兩個API将進行對原始程式的導入函數進行還原。LoadLibraryA進行加載導入函數相關的動态連結庫,GetProcAddress在動态連結庫裡面擷取導入函數的位址進行還原。

LoadLibraryA

脫殼筆記-手工脫UPX壓縮殼

GetProcAddress

脫殼筆記-手工脫UPX壓縮殼

(2)注意相關的邏輯循環,使用F4運作到指定位置,跳出循環(注意:如果碰到nop的指令,F4定到下一條語句,否則程式會跑飛)。UPX在完成解壓縮之後,會進行跳轉到原始程式入口點,這是跨區段的跳轉,在F8與F4往下運作的同時,注意跨區段的JMP

脫殼筆記-手工脫UPX壓縮殼

位址 0x0055B9D4與0x004E53C2,位址之間相差巨大,此時往往為跨區段的跳轉。該條指令就是跳轉到原始程式的入口點,F8自動步入到OEP

脫殼筆記-手工脫UPX壓縮殼

(3)打開LoadPE,選中該應用程式程序,右鍵先“修正鏡像大小”,再“完整轉存”,将OD跟進到OEP的程式轉儲下來。

脫殼筆記-手工脫UPX壓縮殼

此時轉儲下來的dumped.exe程式無法運作,因為導入表還沒有進行修複

脫殼筆記-手工脫UPX壓縮殼

接下來我們進行導入表的修複

(4)計算出OEP的RVA值,也可以在我們跟進的OEP處,右鍵選中Dump Process插件(注:不同的OD的名稱有細微的差别),擷取目前EIP作為OEP的RVA值(Get EIP as OEP)

脫殼筆記-手工脫UPX壓縮殼

擷取到OEP的值為 0x000E53C2

(5)使用ImpREC進行對導入表的修複

脫殼筆記-手工脫UPX壓縮殼

填寫我們的OEP值,然後點選“自動查找IAT”,再點選“擷取輸入表”,最後進行轉儲到檔案,進行修複dump下來的導入表(無效的指針在脫UPX殼中可以不用删除)

脫殼筆記-手工脫UPX壓縮殼

修正後的可執行檔案dumped_.exe

脫殼筆記-手工脫UPX壓縮殼

dumped_.exe就是可以正常運作的程式了,我們最後再來查殼看看該程式,此時沒有殼

脫殼筆記-手工脫UPX壓縮殼

脫upx殼小技巧:通過脫殼發現,upx殼的解壓縮完成後跳轉到OEP的jmp指令後面為nop指令,通常隻需要滑鼠往下滾動,發現很多nop指令時,就能找到該jmp指令。

四、脫殼找IAT小技巧

我們在進行跟進到OEP後,有可能殼的解壓縮程式并沒有完全的幫我們恢複IAT(例如:FSG殼),而ImpREC并不能幫我們完整的修複,此時就需要我們手動進行修複,如何查找到IAT?

調用系統的API的call指令的二進制指令代碼為 FF 15,是以我們隻需要在OD中,查找FF 15二進制指令就能找到某個導入函數的位址,然後再資料視窗中跳轉到該位址就能到IAT的位置,再進行上下滾動就能查找了。

基本步驟:

1、Ctrl+B或在OD中右鍵->查找->二進制子串

脫殼筆記-手工脫UPX壓縮殼

輸入FF 15,點選确定就能查找到某一個導入函數的位址

2、此時查找到的API為kernel32裡面的GetCommandLineA,它在記憶體中的位址為0x53230C,我們在資料視窗中Ctrl+G,輸入該導入函數的位址跳轉到0x53230C(注:資料視窗中需要右鍵->長型->位址才能檢視到API的名稱)

脫殼筆記-手工脫UPX壓縮殼

此時查找到IAT,就可以進行一些相關恢複。

upx殼的解壓縮代碼已經進行了完全的恢複,是以此處并不需要進行相關修複。

本文難免有所錯誤,如有問題歡迎留言