upx加殼源碼
⑴ upx技術原理
在保護程序資源方面,利用UPX技術進行可執行文件的壓縮是一種常見的手段,也被稱為文件"加殼"。加殼的目的是為了隱藏程序的原始源代碼,使其在不被直接查看的情況下運行。
加殼的過程實際上是一個特殊的編碼過程,它運用了一種類似於WINZIP的壓縮演算法,但區別在於,壓縮後的文件無需解壓即可直接執行。壓縮操作在內存中悄悄進行,不暴露給用戶任何解壓的跡象。這個過程在文件的頭部嵌入了一段指令,該指令向CPU提供了解壓的線索。當程序被加殼時,就像給文件穿上了無形的外殼,用戶實際上執行的是這個外殼程序。
外殼程序在運行時會負責在內存中解壓真正的程序。解壓完成後,程序的真正執行交給解包後的部分。這種方式不僅保護了代碼的隱私,還提高了程序的運行效率,因為無需在磁碟上進行解壓縮操作。
(1)upx加殼源碼擴展閱讀
UPX (the Ultimate Packer for eXecutables)是一款先進的可執行程序文件壓縮器,壓縮過的可執行文件體積縮小50%-70% ,這樣減少了磁碟佔用空間、網路上傳下載的時間和其它分布以及存儲費用。 通過 UPX 壓縮過的程序和程序庫完全沒有功能損失和壓縮之前一樣可正常地運行,對於支持的大多數格式沒有運行時間或內存的不利後果。 UPX 支持許多不同的可執行文件格式 包含 Windows 95/98/ME/NT/2000/XP/CE 程序和動態鏈接庫、DOS 程序、 Linux 可執行文件和核心。
⑵ 使用x64dbg脫殼之開源殼upx
大家好,我是藍鐵,你們的老鐵,^_^ 我們知道在分析病毒的時候,最常見的一種殼就是upx,使用upx的好處就是壓縮率還不錯,可以讓原程序縮小一倍,便於在網路中傳輸。本節就是以開源殼upx為例講解x64dbg中的脫殼方法。
脫殼中的一些常見概念
首先我向大家介紹一下脫殼相關的概念。
脫殼中的一些方法
脫殼算是軟體逆向技術中一種比較難的技術,方法也有很多,我在這里先介紹有代表性的方法:
單步跟蹤(踏踏實實法)
一步一步分析每一條匯編指令,吃透每一行匯編背後所代表的意思,將殼代碼讀懂,從而找到原始OEP然後脫殼。這種方法是最鍛煉人的,也是最難的。即使一個有經驗的逆向分析者在對一個陌生的加殼程序分析時也需要花費很多時間,但這就是逆向工程的魅力,挑戰自我,挑戰才能突破。一般這種方法是在我們學習逆向工程時或是不能使用技巧時才會用的方法,耐心是這個方法的關鍵。
平衡堆棧(又稱ESP定律,技巧法)
一般加殼程序在運行時,會先執行殼代碼,然後在內存中恢復還原原程序,再跳轉回原始OEP,執行原程序的代碼,我們可以把殼代碼理解為一個大的函數,既然是函數,那麼進入函數和退出函數時,堆棧應該就是平衡的,基於這樣的一種特性,我們可以在殼代碼操作了堆棧之後,對堆棧設置訪問斷點,然後讓程序跑起來,當程序暫停的時候,就是殼代碼即將執行完的時候,然後在其附近單步跟蹤,就可以找到原始OEP了。這種方法比較適用於upx這種只對代碼和數據壓縮了的殼,如果還對代碼加密了,那麼就不是太好找了。加密的話就需要結合單步跟蹤法。
脫殼三步法
不管是哪種脫殼方法,都需要遵循脫殼三步法,脫殼三步法分為以下三步: ① 尋找原始OEP 這一步驟的主要作用就是要確定原始程序代碼到底在哪裡,能找到原始程序的代碼,說明殼代碼執行完了,我們只有找到原始OEP才能進行下一步的動作。 ② mp內存到文件 當我們找到原始OEP,調試運行到原始OEP時,只要代碼被還原,我們就可以在這個地方進行mp內存,將內存中被還原的代碼和數據抓取下來,重新保存成一個文件,這樣脫完殼時,我們就可以用靜態分析工具分析程序了。
③ 修復文件 這一步主要就是修復IAT,對從內存中轉儲到本地的文件進行修復。
下載upx與使用upx對文件加殼
下載upx
upx殼的官網是: upx.github.io/ 下載最新版的upx: github.com/upx/upx/rele... 本次實驗使用的是windows版的upx,所以下載的版本是:
使用upx對文件加殼
下載完之後,解壓開可以找到upx加殼的主程序upx.exe,我們可以對任意程序進行加殼,可以使用命令行進行加殼。 以VC6.0編寫的一個程序為例,對其進行加殼,加殼之前我們先使用x64dbg查看一下其OEP:
可以觀察一下OEP有什麼特點? 然後我們使用命令行對vc6.0的demo程序加殼
可以看到,加殼之後,文件大小從200多K變成了90多K。 再使用x64dbg觀察加殼後程序的OEP:
可以發現,加殼之後的程序和加殼前真的很不一樣,所以我們才要進行脫殼。
使用x64dbg脫殼之尋找OEP
定址OEP的方法有多種,這里我們使用前面介紹的平衡堆棧法,我們使用x64dbg調試加殼後的程序,觀察oep處的指令,可以發現OEP的第一條指令是pushad,其作用一般是保存寄存器環境,可以將8個通用寄存器都壓入堆棧,那麼我們可以單步程序(F8),執行pushad,這樣堆棧就會發生變化,而後我們可以在堆棧棧頂處,即ESP指向的內存處,設置硬體訪問斷點,
我們可以在x64dbg中的寄存器窗口處,選中esp,然後右鍵選中在內存窗口中轉到
然後在內存窗口處,右鍵設置硬體訪問斷點
之後,可以使用快捷鍵F9運行程序,程序會再次暫停下來,我們觀察附近指令
可以發現我們暫停的指令上方就是popad指令,一般遇到popad指令,就離原始OEP不遠了,因為執行完popad指令意味著殼代碼告一段落了。 繼續單步,可以發現一個比較大的jmp跳轉。這個jmp其實就會跳轉到原始OEP。
實際上在分析時,我們是先單步到jmp跳轉到的代碼進行觀察之後得出是否是原始OEP的結論的,這個部分需要我們對未加殼程序的OEP要有所了解,比如VC6.0的程序一般OEP最開始的一個API調用是GetVersion,看OEP見到GetVersion就如見到了vc6.0程序。 我們單步到跳轉之後的代碼處,409376,這個地方就是原始OEP,而後我們要做的就是在這個地方進行mp。
使用x64dbg脫殼之mp內存
當我們找到原始OEP時,我們運行到此處,然後對當前程序的內存進行mp,需要使用x64dbg中的一個插件:Scylla。
打開插件Scylla
使用快捷鍵Ctrl+I可以直接打開插件,進行mp。
Scylla的使用
注意,mp時需要填寫正確的原始OEP地址,然後點擊Dump按鈕保存文件。
保存完畢之後,最後就是修復文件了。
使用x64dbg脫殼之修復文件
修復文件,本質上就是修復IAT,所以還是使用插件Scylla,先對當前程序的IAT進行掃描,如果能找到就可以使用工具修復,不能就需要手動修復。 為了能更好的獲取IAT,我們需要對插件Scylla進行設置。
使用x64dbg單步跟蹤,發現出現異常的地方
根據這個地址以及經驗可以猜出,可能是這個地址所在的區段的屬性不可寫。使用LordPE,可以查看區段屬性,如下圖,果然是沒有可寫的屬性。
將其可寫屬性打鉤,保存文件即可添加屬性,這樣就完成了脫殼。
測試結果
最後我們可以運行已經脫殼修復完成的程序,先使用PEID查看一下區段,然後運行。
總結
脫殼這門技術在任何一個平台下都是比較難的技術,想要練成這項技術,除了對匯編語言要非常熟悉之外,還需要對可執行文件的格式很熟悉,並且對可執行文件的載入流程還有一定認識,比如在這一節中,我們講到了一個名詞,修復IAT,只有對可執行文件載入流程理解了,修復IAT才會真正理解。綜上,脫殼技術的練習是綜合練習,我們從Upx開始,一步一步去分析現在主流的病毒混淆殼吧!希望大家可以跟著我嘗試練習^_^。