以下几个方面用来区分不同的程序集:
○ 程序集名称:Name
○ 程序集版本:Version
○ 程序集公匙: Public Token
○ 程序集文化:Culture
如果没有很严格地按照上面的几个方面来创建程序集,程序集是很容易被篡改的。本篇体验篡改程序集。
→清空F盘as文件夹下的所有文件
→在as文件夹下创建Dog.cs类,用记事本打开,编写如下,保存
using System;
public class Dog{public static void MakeSound(){Console.WriteLine("汪汪汪");
}}
→把Dog.cs编译成程序集
// Metadata version: v4.0.30319
.assembly extern mscorlib
{.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .zV.4..
.ver 4:0:0:0}.assembly Dog{.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..WrapNonEx63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.hash algorithm 0x00008004.ver 0:0:0:0}.module Dog.dll// MVID: {A8BAEEAB-2DF4-425C-B851-87260378D735}
.imagebase 0x10000000.file alignment 0x00000200.stackreserve 0x00100000.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x00400000
// =============== CLASS MEMBERS DECLARATION ===================
.class public auto ansi beforefieldinit Dogextends [mscorlib]System.Object{.method public hidebysig static void MakeSound() cil managed{// 代码大小 13 (0xd)
.maxstack 8IL_0000: nopIL_0001: ldstr bytearray (6A 6C 6A 6C 6A 6C ) // jljljl
IL_0006: call void [mscorlib]System.Console::WriteLine(string)IL_000b: nopIL_000c: ret} // end of method Dog::MakeSound
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{// 代码大小 7 (0x7)
.maxstack 8IL_0000: ldarg.0IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret} // end of method Dog::.ctor
} // end of class Dog
○ .assembly Dog表示程序集的名称是Dog
○ .assembly Dog语句块中的.ver 0:0:0:0表示程序集的版本没有经过特别的设置
○ .assembly Dog语句块中也没有Public Token和Culture相关信息
→在as文件夹下创建MainClass.cs类,用记事本打开,编写如下,保存
using System;
class MainClass
{static void Main(){Dog.MakeSound();}}
→编译MainClass.cs,引用Dog.dll,生成MainClass.exe
→执行MainClass.exe
→现在要篡改Dog.dll,先删除Dog.dll
→在as文件夹下创建AnotherDog.cs类,用记事本打开,编写如下,保存
using System;
public class Dog{public static void MakeSound(){Console.WriteLine("小狗怎么叫~");
}}
→编译AnotherDog.cs类,同样生成一个Dog.dll程序集
→再次运行MainClass.exe
篡改程序集成功。
总结:在生成程序集的时候,如果没有对程序集的版本、公匙、文化等进行特别的设置,程序集很容易被篡改。
“C#程序集系列”包括:
C#程序集系列01,用记事本编写C#,IL代码,用DOS命令编译程序集,运行程序
C#程序集系列02,使用记事本查看可执行程序集的IL代码
C#程序集系列03,引用多个module
C#程序集系列04,在程序集包含多个module的场景下理解关键字internal
C#程序集系列05,让程序集包含多个module
C#程序集系列06,程序集清单,EXE和DLL的区别
C#程序集系列07,篡改程序集
C#程序集系列08,设置程序集版本
C#程序集系列09,程序集签名
C#程序集系列10,强名称程序集
C#程序集系列11,全局程序集缓存
C#程序集系列12,C#编译器和CLR如何找寻程序集
C#程序集系列13,如何让CLR选择不同版本的程序集
参考资料:
http://www.computersciencevideos.org/ created by Jamie King