浙江麻将机生产厂家
危險漫步博客
有時候,正是那些意想不到之人,成就了無人能成之事。
文章1443 瀏覽13842297

Net生肉研究報告

 我們在《論.Net熟肉的正確打開方式》已經探討了.Net熟肉,也就是沒有經過任何保護,直接就把編譯后的MSIL(.Net中間語言,也可理解為.NetFrameWork虛擬機的字節碼)放出來的.Net程序的逆向方法。相信很容易感覺到,在現在.Net逆向工具如此成熟的環境下,直接放出.Net熟肉無異大聲宣布我準備任人魚肉。這已經不是一兩處關鍵代碼被偷窺的問題,而是相等于整套程序代碼拱手送人,重新編譯發布也是分分鐘的事情。如果有靠寫.Net編寫小玩意賣錢的同學,看到這里相信已經深吸了一口冷氣。不過矛盾矛盾,有矛自然有盾,.Net的逆向安全雖然不溫不火,但整個生態環境實際已經相當成熟。逆向的工具前面已經說了,保護工具,也即所謂的加殼工具,也已經經行過幾輪的迭代。保護的思路,概括來看大抵有兩種,一種是延續傳統對PE文件的保護方式,業界稱為整體保護方案;一種是專門針對.Net熟肉一被拖進逆向工具,就把底褲都亮出來的尿性,采取了加入垃圾以及各種打亂的混淆保護的策略,有意思的是,大概連微軟都知道.Net的統一編譯成MSIL特性簡直是為逆向而生,在VisualStudio中也專門提供了名為dotfuscator的混淆工具。保護的方法不多就兩種,但具體的實現仍然百家爭鳴。從本篇開始我們將作一個系列來逐一研究。不過要說明的是,兩種保護技術并不相斥,很多保護方案都是融合了兩種保護思路,以求互為犄角。

這一篇首先看看整體保護方案。我們知道.Net程序雖然需要首先安裝.NetFrameWork才能運行,但它也是exe結尾,實際上也同樣采用和普通exe文件相同的PE文件結構,當然,會有一些拓展,后面介紹手工脫殼方法的時候再具體介紹。這里只需要知道,.Net程序也是PE結構,也包含各種頭各種節,也有OEP和IAT,傳統面向PE結構的保護殼,保護的也是這些東西,理論上套上就該能用了,也就是在.Net的PE結構上套一層保護殼,將內部結構加密隱藏就保護起來了,在運行的時候再解密釋放出來。不過.Net畢竟有一些新的機制,因此還需要進行一些兼容性的調整,不過大致過程和普通保護殼是一樣的。

口說無憑,首先看一款老牌的.Net加殼工具.NetReactor(請注意和逆向工具.NETReflector區分,兩個是不同單詞),這是款最早出現的專門針對.Net的保護殼之一,現在還在更新。早期的.NetReactor主要依靠整體保護的方案來進行保護,可以以此對比觀察加殼前后的變化。

先編譯一個.Net程序,觀察其內部結構如圖1所示。

圖1

這是張很經典的.Net程序文件結構圖,可以注意到兩點:1.如上所說,它擁有傳統PE結構的全部信息,也就是完整繼承了傳統的PE結構;2.它擁有.Net特有的數據結構,可以看到有一項名為.NETDiretory的數據項,這是.Net程序的一大特征,下面還有幾個Meta開頭的數據結構,以及一些Table,這些稱為元數據,在后面的文章將詳細介紹。.NETDiretory和元數據是查看某個EXE文件是否為有效.Net程序的重要判斷依據。同時也是判斷一個.Net程序是否啟用整體保護方案的重要依據。請記住這句話。

《論.Net熟肉的正確打開方式》介紹了.Net逆向神器.NETReflector,現在就看看保護后的效果。用.NETReflector打開被保護的程序,提示:isnota.NETmodule,也就是.NETReflector認為它不是一個有效的.Net程序。再來看看.NetReactor保護后的文件結構如圖2所示。

圖2

現在變成了傳統的PE結構,所有.Net程序特有的信息都被加密保護起來了。同時也由于.Net相關的文件結構均已不存在,被保護的程序不再是一個有效的.Net程序,也就不再能夠使用.NETReflector逆向了。因此起到了防止逆向的效果。到這里為止,對.Net程序的整體保護和傳統對PE文件的加殼保護并沒有很大區別,同樣是對敏感的數據結構進行加密,保護后原文件相關的二進制信息是無法直接查看的。是不是進行了整體保護,就不再能夠逆向.Net程序了呢?當然不是,為了對抗傳統的加殼技術,以及發展出多種脫殼工具和技術,.Net的整體保護既然也類似于加殼,當然也就會有對應的脫殼工具和技術。我們知道,傳統的加殼軟件,會在運行時還原或部分還原數據結構(部分信息可能仍存于加密狀態以防止逆向,譬如IAT等),以保證程序同義執行,也即保持功能的一致性,能像原來那樣運行。.Net的整體保護也一樣,會在運行時還原原來的.Net程序。如果能有一款工具抓取此時的內存數據,不就能DUMP得原來的.Net程序了嗎?真的就有這么一款專門針對.NetDump脫殼的工具,而且非常自動化,能完成從DUMP到REBUILD一條龍工作,更重要的是,操作非常簡單。這款有點半仙味道的工具叫做NETUnpack,如圖3所示。

圖3

用法非常簡單。我們以脫.NetReactor主程序為例子進行演示。雖然我們已經知道.NetReactor采用了整體保護的方案,但我們還是嘗試.NETReflector打開,OK,提示錯誤,如圖4所示。

圖4

接下來運行.NetReactor,然后運行NETUnpack。NETUnpack的界面一看就知道是進行列表,右邊有兩個按鈕,從上到下分別是Unpack,也就是脫殼,和Reflesh,也就是刷新功能。在列表中找到.NetReactor的進程(如果列表里沒有,點下面也就是刷新按鈕),然后點脫殼。這時會彈出一個保存框選擇保存路徑,這里推薦保存到一個文件夾當中,因為Dump下來的通常不止一個文件.

這次一共Dump了8個PE文件,其中第5個已經顯露出圖標.NetReactor的圖標,我們很容易就猜到這才是想要的主程序脫殼文件。把它放回原程序目錄,OK正常運行,說明它確實是主程序脫殼后的文件里。把它拖進.NETReflector,現在一切正常。.NetReactor的主程序都可以用這種方法脫殼,受它保護的.Net程序自然不在話下。NETUnpack是一款通用性很好的采用內存Dump技術的脫殼工具,遇到整體保護的.Net程序,不妨用它來試試。不過,這里我要提出一個看法,運行正常離逆向完成其實還有一點距離。原因?請看圖6。

圖6

雖然可以打開了,但各種名稱都變成了“亂碼”。可能已經有同學猜到,這就是所謂的混淆技術中的一種,是名稱混淆。名稱是無關乎運行的,但畢竟逆向分析人員是人,讀逆向代碼的也是人,軟件工程專門就講了代碼可讀的重要性,其中命名規范肯定是濃墨重彩的一章。后面我們將會繼續研究如何對抗采用混淆技術保護的.Net程序。

(完)

相關推薦

浙江麻将机生产厂家 时时彩官网 重庆老时时彩最快开奖 兴华彩票是真的假的 北京pk拾全天赛车计划 11选5在线预测 黑龙江时时g4 时时彩开奖结果 浙江快乐时时开奖号码 时时彩官方网 吉林时时走势图开奖