如何通过ildasm/ilasm修改assembly的IL代码
原文地址:http://kb.cnblogs.com/page/101162/
这段时间为跟踪一个Bug而焦头烂额,最后发现是Framework的问题,这让人多少有些绝望。所以到微软论坛提了个帖子,希望能得到些帮助。虽然论坛智能到能够判断楼主是否是MSDN订阅用户,以便尽快解决(传说MSDN订阅用户的问题能在两天内得到回复的,当时还很得意公司为我们购买的MSDN订阅账号),但得到的回复是“Could you file a bug report for this issue through Connect?”,绝望之后的又一次寒心啊。
看过payeasy的广告之后,便有了以下的这些内容,如何修改.net framework:
这里我们以修改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程序运行时会检查程序集版本。那么就试试看吧:
直接访问指定的路径看来是不行的了,正如下图所示:
不过没关系,我们可以通过第三方工具访问到该目录,可以通过刚才的FileMon,双击条目可以打开相应的文件目录,还有一种更常用的方便的方式是用TotalCommander, 可以方便的访问windows的各种隐藏路径。
将文件拖放到对应目录便可以覆盖了。
8, 删除程序集的本机映像(native image)
回到刚才用FileMon监视mscorlib访问时,大家可能会发现我们的小程序直接访问的并非mscorlib.dll, 而是一个名为mscorlib.ni.dll的文件(在C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\mscorlib\9adb89fa22fd5b4ce433b5aca7fb1b07\ 路径下),这是mscorlib.dll的本机映像(native image),关心过.net优化的朋友应该会知道我们可以通过ngen来将程序集生成本机映像以提高运行速度。那么程序将直接去访问该映像而非我们修改过的mscorlib.dll,这会导致我们的修改看不到效果。所以我们要将该映像删除。为什么是删除,而不是将修改过的mscorlib.dll利用ngen来生成一个新的映像而覆盖之? 原因很简单,大家自己想想吧。
首先,利用 ngen uninstall 命令从本机映像缓存中卸载本地映像,然后利用TotalCommander将其删除(注意,先关闭可以对所覆盖的程序集有所引用的应用程序,最好重启一下电脑,应该不用进安全模式删那么费劲)
9,验证一下成果:
class Program
{
static void Main(string[] args)
{
Guid guid1 = Guid.NewGuid();
Guid guid2 = Guid.NewGuid(); Console.WriteLine("the first GUID: {0}", guid1);
Console.WriteLine("the second GUID: {0}", guid2); Console.Read();
}
}
如果使用MS原版的mscorlib.dll我们将得到类似于下面的输出: 使用我们修改过的mscorlib.dll:
(另外,值得注意的是,Visual studio对某些程序集的引用来自于C:\Program Files\Reference Assemblies 下,所以,对于某些程序集如果要对VS引用造成影响则应该覆盖C:\Program Files\Reference Assemblies下的对应文件。这里的mscorlib不需要)
感谢阅读,仅供参考
如何通过ildasm/ilasm修改assembly的IL代码的更多相关文章
- 用ildasm/ilasm修改IL代码
原文地址:http://www.cnblogs.com/dudu/archive/2011/05/17/ildasm_ilasm_il.html 在开发中遇到这样一个场景,需要修改一个dll文件(.N ...
- 用ildasm/ilasm修改IL代码(操作步骤)
在开发中遇到这样一个场景,需要修改一个dll文件(.NET程序集)中某些地方的类型名称,但没有源代码,只能修改IL代码. 操作步骤如下: 1. 运行ildasm ildasm是由微软提供的.NET程序 ...
- 读懂IL代码就这么简单 (一)
一前言 感谢 @冰麟轻武 指出文章的错误之处,现已更正 对于IL代码没了解之前总感觉很神奇,初一看完全不知所云,只听高手们说,了解IL代码你能更加清楚的知道你的代码是如何运行相互调用的,此言一出不明觉 ...
- 读懂IL代码就这么简单
原文地址:http://www.cnblogs.com/zery/p/3366175.html 一前言 感谢 @冰麟轻武 指出文章的错误之处,现已更正 对于IL代码没了解之前总感觉很神奇,初一看完全不 ...
- 【转载】读懂IL代码就这么简单 (一)
一前言 感谢 @冰麟轻武 指出文章的错误之处,现已更正 对于IL代码没了解之前总感觉很神奇,初一看完全不知所云,只听高手们说,了解IL代码你能更加清楚的知道你的代码是如何运行相互调用的,此言一出不明觉 ...
- 小试ildasm,ilasm,ilspy
选择了微耕的软件(为什么选择它,因为微耕的二次开发实在太牛了,只给文档,一切技术问题都不回答.文档也是只公开基本的东西) 第一个功能:换文字 第二个功能:插入一个新的程序集,在做某些事情前先做我想做的 ...
- 浅谈 C# Assembly 与 IL (一):C# Assembly 与 Reflection
作者:Compasslg 前言 前一阵子想利用闲余时间写一个 Unity 游戏的翻译工具,主要是用于翻译一些内嵌在代码中的文本,最初想偷懒看了一下网上的教学推荐说可以先利用DnSpy.ILSpy等工具 ...
- 【抬杠.NET】如何进行IL代码的开发
背景 在有些时候,由于C#的限制,或是追求更高的性能,我们可以编写IL代码来达到我们的目的.本文将介绍几种IL代码开发的几种方式,环境为visual studio 2019 + net5.0 sdk. ...
- 【计算机基础】IL代码-CLR平台上的字节码【什么是字节码?它与虚拟机的关系?】
字节码(英语:Bytecode)将虚拟机可以读懂的代码称之为字节码.将源码编译成虚拟机读的懂的代码,需要虚拟机转译后才能成为机器代码的中间代码 叫做字节码. 字节码主要为了实现特定软件运行和软件环境. ...
随机推荐
- CodeForces 651B Beautiful Paintings 贪心
A. Joysticks time limit per test 1 second memory limit per test 256 megabytes input standard input o ...
- linux终端下为什么用命令打开软件后,要关闭软件才能继续下一条命令?
用终端打开chromium浏览器(命令:chromium-browser)的时候发现打开浏览器之后无法继续在终端输入命令,只能关闭浏览器或者在终端按下Ctrl+c,此时系统将退出浏览器并可以继续在终端 ...
- json和jsonp的传输方式
jsonp传输会解决跨域的问题 $.ajax({ async: false, /* url: "http://127.0.0.1:8080/2015020601/background/mea ...
- [SAP ABAP开发技术总结]权限对象检查
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- [SAP ABAP开发技术总结]选择屏幕——PARAMETERS
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- [SAP ABAP开发技术总结]字段符号FIELD-SYMBOLS
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- CUBRID学习笔记 18 sql语句的预处理(类似存储过程)
定义预处理 类似sqlserver的存储过程 语法 PREPARE stmt_name FROM preparable_stmt 说明 PREPARE 关键字 stmt_name 预处理语句的名字 ...
- ServiceStack.OrmLite 笔记2 -增
ServiceStack.OrmLite 笔记2 这篇主要介绍 增加 db.Insert(new Employee { Id = 1, Name = "Employee 1" }) ...
- Sbt的使用初步和用sbt插件生成eclipse工程
以前一直是用maven去管理java项目,现在开始写scala项目了但是在scala-ide中去编译scala项目和sbt的区别一直没弄清楚受到文章:http://my.oschina.net/yjw ...
- unity3d中asset store 的资源下载到本地的目录位置
来源:http://blog.csdn.net/fzhlee/article/details/8613688 C:/Users/[当前用户]/AppData/Roaming/Unity/Asset S ...