
.net框架中包括有一组.net框架类库(Framework Class Library,简称FCL)程序集,其中含 有几千个类型的定义,每个类型都提供了某种功能。
IL又称为(interpretative language 解释语言),我们.NET开发人员必定离不开IL,就算您没有学习,也一定可以在各处看到它的身影。而且IL也是.NET唯一懂得的语言,我们每天其实都在使用着ILIL是中间层语言
上层代码编译完成后都要转换为中间语言供CLR使用
IL为Intermediate Language
有时候也叫Microsoft Intermediate Language
中间语言使得在.Net中各种语言的方便交互成为了可能。
assembly, 这里把它翻译为配件, 以示和组件(Component)加以区别.
一个配件有时候是指一个EXE或者DLL文件, 实际上是一个应用程序(就是指带有主程序
入口点的模块)或者一个库文件. 但是配件实际上可以是由一个或者多个文件组成
(dlls, exes, html等等), 代表一组资源, 以及类型的定义和实现的集合. 一个配件也可
以包含对其它配件的引用. 所有这些资源、类型和引用都在一个列表(manifest)中描述?nbsp
U飧鳇anifest也是配件的一部分,所以配件是一个自我描述的,不需要其它附加的部件
对其描述!配件的另一个重要特性是,它是.Net环境下类型标识的一部分,也可以说
是基本单位。因为,区分一个类型的标识就是包含这个类型的配件名字加上类型名本身。
举个例子,配件A定义了类型T, 配件B也定义了同名类型T,但是.Net把这两个类型认为是
不同的类型。 注意,不要把配件(assembly)和名字空间(namespace)混淆起来。其实
名字空间仅仅是用来把类型名用树的形式组织起来的手段。对于运行是环境来讲,类型名
就是类型名,和名字空间一点关系都没有。 总之,记住配件名加上类型名唯一标识一个
运行时类型。 另外,配件也是.Net框架用于安全策略的基本单位,许多安全策略都是
基于配件的。
这里我们以修改Guid类为例,我们将修改这个类的内部构造,以便其始终构造值为0值(00000000-0000-0000-000000000000)的对象1,知道你要修改谁(dll的名称)
这很简单, 翻翻MSDN,你应该能找到你所调用的类库是哪一个,或者使用reflector可以得到更详尽的信息。从MSDN得知,Guid类在mscorlib.dll中
2,找到你要修改的dll,并拷贝出来,以便修改
mscorlib.dll位于GAC中,很可惜,windows只允许按照“可远观不可亵玩"的方式静静欣赏(尽管心急如焚)
我们现在需要将该dll在 *** 作系统中的实际路径找出来。
2.1 下载FileMon,其用于监视文件的被访问情况,我们可以通过他,找到文件路径。
2.2 写一个小程序,让该程序去访问(引用)你需要查找路径的文件,这里也就是我们的mscorlib。
static void Main(string[] args)
{
Guid guid = Guid.NewGuid()
Console.WriteLine(guid)
Console.Read()
}
代码中的Guid以及Console等都会访问mscorlib.dll。
2.3 运行FileMon,让他去监视mscorlib的访问,由于我们不知道mscorlib的具体路径(废话),但我们至少知道它在C:\WINDOWS\assembly下(至少知道在系统盘下),那么我们就将这个文件夹及其所有文件一块监视吧:
2.4,运行我们的小程序,FileMon将监视到所有到C:\WINDOWS\assembly下的访问,并将包含mscorlib的高亮,双击列表中的条目,其将自动打开文件所在的文件夹:
OK,现在找到该dll文件了,将其拷贝出来,以供我们修改,并将其路径记录下来以备将来使用(C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089)。另外,建议备份一下拷出来的dll。
3,利用ildasm反编译该dll,生成中间语言(IL)文件,我们将修改该IL文件
ildasm是.net自带的一个反编译工具,可以在SDK(C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\)中找到,但通过VS的控制台便可以使用了(具体使用方式,参考MSDN)
然后可以得到该程序集的IL文件:
它其实是一个文本文件,所以可以直接打开进行编辑,但建议使用Notepad++或 UltraEdit 文本编辑器,但打开后似乎有些让人有些崩溃,汪洋大海啊,如何找到我们需要修改的代码所在的位置呢
4,利用reflector查看所要寻找的类或方法的定义
打开reflector,查找所要寻找的类或方法,并查看其定义,假设我们需要的是Guid.NewGuid()方法:
切换到IL视图:
OK,有了该IL片段,要在mscorlib.dll.il的汪洋大海中查找该方法就很简单了(Ctrl-F)。
5,修改IL代码
在notepad++或UltraEdit中找到对应的方法。我们发现NewGuid()实际是调用其Guid(bool)方法,我们可以将其替换成默认构造函数(默认构造函数构造的guid为00000000-0000-0000-000000000000)这样一来调用NewGuid()方法时则始终返回0值了,也可以在调用Guid(bool)时传入true,我们采用后者:
.method public hidebysig static valuetype System.Guid
NewGuid() cil managed
{
// 代码大小 7 (0x7)
.maxstack 8
IL_0000: ldc.i4.0
IL_0001: newobj instance void System.Guid::.ctor(bool)
IL_0006: ret
} // end of method Guid::NewGuid
上面代码中的IL_0000: ldc.i4.0 表示将0(false)作为4字节整数入栈,我们将其中的0改成1:
.method public hidebysig static valuetype System.Guid
NewGuid() cil managed
{
// 代码大小 7 (0x7)
.maxstack 8
IL_0000: ldc.i4.1
IL_0001: newobj instance void System.Guid::.ctor(bool)
IL_0006: ret
} // end of method Guid::NewGuid
(注意,这里的 *** 作很简单,所以很单纯地修改了,若对于比较复杂的 *** 作请先学习IL相关知识)
然后保存你的修改。
6,编译IL代码,生成新的DLL
利用ms提供的ilasm可以将IL文件编译成dll:
(编译前别忘记关闭文本编辑器,比如ultraEdit会独占文件而导致无法访问)
7,将修改后的DLL放回到GAC
你可能会想到按照MSDN上提到的方法就如同安装自己普通的程序集一样将其安装到GAC,大概能猜想到这是不可行的,否则”不安全了“。 或者,我们刚才不是记录了mscorlib的路径的吗,直接复制粘贴进去覆盖不就行了,也许可以,也许不可以,只所以说不可以,原因有可能有二,一是根本不让访问页不让覆盖,二是程序.net程序运行时会检查程序集版本。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)