【轉載】關於 .Net 逆向的那些工具:反編譯篇

在項目開發過程當中,估計也有人和我遇到過一樣的經歷:生產環境出現了重大Bug亟需解決,而恰恰就在這時倉庫中的代碼卻不是最新的。在這種狀況下,咱們不能直接在當前的代碼中修改這個Bug而後發佈,這會致使更嚴重的問題,由於至關於版本回退了。即便咱們眼睜睜的看着這個Bug兩行代碼就能搞定,在咱們的代碼沒更新到最新版本以前,都不敢輕舉妄動。可是客戶的呼聲讓人抵擋不住,客戶聲稱的分分鐘多少多少的經濟損失咱們也承受不起。這時若是你是作PHP開發的,你會慶幸,由於你能夠直接去生產環境修復掉這個Bug讓客戶先閉嘴而後再慢慢折騰你那出問題的代碼管理工具;而若是你作是.Net抑或C/C++開發的,就沒這麼輕鬆了。面對服務器上拷下來的有着重大Bug的dll或exe,你很難直接去修改它裏面的代碼邏輯,只能利用一些逆向的技巧和工具了。 php

因爲我這裏是.Net的環境,因此我決定在這篇博客裏介紹下如何利用逆向工具來修改生產上的.Net程序集。可是就在我決定寫這篇博客的時候我忽然發現,其實,若是你只是單純的修改一個.Net程序集中的某個方法或功能,並且這個程序集仍是出自於你本身或你所在團隊之手,這實在是一件很是容易的事情,這和破解別人的程序徹底不一樣,你不會遇到沒法破解的加密算法,也不會遇到讓人噁心的加殼混淆。利用搜索引擎能夠搜到大量這樣的教學文章,因此我改變了下主意,決定不在這篇博客中重複造輪子,而是把已有的輪子一個個的列出來總結一下。 html

這篇博客主要彙總一些.Net反編譯相關的工具。 node

1、ilasm & ildasm

ilasmildasm 都是微軟官方提供的.Net編譯與反編譯工具,可謂是.Net逆向中的瑞士軍刀。這兩個工具的位置分別位於.Net Framework目錄和Microsoft SDK目錄中: git

C:\Windows\Microsoft.NET\Framework\v2.0.50727\ilasm.exe 程序員

C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\ildasm.exe github

這裏有一篇文章詳細介紹瞭如何經過ilasm 和 ildasm 修改.Net程序,歸結起來就下面幾個步驟: 算法

  1. 使用工具ildasm打開要逆向的.Net程序,並另存爲IL文件;
    ildasm程序有命令行和圖形界面兩種運行模式,通常狀況下雙擊ildasm便可啓動圖形界面的主程序,而後經過菜單項 File -> Dump ,選擇UTF-8編碼,便可導出到IL文件中。若是是以命令行模式運行的話,能夠打開Visual Studio自帶的開發環境命令行工具(Developer Command Prompt for VS2012),這樣能夠不用關心ildasm所處的目錄,直接運行下面的命令:ildasm test.exe /out:test.il
    若是程序含資源文件的話,除了生成一個IL文件,可能還會有其餘的*.res文件等。編程

  2. 打開IL文件閱讀IL源碼並定位到須要修改的代碼處,對IL代碼進行修改;
    使用ilasm 和 ildasm 反編譯.Net程序須要瞭解一點MSIL的語法,這樣不管閱讀仍是修改IL文件都要方便的多,好在MSIL的語法並非很複雜,花一天的時間研究下仍是值得的。這裏有一篇不錯的MSIL教程
    若是真的對MSIL不熟悉不會編寫MSIL的話,其實也沒有大礙,只要你會大概的看懂MSIL源碼和會編寫C#程序也能夠。能夠參考這篇文章,具體的方法是:用C#編寫你須要修改的方法,而後編譯成exe/dll文件,再經過ildasm反編譯成IL文件,從這個IL文件中複製出須要的IL源碼覆蓋掉以前那個須要修改的IL文件中的相關代碼,這樣你就算不會MSIL,也能修改IL文件了,確實有點偷樑換柱的味道。c#

  3. 使用ilasm將IL文件從新編譯成.Net程序。
    最後,使用ilasm程序從新編譯IL文件:ilasm test.il /output:test-mod.exe,再使用PEVerify執行校驗確保文件無誤:PEVerify test-mod.exe。若是一切順利的話,將test-mod.exe替換掉老的test.exe便可。
    默認狀況下,ilasm將生成exe文件,若是須要生成dll文件,可使用下面的命令:ilasm test.il /dll /output:test-mod.dll,若是須要集成資源,則須要指定/resource參數:ilasm test.il /resource:test.res /output:test-mod.exe服務器

2、.Net Reflector & Reflexil

雖然說ilasm 和 ildasm是.Net逆向中的瑞士軍刀,可是一提起.Net逆向,其實不少人第一反應都是Reflector這款神器,而對微軟提供的這兩個官方工具知之甚少。這一方面是因爲Reflector良好的用戶體驗和強大的插件功能,另外一方面要歸功於Reflector堪稱完美的智能反編譯能力,使用它不只能看到反編譯後的IL源碼甚至能直接反編譯出C#源碼,並且和編寫時的代碼幾無二致,若是須要還能夠直接另存爲工程文件用Visual Studio打開。
Reflector是RedGate開發的.Net逆向工具,單純的Reflector程序只有反編譯功能,能夠查看IL或C#源碼,以及導出源碼。並不能修改.Net程序。幸虧咱們有sailro編寫的Reflexil插件,Reflexil基於Mono.Cecil,是一個強大的程序集編輯器。Reflector + Reflexil 可謂是強強聯合,和 ilasm + ildasm 這個組合比起來簡直是大巫見小巫。

若是是第一次加載Reflexil插件,打開Reflector,在 Tools -> Add-Ins -> Add -> 選擇Reflexil.dll,之後就能夠直接在Reflector的Tools菜單中打開了。用Reflector打開test.exe,選擇某個函數能夠發現IL代碼顯示在下方的Reflexil窗口中,能夠點擊右鍵Edit,Delete,Create等操做。還能夠修改類或方法的訪問權限等,好比將private改爲public。
另外,在編輯IL的操做中還有一個Replace all with code選項,經過這個能夠直接用C#代碼來對程序進行修改,無需你熟悉MSIL語法,相似於上一節介紹的「偷樑換柱」的方法,只不過集成在Reflexil中讓咱們的操做更方便了。以下圖所示:

reflexil.png

Reflexil的做者在codeproject上寫了一長篇Reflexil的各類實用技巧,能夠去這裏看看。Reflexil惟一的缺憾是並無和Reflector無縫結合,使用Reflexil修改完IL源碼或類的屬性後,上面Reflector中顯示的IL或C#源碼並無當即更新,必須保存修改後使用Reflector從新打開才能看到所作的修改。這多少有點讓人感受不爽,但比起 ilasm + ildasm 這種純手工逆向工具來說已經好太多了。

還有一點要說明的是:.Net Reflector很早就轉向收費軟件了,並且價格不菲,普通版95刀每用戶,專業版甚至要199刀。對於咱們大多數開發人員來講逆向並非咱們的平常工做,可能只是偶爾好奇而爲之,這樣爲了偶爾的好奇而須要支付這麼多的money實在是讓人有點捨不得。因而一部分人走上了破解和盜版的路,而另外一部分人走上了開源的路。這也是下一節將要介紹的ILSpy工具的由來。

3、ILSpy

ILSpy 是爲了徹底替代收費的Reflector而生,它是由 iCSharpCode 團隊出品,這個團隊開發了著名的 SharpDevelop 。ILSpy 徹底開源,目前還處於開發階段,不少功能還不夠完善,可是具備強大的反編譯功能對於咱們來講已經足夠了。對於ILSpy的使用和上面的Reflector徹底相似,此處再也不贅述。

在我寫這篇博客的時候,ILSpy最新的發佈版本爲3/9/2015 Version 2.3,尚未和Reflexil具備相似功能的代碼修改插件。可是在ILSpy的Further Down the Road能夠看到,這樣的功能也已經在計劃之中了。

ilspy-down-road.png

雖然官方的發佈版本尚未提供Reflexil的功能,可是Reflexil的做者sailro很早就在項目描述中介紹了對ILSpy的支持:

Reflexil is an assembly editor and runs as a plug-in for Red Gate's Reflector, ILSpy and Telerik's JustDecompile. Reflexil is using Mono.Cecil, written by Jb Evain and is able to manipulate IL code and save the modified assemblies to disk. Reflexil also supports C#/VB.NET code injection.

得益於ILSpyReflexil都是開源的,咱們從GitHub上把最新的代碼Clone下來並進行編譯,Reflexil\Plugins\Reflexil.ILSpy這個目錄下是Reflexil插件的源碼,咱們將編譯後的全部dll文件拷貝到ILSpy的bin目錄,運行ILSpy就能在View選項中看到Reflexil了,以下圖:

ilspy-view.png

關於ILSpy和Reflexil的操做和上面介紹的Reflector幾乎同樣,不過有一點很讓人振奮,ILSpy提供了更新對象模型的功能,這樣Reflexil插件就能夠在修改完代碼後直接更新ILSpy的代碼了,而不用像Reflector那樣須要從新加載才能看到所作的修改。以下圖所示,點擊「Update ILSpy object model」,上面ILSpy的代碼會當即更新:

ilspy-reflexil.png

4、Just Decompile

相信很多人都聽過 Telerik 公司,該公司很是關注於.Net平臺下的控件研發,而且發佈了不少著名的開發工具,例如:Fiddler 和 JustDecompile。JustDecompile 正是 Telerik 的一款.Net反編譯工具,和ILSpy不一樣的是,它並非徹底開源的,可是它有着商業化的技術支持,這一點很是可貴。不只如此,Telerik 也開源了JustDecompile的引擎部分:JustDecompile Engine,這也是很是不錯的。
JustDecompile在使用上和其餘的反編譯工具差很少,並且它也具備插件系統,官方目前提供了三個插件,以下:

jd-plugins.png

其中Assembly Editor正是Reflexil。從菜單Plugins中調出Reflexil,enjoy it!

jd-reflexil.png

5、dotPeek

JetBrains是捷克的一家軟件開發公司,出品了大量著名的開發工具,包括:IntelliJ IDEA、PHPStorm、ReSharper、TeamCity、YouTrack等等,每一款產品都如雷貫耳。dotPeek 是 JetBrains 開發的一款.Net反編譯工具,是.Net工具套件中的一個,其餘的還有dotTrace、dotCover 和 dotMemory。相比於前面幾款工具來講,dotPeek算比較小衆的一款。我的感受它最大的特點就是Visual Studio風格,這對於那些長期在Visual Studio下進行開發的人來講應該更親切一點。

dotPeek.png

不過dotPeek目前好像尚未相似於Reflexil這樣的編輯插件,自己也並無編輯功能。若是咱們須要修改程序集的話,能夠另存爲工程文件,使用Visual Studio打開直接修改源碼從新編譯。

6、更多選擇

實際上,利用上面介紹的這些工具已經徹底可以知足你的需求了。可是咱們老是有更多選擇(等有時間的時候再玩這些吧):

另外,本文中的一些工具能夠在此下載

TODO:Mono.Cecil

這篇博客的主要目的原本只是在無源碼的狀況下修改.Net程序集,但到這裏已經徹底演變成了.Net反編譯工具的羅列清單。Never mind,關於.Net程序集的修改,上面最耀眼的非Reflexil莫屬。而Reflexil依賴於Jb Evain所寫的Mono.Cecil,Cecil 是一個對於Mono項目具備戰略意義的函數庫。它爲不少項目(包括:Mono Debugger、Gendarme 和 MoMA 等)提供了內部處理的能力,並且 Cecil 也能操做編譯好的CIL,並把修改後的程序集保存到磁盤裏。

做爲一個.Net程序員,修改.Net程序集最終極的方法莫過於本身動手寫出修改程序集的代碼,利用Mono.Cecil能夠輕鬆實現這個目的。暫且給本身挖個坑,之後填上吧。

參考

  1. 操做步驟:用ildasm/ilasm修改IL代碼 - dudu - 博客園
  2. Ilasm.exe(IL 彙編程序)
  3. Ildasm.exe(IL 反彙編程序)
  4. MSIL Tutorial
  5. 經過學習反編譯和修改IL,閱讀高人的代碼,提升自身的水平。 - 辰 - 博客園
  6. 初識Ildasm.exe——IL反編譯的實用工具 - Youngman - 博客園
  7. Reflector 已經out了,試試ILSpy - James Li - 博客園
  8. c#:Reflector+Reflexil 修改編譯後的dll/exe文件 - 菩提樹下的楊過 - 博客園
  9. 幾款 .Net Reflector 的替代品 - 張志敏 - 博客園
  10. Assembly Manipulation and C# / VB.NET Code Injection - CodeProject

 

【轉自】http://www.aneasystone.com/archives/2015/06/net-reverse-decompiling.html

相關文章
相關標籤/搜索