利用 ildasm.exe 將組件反組譯為 IL 程式碼,修改後再用 ilasm.exe 重新編譯為組件。適用情境:
[helpstring])reflector.exe 可將 IL 轉為 C#,但無法處理 C# 不支援的 IL 結構,此時必須使用 ildasm.exe。// HelloProgram.cs
using System;
class Program {
static void Main(string[] args) {
Console.WriteLine("Hello CIL code!");
Console.ReadLine();
}
}
csc /out:D:\HelloCilCode\HelloProgram.exe D:\HelloCilCode\HelloProgram.cs
ildasm.exe D:\HelloCilCode\HelloProgram.exe /out:HelloProgram.il
產生 HelloProgram.il 與 HelloProgram.res,原始 .cs 與 .exe 可刪除。
// 外部組件參考
.assembly extern mscorlib {
.publickeytoken = (B7 7A 5C 56 19 34 E0 89)
.ver 2:0:0:0
}
// 目前組件定義
.assembly HelloProgram {
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module HelloProgram.exe
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003
.corflags 0x00000001
// 類別定義
.class private auto ansi beforefieldinit Program
extends [mscorlib]System.Object
{
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 8
IL_0000: nop
IL_0001: ldstr "Hello CIL code!"
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
}
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
}
}
[mscorlib]System.Console::WriteLine(string).entrypoint 標示程式進入點.maxstack 宣告評估堆疊最大深度IL_XXXX:)可自訂或移除(無分支/迴路時)目標:引用 System.Windows.Forms.dll,在 Main 中呼叫 MessageBox.Show。
// 新增外部組件參考
.assembly extern System.Windows.Forms
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89)
.ver 2:0:0:0
}
// 修改 Main 方法
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 8
ldstr "CIL is way cool"
call valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult
[System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string)
pop
ret
}
注意: 版本號與公開金鑰權杖需依實際 GAC 中組件調整(可從 C:\Windows\assembly 查詢)。
ilasm /exe HelloProgram.il /output=NewAssembly.exe
成功後執行 NewAssembly.exe 將彈出訊息方塊。
| 參數 | 用途 |
|---|---|
| /debug | 包含偵錯資訊(區域變數名稱、行號) |
| /dll | 輸出 .dll |
| /exe | 輸出 .exe(預設) |
| /key | 使用 .snk 強名稱簽署 |
| /output | 指定輸出檔名 |
下一篇將深入探討 IL 指令與屬性的語法語意,掌握 IL 程式設計核心。