IL DASM反編譯工具 使用C#的猿人或多或少都會對微軟的IL反編譯工具(ildasm.exe)有所認識。我最早接觸到這工具是公司同事使用他反編譯exe程式,進行研讀和修改。感覺他還是很強大。 IL是微軟平臺上的一門中間語言,我們常寫的C#代碼在編譯器中都會自動轉換成IL,然後在由即時編譯器(JI ...
IL DASM反編譯工具
使用C#的猿人或多或少都會對微軟的IL反編譯工具(ildasm.exe)有所認識。我最早接觸到這工具是公司同事使用他反編譯exe程式,進行研讀和修改。感覺他還是很強大。
IL是微軟平臺上的一門中間語言,我們常寫的C#代碼在編譯器中都會自動轉換成IL,然後在由即時編譯器(JIT
Compiler)轉化機器碼,最後被CPU執行。ildasm.exe反編譯工具將IL彙編成可跨平臺可執行的(pe)文件。可供我們瞭解別人代碼和修改。有了他我們看待問題可以不用停留在編輯器層面,可深入中間層。
VS中增加IL DASM工具
我們在安裝VS同時都會自動安裝ildasm工具,無需另行安裝。ildasm工具打開方法如下圖:
我們也可以直接wind+R.輸入:C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\ildasm.exe (window 7 64位 操作系統安裝目錄) 同樣可以打開ildasm。
我們也可以把ildasm工具增加到我們常用的VS中。
1.工具(Tools)-->外部工具(External Tools..)
2.添加內容填寫對應信息。命令:C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\ildasm.exe
(window 7 64位 操作系統安裝目錄) 。
已上信息填寫完成後,在“工具”選擇卡中能找到我們剛增加的外部工具名稱(IL_DASM)。增加完成後可以小試一把。
國際慣例來段"Hello World"。代碼編寫完後直接F6生成exe文件,然後工具-->IL_DASM-->確認(無需修改任何參數,預設目標文件路徑)。系統會彈出IL工具,我們雙擊Main方法。
這時可以看到Main方法在IL中編譯的代碼。感覺有點陌生不易看懂。 還有IL編譯出現的三角型,正方型都是啥!
IL DASM 基礎
1.圖標含義
使用IL反編譯出項目代碼
MANIFEST:是一個附加信息列表,主要包含程式集的一些屬性,如程式集名稱、版本號、哈希演算法等;
Democode:項目名稱
Democodeing.Common:命名空間
Democodeing.ICar:介面
Democodeing.Program:類,主要查看存類下麵的內容。
.class 類信息項代碼:
.class private auto ansi beforefieldinit DemoCoding.Program
extends [mscorlib]System.Object
{
} // end of class DemoCoding.Program
1).class,表示Program是一個類。並且它繼承自程式集—mscorlib的System.Object類;
2)private,表示訪問許可權;
3)auto,表示程式的記憶體載入全部由CLR來控制;
4)ansi,是為了在沒有托管代碼與托管代碼之間實現無縫轉換。這裡主要指C、C++代碼等;
5)beforefieldinit,是用來標記運行庫(CLR)可以在靜態欄位方法生成後的任意時刻,來載入構造器(構造函數);
.ctor 方法代碼:
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// 代碼大小 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method Program::.ctor
1)cil managed:表示其中為IL代碼,指示編譯器編譯為托管代碼;
2).maxstack:表示調用構造函數.otor期間的評估堆棧(Evaluation Stack) ;
3) IL_0000:標記代碼行開頭;
4)ldarg.0:表示轉載第一個成員參數,在實例方法中指的是當前實例的引用;
5)call:call一般用於調用靜態方法,因為靜態方法是在編譯期就確定的。而這裡的構造函數.otor()也是在編譯期就制定的。而另一指令callvirt則表示調用實例方法,
它是在運行時確定的,因為如前述,當調用方法的繼承關係時,就要比較基類與派生類的同名函數的實現方法(virtual和new),以確定調用的函數所屬的Method
Table;
6)ret:表示執行完畢,返回;
Main() 靜態方法代碼:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// 代碼大小 19 (0x13)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "Hello World"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: call string [mscorlib]System.Console::ReadLine()
IL_0011: pop
IL_0012: ret
} // end of method Program::Main
1) hidebysig:表示當把此類作為基類,存在派生類時,此方法不被繼承,同上構造函數;
2).entrypoint:指令表示CLR載入程式時,是首先從.entrypoint開始的,即從Main方法作為程式的入口函數;
3)nop:為空該指令,主要給外部設備或者指令間隙準備時間;
4)ldstr:創建String對象變數"Hello World." ;
5)pop:取出棧頂的值。當我們不需要把值存入變數時使用;
使用IL DASM 修改EXE程式代碼
1.打開IL工具,選擇所要修改的EXE程式。
2.文件-->轉儲。確定後選擇另存路徑,會生成二個文件:*.il 和 *.res
3.用記事本打開*.il修改裡面的內容:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// 代碼大小 19 (0x13)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "Hello World-[已使用il工具修改過...]"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: call string [mscorlib]System.Console::ReadLine()
IL_0011: pop
IL_0012: ret
} // end of method Program::Main
4.把修改後的代碼編譯成EXE程式。
ilasm /exe /output=C:\CK.exe /Resource=C:\Users\Ck\Desktop\coding.res C:\Users\Ck\Desktop\coding.il
修改就這麼簡單。運行修改後的EXE程式,值已修改。