17.1 学习cil语法的原因
将*.cs代码文件,通过编译器(ilasm.exe),编译成CIL代码
CIL是.NET平台母语
17.2 CIL指令、特性和操作码
CIL编译器识别的标记进一步被划分到3个类别中
CIL指令(定义程序集用到的命名空间,类型,成员。使用(.)前缀。如:.namespace,.class)
CIL特性(如何处理一个CIL指令。public特性,extends特性)
CIL操作码(如:ldstr 定义一个字符串变量,box装箱,unbox拆箱)
CIL助记符
+ 0x58(十六进制表示) Add(助记符)
- 0x59(十六进制表示) sub(助记符)
分配一个新对象 0x73(十六进制表示) newobj
17.3 入栈和出栈:cil基于栈的本质
c#
public void PrintMessage() { string myMessage = "Hello."; Console.WriteLine(myMessage); }
CIL
17.4 正反向工程
将exe文件转成 *il,在将*il 转成 exe。
步骤一:HelloProgram.cs
using System; class Program { static void Main(string[] args) { Console.WriteLine("Hello CIL code"); Console.ReadLine(); } }
步骤二:将cs转成exe文件
步骤三:将exe 转成 *il 文件
第四步:打开il文件,并修改il 文件
// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.1
// Metadata version: v4.0.30319
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
//添加对System.Windows.Forms.dll程序集的引用
.assembly extern System.Windows.Forms
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly HelloProgram
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module HelloProgram.exe
// MVID: {F8962BDF-776A-4346-B6B4-3795CAE13BBF}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x00000000023A0000
// =============== CLASS MEMBERS DECLARATION ===================.class private auto ansi beforefieldinit Program
extends [mscorlib]System.Object
{
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// 代码大小 19 (0x13)
.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)//System.Windows.Forms.MessageBox.Show("CIL is way cool")
pop
ret
} // end of method Program::Main.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} // end of class Program
// =============================================================// *********** 反汇编完成 ***********************
// 警告: 创建了 Win32 资源文件 C:\1.res
第五步:将*il 转成 exe
17.5 cil指令和特性
17.5.1 在CIL中指定外部引用程序集
.assembly extern 外程序集名{
.publickeytoken=(公共密匙)
.ver 版本
}
window浏览器查看.NET4 GAC
.NET1.0-.NET3.5基础类库位于C:\windows\assembly
.NET4 位于c:\window\Microsoft.Net\assembly\GAC_MSIL(如:.Net4.0版本下编译_版本_公匙标记)
17.5.2 在CIL中定义当前程序集
.assembly 程序集名
17.5.3 在CIL中定义命名空间
.namespace 命名空间名{}
17.5.4 在CIL中定义类类型
.class public 类名{}
17.5.5 在CIL中定义和实现接口
.class public interface 接口名{}
.class public a implements 命名空间.接口名{}
17.5.6 在CIL中定义结构
.class public sealed value 结构名{}
17.5.7 在CIL中定义枚举
.class public sealed enum 枚举名{}
17.5.8 在CIL中定义泛型
.class public 泛型名称`1<T>{} //一个参数泛型
// 引用外部mscorlib.dll程序集.
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 4:0:0:0
}
// 定义CILTypes程序集
.assembly CILTypes
{
.ver 1:0:0:0
}
// 单文件程序集模块(给出这个.NET二进制文件的官方名称 CILTypes.dll).
.module CILTypes.dll
// 定义MyNameSpace命名空间.
.namespace MyNamespace
{
// 定义接口.
.class public interface IMyInterface {}
//定义MyBaseClass类
.class public MyBaseClass
{
// 变量.
.field private string stringField="hello"
.field private int32 intField=int32(42)
// 实例化层次的构造函数.
.method public hidebysig specialname rtspecialname
instance void .ctor(string s, int32 i) cil managed
{
// TODO: Add implementation code...
}
// Property syntax.
.method public hidebysig specialname
instance string get_TheString() cil managed
{
// TODO: Add implementation code...
}
.method public hidebysig specialname
instance void set_TheString(string 'value') cil managed
{
// TODO: Add implementation code...
}
.property instance string TheString()
{
.get instance string
MyNamespace.MyBaseClass::get_TheString()
.set instance void
MyNamespace. MyBaseClass::set_TheString(string)
}
}
//MyDerivedClass实现IMyInterface,并扩展MyBaseClass(要完整名字)
//注意:extends子句必须在implements之前
.class public MyDerivedClass
extends MyNamespace.MyBaseClass
implements MyNamespace.IMyInterface {}
//定义结构
.class public sealed value MyStruct{}
//定义枚举
.class public sealed enum MyEnum
{
.field public static literal valuetype
MyNamespace.MyEnum A = int32(0)
.field public static literal valuetype
MyNamespace.MyEnum B = int32(1)
.field public static literal valuetype
MyNamespace.MyEnum C = int32(2)
}
//一个参数的泛型
.class public MyGenericClass`1<T>{}
}
编译 CILTypes.il文件
ilasm /dll cilTypes.il
17.6 .net基础类库、c#和cil数据类型的映射
17.7 在CIL中定义类型成员
.NET类型可以支持多种成员。
枚举类型由一系列名称/值的对构成。
结构和类则有构造函数、字段、方法、属性、静态成员等。
17.7.1 在CIL中定义数据字段
枚举、结构和类都支持数据字段。在每个子句中都将用到 .field 指令。
//定义枚举
.class public sealed enum MyEnum
{
.field public static literal valuetype
MyNamespace.MyEnum A = int32(0) //MyEnum.A
.field public static literal valuetype
MyNamespace.MyEnum B = int32(1)
.field public static literal valuetype
MyNamespace.MyEnum C = int32(2)
}
//定义变量
.field private string stringField="hello"
.field private int32 intField=int32(42)
17.7.2 在CIL中定义类型的构造函数