初探手工脫UPX殼(IAT修復Dump+ESP定律找OEP),學學如何幫程式脫殼裸奔

這是個人練習UPX脫殼的筆記文XD
本來就對脫殼技術蠻有興趣der,直到最近才開始練T___T

後繼心得:
自己手脫過一次殼過後才能體會為啥問過某些大佬能不能脫Themida那種殼帶肉的殼
會被以一種“你沒見過世面膩”的眼神翻白眼XDDDDDDDDDD



本次欠脫殼的程式載點在這
內有一個UnPackedApp.exe是原始exe
還有一個PackedApp.exe是加過UPX殼的exe

首先用CBuilder寫了個只有窗體的exe
不過因為是第一次玩脫殼
所以用了最好脫的殼做練習 UPX壓縮殼

ok,本日主角就這樣誕生惹
首先先看看原本剛編譯好的exe的入口(OEP):
是很標準的C++ Builder的入口 :)

接著看看UPX加殼過後的入口:
會先做一個pushad保護堆疊,然後進入UPX的解壓縮資源步驟
接著往下翻一下很快就會看到很多UPX解壓縮的過程,最後來到這裡有個popad
去把剛剛pushad推入的東西做一個推出,恢復堆疊
然後jmp PackedAp.004021B8這邊就是回到原本C++ Builder的標準OEP了

既然找到OEP,那該怎麼把UPX脫掉?
剛剛在執行步驟中可以很明顯看到,UPX會先做一個pushad
保護當前ESP資源不受破壞,接著做一系列的解壓縮資源到內存中,
解壓縮完畢後會再做一個popad把ESP做還原,然後jmp入C++ Builder的OEP

所以,執行到004021B8這邊開始就是進入C++ Builder的標準程序了
從這邊開始,使用OllyDump開始做dump內存
這邊設定一下入口地址OEP從0x3CD1F0(也就是0x7CD1F0一開始看到的pushad)
修正為:0x21B8(也就現在看到的0x4021B8)

接著這邊有件神奇的事情要說,一般VC++之類的exe勾選重建輸入表然後按下脫殼好像就可以全自動修復IAT了,不過...C++ Builder套殼後不管是ollyDump或者是大名鼎鼎的ImportREC 1.6版本、1.7版本,通通沒辦法修IAT,這些主流工具通通無法辨識C++ Builder的IAT ( ゚д゚)

所以接下來因為要介紹另套工具修IAT,所以這邊OllyDump在做Dump的時候請記得把重建輸入表的選項給勾勾取消,然後按下脫殼,並且找好地方做儲存

接下來要介紹的工具是這套,Layz大大介紹的神器 Scylla 海妖<(_ _)>
在GitHub上是開源的修IAT的工具,猛猛der...可以修C++ Builder的IAT

它的核心概念是把正在執行的Process的IAT表分析完之後,
再轉存入Dump內做修復Dump的工作
所以我們得先鎖定正在執行的Process,然後填入我們找到的原始OEP,按下IAT AutoSearch它會自動搜索出整個IAT導入表的資料,如果成功就會回應一個上圖的訊息

接著按Get Imports就可以針對IAT再做細部的每個API搜索Offset算出來整個IAT所有結構體跟Offset的關係,最後按下Fix Dump按鈕去選擇我們剛剛用OllyDump出來的東西就可以替我們修復惹

最後,這是成功效果圖ㄧ覽
123.exe是用OllyDump做轉存出來的,沒有修正IAT不能執行
然後123.exe經由Scylla修正後會產生一個123_scy.exe的檔案,這個雙擊兩下就可以正確執行惹!用PEID查一下的確已經沒有UPX殼了,成功去殼啦~~

接下來是比較有疑問的地方是:

那如果我不知道popad在哪不就找不到原始OEP了嗎
這就要提學脫殼必學的ESP定律找OEP惹
首先我們都知道的是正常程式被Windows開啟時是這樣的:
[Windows創建進程]->[給予一個合法可用的ESP地址]->[接著從OEP開始跑]

不過如果套殼之後,會是:
[Windows創建進程]->[給予一個合法可用的ESP地址]
->[做一次pushad避免殼在解壓縮時破壞Stack的內容]->[先跑殼的解壓縮流程]
->[最後還原原本的ESP內容到當前的ESP+0上的內容]
->[popad恢復Stack]->[從原始OEP開始跑]

所以我們知道一定在殼解壓縮過程中會需要使用到那個空白地址[ESP+0]來做恢復Stack還原ESP現場的動作,那就可以很快的找到原始ESP地址

以下拿剛剛同一隻UPX加殼後的程式做操作
首先一樣從殼的入口開始看,先用F8單步過pushad,會看到原始ESP是0x12FF8C(Windows給的)經過了pushad後,Stack上會多了8個WORD大小的資料(也就是偏移了8x4 = 32的地址)

所以我們可以確定最後0x12FF6C就會是還原現場時的ESP+0必須做還原
所以這邊我們先跳到0x12FF6C下一個硬斷
(或者你也可以挑0x12FFA8、AC、B0...etc只要介於ESP+0~原始ESP就可以惹)
下好硬斷後就可以按F9 Let it go~
很快就可以看到OD跟蹤到了popad這個點
主要是popad釋放掉了ESP上的8個DWORD觸發了我們下的硬斷存取的事件
接著單步跟蹤下去
於是很快就可以跟蹤到原始OEP囉

留言

這個網誌中的熱門文章

[C#] Lambda花式應用噁爛寫法(跨UI委派秒幹、多線程處理...etc)

[Black Asia Arsenal] puzzCode: 專注開發後門的編譯器, 自帶反逆向、對抗病毒特徵碼定位技術

[Windows] 逆向工程 C++ 中入口函數參數 main(argc, argv) 與如何正確的進行參數劫持