1. 程式人生 > >防查殼、防殺軟誤報——手動修改加UPX殼的應用程式

防查殼、防殺軟誤報——手動修改加UPX殼的應用程式

眾所周知,作為一款優秀的可執行檔案壓縮工具,UPX受到程式開發者的廣泛歡迎。然而一些病毒、木馬和其他惡意程式使用了UPX來隱藏自身行為,這使得它擁有不好的名聲,導致了防毒引擎對一些無害的應用程式的誤報。有些防毒引擎甚至將所有加了UPX殼的程式視為病毒,比如ClaimAV、Comodo、F-Prot等等。

其實,不僅是UPX,其它的壓縮殼,比如ASPack、PECompact也是如此。今天我們要討論的,是使用最為廣泛的UPX。

所以,我們需要做的,就是讓自己的程式不具備,或者說,不完全具備UPX殼的特徵。這既能夠有效避免防毒軟體的誤報發生,又能使自己的程式不容易被輕易殼脫殼並任意篡改其中的資料。(UPX殼不是加密殼,若有防破解的特殊需求,建議使用加密殼)


首先,我們來講一講殼的原理。不論是壓縮殼,還是加密殼,都有特定的演算法。加同種殼的不同應用程式,有一部分機器碼是相同的,它們被稱為“簽名”或者“特徵碼”。有些殼還會將自身的一些資訊寫入可執行程式。

主流的防毒引擎,比如360防毒,會藉助特徵碼技術來查毒,比如,當一個加了UPX殼的木馬被識別後,其部分程式碼被記入病毒庫中,而這可能會導致同樣是加了UPX殼的無害應用程式在被進行深入的行為分析前草率地被識別為木馬。

下面我們拿我以前寫的一個簡單的數學工具為例。使用EXEinfoPE,可以發現它沒有加殼,以及它是用VS2013的Visual C++編寫的。


上傳至Virscan.org發現只有F-Prot報毒。這是一次誤報,因為程式並沒有訪問網路的行為。


現在我們用最新的UPX給它加殼。使用“強制壓縮”命令來提高壓縮比,並將其儲存到一個新檔案。可以看到,壓縮效果還是不錯的。


現在我們再用EXEinfoPE檢視加殼後的程式。可以發現它識別出了UPX殼,並提供了較為直接的脫殼方法:UPX的“upx -d”命令。


我們把加殼後的程式上傳至Virscan.org,發現有三個防毒軟體報毒。其中,來自Hacksoft的產品TheHacker懷疑這是個蠕蟲,ClaimAV表示這個程式加了UPX殼,F-Prot表示這個程式加了個“未知殼”。


360的QVM引擎也誤報了這個程式。


現在來分析一下檔案資料。用任何一個十六進位制編輯器(UltraEdit,還有VS自帶的十六進位制編輯器等等都可以,但是不如WinHex)開啟加殼後的程式。可以看到三個區段名。“UPX0”和“UPX1”是加UPX殼後的兩個區段名。其中UPX1區段包含了需要解壓的資料塊。“.rsrc”是程式資源資訊區段名,這個區段含有原資源段的完整頭部以及圖示、Manifest、版本等未被壓縮的資源,當然還有UPX自身需要的匯入資訊等(如果程式自身不含資源段,加殼後就是“UPX2”)。“UPX0”和“UPX1”可以被隨意改成任何字串,雖然這樣改用處不大,但是也能起到偽裝的作用。


再向後翻頁,可以看到UPX頭部,這些資料的內容大致內容如下所示。具體不再贅述,參見UPX的原始碼。UPX頭是供UPX通過“upx-d”命令脫殼用的,並不影響程式執行。我們可以把它全部抹去(寫0),或者把它改成無效資料,這樣就無法使用命令“upx -d”快速脫殼了。

現在可以看到,UPX已經不能夠脫自己加的殼了。


在我們破壞UPX頭部後,EXEinfoPE依然能夠識別出UPX殼。那它又是如何識別出來的呢?點選編輯框右邊的小箭頭。


可以看到,EXEinfoPE是通過userdb.txt檔案中的特徵碼庫來辨別殼的。其中,UPX的特徵碼有一段“60 BE ?? ?? ?? 00 8D BE ?? ?? ?? FF”。“??”可以對應任意位元組。


使用任意反彙編工具(比如OllyDbg)開啟它。可以發現,程式的入口點就在這裡。現在需要做的,就是在不影響程式執行的情況下破壞特徵碼的匹配。方法有很多,這裡提供最簡單的一種。如下圖,抹去此處的pushad並不會影響程式的執行,所以可以把它改成nop(對應的機器碼是90)。nop是一個空指令,處理器什麼都不做,但是會產生一個極短(通常為幾微秒)的延遲。


儲存以後,由於匹配不上特徵碼,ExEinfoPE已經識別不出UPX了。但是它依然具備殼的特徵,再加上有三個區段,所以ExEinfoPE猜測這是個UPX。


360防毒並沒有誤報。


上傳到VirScan.org以後,發現TheHacker不再認為該程式是蠕蟲。但是ClaimAV依然識別為UPX(說明UPX還有不少可用作識別的特徵),但那並不重要。因為我們已經解決了誤報問題,防毒軟體沒有直接把它識別為惡意軟體或者木馬,這就足夠了。


UPX會採取多種方式嘗試壓縮程式以獲得較優壓縮率,所以有時會匹配到其他的特徵碼。下面我再舉一個例子。這次還是用3.91版本的UPX,但壓縮的是一個體積800多KB的程式,最終匹配到了UPX V2.0的特徵碼。


這段特徵碼比較長,我們開啟反彙編工具,找到它的尾部。


把“push 0x0”改成“push 0x1”即可。


上傳到Virscan.org以後發現,江民防毒軟體對它的誤報解除了。同時可以看到,ClaimAV這次無法識別出UPX殼。



最後,我們可以使用以下方法來進一步防止查殼。先開啟剛才修改過的Dec2Frac2.exe。0x3C和0x3D對應“00 01”的是PE頭的地址(反過來寫,實際上地址是0x100)從0x40開始一直到PE頭之前的資料可以被抹去或者覆蓋,不會影響程式正常執行。“E0 00”是PE頭的預設長度(224位元組),我們現在可以將這224個位元組覆蓋到0x48這個地址上,其餘的部分都寫0。


覆蓋以後,PE頭的偏移地址為0x48,所以填“48 00”,長度為408位元組,即0x198,所以填“98 01”。(注:PE頭可以覆蓋在0x40到原PE頭地址之間的任意位置)


現在可以發現EXEinfoPE無法找到程式的入口點。(提示:如果ExEinfoPE仍然能夠正常識別這個程式,把PE頭靠近末尾的幾個位元組寫0一般就可以了)但這樣做可能會導致更多的防毒引擎將其識別為可疑程式。


大家可以舉一反三,嘗試一下其他壓縮殼的修改,並測試一下防誤報的效果。