標籤:

使用x64dbg脫殼之開源殼upx

引言

大家好我是藍鐵,你們的老鐵,^_^

我們知道在分析病毒的時候,最常見的一種殼就是upx,使用upx的好處就是壓縮率還不錯,可以讓原程序縮小一倍,便於在網路中傳輸。本節就是以開源殼upx為例講解x64dbg中的脫殼方法。

脫殼中的一些常見概念

首先我向大家介紹一下脫殼相關的概念。

  • 外殼,英文為shell,在黑客技術中,一種比較高超的加密技術,對可執行文件(例如windows下的exe文件、Linux下的elf文件)進行加密壓縮處理的技術。

    一般對可執行文件加殼的目的有三:

    ① 軟體加殼,保護數據、防止破解

    ② 外掛加殼,保護數據、防止破解

    ③ 病毒加殼,防止被查殺。

    常見的殼分為壓縮殼和加密殼兩種,upx屬於壓縮殼。
  • 脫殼

    對加密處理的文件進行反分析,將已有的保護外殼去掉的過程。
  • OEP

    程序入口點,程序最開始執行的地方。
  • 原始OEP

    當程序加殼之後,殼會修改程序入口點,會先執行殼代碼,會將原程序的入口點隱藏,這裡我們把原程序的入口點稱為原始OEP。
  • dump內存

    將內存中的數據或代碼轉儲(dump)到本地
  • IAT

    導入地址表,windows下可執行文件中文件格式中的一個欄位,描述的是導入信息函數地址,在文件中是一個RVA數組,在內存中是一個函數地址數組。(關於PE文件相關的知識可以通過搜索引擎查閱一下)
  • 修復IAT

    脫殼中比較重要的一步,不論是壓縮殼還是加密殼,在脫殼過程中都需要修復IAT,因為脫殼時會將內存中的數據轉儲(dump)到本地,保存成文件,而IAT在文件中是一個RVA數組,在內存中是一個函數地址數組。我們需要將轉儲出來的文件中的IAT修復成RVA數組的形式,這樣程序才算是恢復。

  • 脫殼的環境

    這個單獨出來說,主要原因就是不同的系統脫殼時遇到的問題可能是不一樣的,因為脫殼時要修改IAT,而不同系統中同一個模塊的API導出的順序是不一樣的,所以修復時一般都會出現點問題。因此,我建議脫殼的環境應該是在32位系統的虛擬機中,以下的所有操作應該在32位系統的虛擬機中操作,64位系統下可能會出現意想不到的問題。

脫殼中的一些方法

脫殼算是軟體逆向技術中一種比較難的技術,方法也有很多,我在這裡先介紹有代表性的方法:

單步跟蹤(踏踏實實法)

一步一步分析每一條彙編指令,吃透每一行彙編背後所代表的意思,將殼代碼讀懂,從而找到原始OEP然後脫殼。這種方法是最鍛煉人的,也是最難的。即使一個有經驗的逆向分析者在對一個陌生的加殼程序分析時也需要花費很多時間,但這就是逆向工程的魅力,挑戰自我,挑戰才能突破。一般這種方法是在我們學習逆向工程時或是不能使用技巧時才會用的方法,耐心是這個方法的關鍵。

平衡堆棧(又稱ESP定律,技巧法)

一般加殼程序在運行時,會先執行殼代碼,然後在內存中恢復還原原程序,再跳轉回原始OEP,執行原程序的代碼,我們可以把殼代碼理解為一個大的函數,既然是函數,那麼進入函數和退出函數時,堆棧應該就是平衡的,基於這樣的一種特性,我們可以在殼代碼操作了堆棧之後,對堆棧設置訪問斷點,然後讓程序跑起來,當程序暫停的時候,就是殼代碼即將執行完的時候,然後在其附近單步跟蹤,就可以找到原始OEP了。這種方法比較適用於upx這種只對代碼和數據壓縮了的殼,如果還對代碼加密了,那麼就不是太好找了。加密的話就需要結合單步跟蹤法。

脫殼三步法

不管是哪種脫殼方法,都需要遵循脫殼三步法,脫殼三步法分為以下三步:

① 尋找原始OEP

這一步驟的主要作用就是要確定原始程序代碼到底在哪裡,能找到原始程序的代碼,說明殼代碼執行完了,我們只有找到原始OEP才能進行下一步的動作。

② dump內存到文件

當我們找到原始OEP,調試運行到原始OEP時,只要代碼被還原,我們就可以在這個地方進行dump內存,將內存中被還原的代碼和數據抓取下來,重新保存成一個文件,這樣脫完殼時,我們就可以用靜態分析工具分析程序了。

③ 修復文件

這一步主要就是修復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,而後我們要做的就是在這個地方進行dump。

使用x64dbg脫殼之dump內存

當我們找到原始OEP時,我們運行到此處,然後對當前程序的內存進行dump,需要使用x64dbg中的一個插件:Scylla。

打開插件Scylla

使用快捷鍵Ctrl+I可以直接打開插件,進行dump。

Scylla的使用

注意,dump時需要填寫正確的原始OEP地址,然後點擊Dump按鈕保存文件。

保存完畢之後,最後就是修復文件了。

使用x64dbg脫殼之修復文件

修復文件,本質上就是修復IAT,所以還是使用插件Scylla,先對當前程序的IAT進行掃描,如果能找到就可以使用工具修復,不能就需要手動修復。

為了能更好的獲取IAT,我們需要對插件Scylla進行設置。

  • 打開設置

  • 設置高級掃描

  • 查找IAT

  • 獲取導入表

  • 修復上一節的dump文件

  • 最終生成文件

    最終會生成的文件是:vc6.0_demo_dump_SCY.exe

    當運行時發生了一個問題,出現了訪問異常

使用x64dbg單步跟蹤,發現出現異常的地方

根據這個地址以及經驗可以猜出,可能是這個地址所在的區段的屬性不可寫。使用LordPE,可以查看區段屬性,如下圖,果然是沒有可寫的屬性。

將其可寫屬性打鉤,保存文件即可添加屬性,這樣就完成了脫殼。

測試結果

最後我們可以運行已經脫殼修復完成的程序,先使用PEID查看一下區段,然後運行。

總結

脫殼這門技術在任何一個平台下都是比較難的技術,想要練成這項技術,除了對彙編語言要非常熟悉之外,還需要對可執行文件的格式很熟悉,並且對可執行文件的載入流程還有一定認識,比如在這一節中,我們講到了一個名詞,修復IAT,只有對可執行文件載入流程理解了,修復IAT才會真正理解。綜上,脫殼技術的練習是綜合練習,我們從Upx開始,一步一步去分析現在主流的病毒混淆殼吧!希望大家可以跟著我嘗試練習^_^。

本文由安全客原創發布

如若轉載,請註明出處: anquanke.com/post/id/99

安全客 - 有思想的安全新媒體


推薦閱讀:

WannaCry病毒利用漏洞--ms17010(永恆之藍)批量自檢工具
Avast---全球十大殺毒軟體之一
病毒分析 | 一款史上最流氓的QQ營銷病毒

TAG:計算機病毒 |