一起谈.NET技术,如何通过ildasm/ilasm修改assembly的IL代码

  这段时间为跟踪一个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不需要)

  感谢阅读,仅供参考
  周银辉 

  【相关文章】

  通过学习反编译和修改IL,阅读高人的代码,提高自身的水平

时间: 2024-10-10 06:23:30

一起谈.NET技术,如何通过ildasm/ilasm修改assembly的IL代码的相关文章

如何通过ildas“.NET技术”m/ilasm修改assembly的IL代码

这段时间为跟踪一个Bug而焦头烂额,最后发现是Framework的问题,这让人多少有些绝望.所以到微软论坛提了个帖子,希望能得到些帮助.虽然论坛智能到能够判断楼主是否是MSDN订阅用户,以便尽快解决(传说MSDN订阅用户的问题能在两天内得到回复的,当时还很得意公司为我们购买的MSDN订阅账号),但得到的回复是"Could you file a bug report for this issue through Connect?",绝望之后的又一次寒心啊. 看过payeasy的广告之后,

用ildasm/ilasm修改IL代码(操作步骤)

在开发中遇到这样一个场景,需要修改一个dll文件(.NET程序集)中某些地方的类型名称,但没有源代码,只能修改IL代码. 操作步骤如下: 1. 运行ildasm ildasm是由微软提供的.NET程序反编译工具,位于"C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\". 2. 用ildasm打开要修改的程序集,如下图: 3. 通过ildasm保存为IL文件 选择菜单File>Dump,选择UTF-8编码,如下图: 4. 用文本编

如何通过ildasm/ilasm修改assem“.NET研究”bly的IL代码

这段时间为跟踪一个Bug而焦头烂额,最后发现是Framework的问题,这让人多少有些绝望.所以到微软论坛提了个帖子,希望能得到些帮助.虽然论坛智能到能够判断楼主是否是MSDN订阅用户,以便尽快解决(传说MSDN订阅用户的问题能在两天内得到回复的,当时还很得意公司为我们购买的MSDN订阅账号),但得到的回复是"Could you file a bug report for this issue through Connect?",绝望之后的又一次寒心啊. 看过payeasy的广告之后,

《创业家》牛文文:少谈点模式多谈点技术

"模式"如同当年的"主义",流行于各种创业大赛.创业励志节目.论坛的"街头"式秀场 文/创业家 牛文文 "美国某某公司你知道吧?就是刚被戴尔.惠普.思科十几亿美元抢购的那家.我们的模式和它的一样,现在还没赢利,可将来起码有十几亿人民币的市值." "我开了小煤矿,但煤运不出去,上商学院之后受到启发,想搞模式创新,具体讲就是想在铁路边上搞个煤炭物流开发区,建一个大的物流和信息流平台,把分散的煤炭集中在我这个园区,这样和铁

一起谈.NET技术,《Effective C#中文版:改善C#程序的50种方法》读书笔记

从去年找工作以来,都没什么时间写博客[找工作的体会:建议以后有自己开公司的IT人一定要找IT专业人员做HR,好多公司的HR并不能真正发掘人才,他们形成了太多的偏见,如在学校期间学不了什么东西.只看学校有多少奖励等.真正钻研技术的人才不会追求虚无的东西],其实这本书我都借了好久,一直没有系统的看,所以趁这两天好好看看,顺便总结了一些要点,给那些需要这方面知识而又没有太多时间的IT人一个快速的学习机会....如果要深入学习,请购买该书. 一.用属性代替可访问的字段 1..NET数据绑定只支持数据绑定

一起谈.NET技术,大话Session

引言     在web开发中,session是个非常重要的概念.在许多动态网站的开发者看来,session就是一个变量,而且其表现像个黑洞,他只需要将东西在合适的时机放进这个洞里,等需要的时候再把东西取出来.这是开发者对session最直观的感受,但是黑洞里的景象或者说session内部到底是怎么工作的呢?当笔者向身边的一些同事或朋友问及相关的更进一步的细节时,很多人往往要么含糊其辞要么主观臆断,所谓知其然而不知其所以然. 笔者由此想到很多开发者,包括我自己,每每都是纠缠于框架甚至二次开发平台之

一起谈.NET技术,验证.NET强命称的思路和实例

手头有一个行业软件,是需要插上加密狗才能正常运行的,C# / .Net Framework 1.1环境开发的.这是我们公司购买的正版软件,所以是能正常使用的,但是由于电脑多,加密狗难免要拔来拔去的.闲来无事,就研究研究吧,也好多学些调试知识.PEiD可以"鉴定"出该软件是Microsoft Visual C# / Basic .NET,新手不要以为脱壳查壳才用到PEiD啊. 那就用Reflector分析吧,注意到不插加密狗会弹出个对话框提示"*****未注册*****&quo

一起谈.NET技术,应用Visual Studio 2010辅助敏捷测试(上)

敏捷软件开发是近些年来比较热门的话题,<敏捷宣言>四条主要精神和十二条基本准则概括了敏捷开发的基本思想.围绕着这些基本概念和思想,产生了一系列的轻量级方法,如:极限编程.测试驱动开发.Scrum.特性驱动开发等.虽然具体名称.过程和侧重点不尽相同,但是相对于非敏捷的开发方法而言,它们都更强调面对面的沟通.团队不同角色之间的紧密协作.频繁交付新的可用的软件版本.紧凑而自我组织型的团队等.敏捷开发只是提供了一个思想和方法论,而要在实际的工程中正确运用它,并真正显现出它的优点和产生实际的效果,这对于

一起谈.NET技术,VS2010 测试功能之旅:编码的UI测试(4)-通过编写测试代码的方式建立UI测试(下)

回顾 最近比较忙,距离上次更新的时间较久,见谅. 在本章上部分,介绍了"添加用户"窗口的测试代码编写.想必大家也看到了,在UIMap.cs文件中实现自定义编码是一件很轻松的事情,接下来将介绍下个部分,查询用户窗体的测试代码的编写,以及他们测试的关联. 示例程序介绍 系统主窗口:(下载点我) 该系统拥有两个功能,"添加用户"和"查询用户": 点击添加用户后,进入添加用户子窗体:("添加用户"窗口的测试代码编写在上部分已经实现)