在项目开发过程当中,估计也有人和我遇到过一样的经历:生产环境出现了重大Bug亟需解决,而恰恰就在这时仓库中的代码却不是最新的。在这种状况下,咱们不能直接在当前的代码中修改这个Bug而后发布,这会致使更严重的问题,由于至关于版本回退了。即便咱们眼睁睁的看着这个Bug两行代码就能搞定,在咱们的代码没更新到最新版本以前,都不敢轻举妄动。可是客户的呼声让人抵挡不住,客户声称的分分钟多少多少的经济损失咱们也承受不起。这时若是你是作PHP开发的,你会庆幸,由于你能够直接去生产环境修复掉这个Bug让客户先闭嘴而后再慢慢折腾你那出问题的代码管理工具;而若是你作是.Net抑或C/C++开发的,就没这么轻松了。面对服务器上拷下来的有着重大Bug的dll或exe,你很难直接去修改它里面的代码逻辑,只能利用一些逆向的技巧和工具了。 php
因为我这里是.Net的环境,因此我决定在这篇博客里介绍下如何利用逆向工具来修改生产上的.Net程序集。可是就在我决定写这篇博客的时候我忽然发现,其实,若是你只是单纯的修改一个.Net程序集中的某个方法或功能,并且这个程序集仍是出自于你本身或你所在团队之手,这实在是一件很是容易的事情,这和破解别人的程序彻底不一样,你不会遇到没法破解的加密算法,也不会遇到让人恶心的加壳混淆。利用搜索引擎能够搜到大量这样的教学文章,因此我改变了下主意,决定不在这篇博客中重复造轮子,而是把已有的轮子一个个的列出来总结一下。 html
这篇博客主要汇总一些.Net反编译相关的工具。 node
ilasm 和 ildasm 都是微软官方提供的.Net编译与反编译工具,可谓是.Net逆向中的瑞士军刀。这两个工具的位置分别位于.Net Framework目录和Microsoft SDK目录中: git
C:\Windows\Microsoft.NET\Framework\v2.0.50727\ilasm.exe
程序员
C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\ildasm.exe
github
这里有一篇文章详细介绍了如何经过ilasm 和 ildasm 修改.Net程序,归结起来就下面几个步骤: 算法
使用工具ildasm打开要逆向的.Net程序,并另存为IL文件;
ildasm程序有命令行和图形界面两种运行模式,通常状况下双击ildasm便可启动图形界面的主程序,而后经过菜单项 File -> Dump ,选择UTF-8编码,便可导出到IL文件中。若是是以命令行模式运行的话,能够打开Visual Studio自带的开发环境命令行工具(Developer Command Prompt for VS2012),这样能够不用关心ildasm所处的目录,直接运行下面的命令:ildasm test.exe /out:test.il
若是程序含资源文件的话,除了生成一个IL文件,可能还会有其余的*.res文件等。编程
打开IL文件阅读IL源码并定位到须要修改的代码处,对IL代码进行修改;
使用ilasm 和 ildasm 反编译.Net程序须要了解一点MSIL的语法,这样不管阅读仍是修改IL文件都要方便的多,好在MSIL的语法并非很复杂,花一天的时间研究下仍是值得的。这里有一篇不错的MSIL教程。
若是真的对MSIL不熟悉不会编写MSIL的话,其实也没有大碍,只要你会大概的看懂MSIL源码和会编写C#程序也能够。能够参考这篇文章,具体的方法是:用C#编写你须要修改的方法,而后编译成exe/dll文件,再经过ildasm反编译成IL文件,从这个IL文件中复制出须要的IL源码覆盖掉以前那个须要修改的IL文件中的相关代码,这样你就算不会MSIL,也能修改IL文件了,确实有点偷梁换柱的味道。c#
使用ilasm将IL文件从新编译成.Net程序。
最后,使用ilasm程序从新编译IL文件:ilasm test.il /output:test-mod.exe
,再使用PEVerify执行校验确保文件无误:PEVerify test-mod.exe
。若是一切顺利的话,将test-mod.exe替换掉老的test.exe便可。
默认状况下,ilasm将生成exe文件,若是须要生成dll文件,可使用下面的命令:ilasm test.il /dll /output:test-mod.dll
,若是须要集成资源,则须要指定/resource参数:ilasm test.il /resource:test.res /output:test-mod.exe
服务器
虽然说ilasm 和 ildasm是.Net逆向中的瑞士军刀,可是一提起.Net逆向,其实不少人第一反应都是Reflector这款神器,而对微软提供的这两个官方工具知之甚少。这一方面是因为Reflector良好的用户体验和强大的插件功能,另外一方面要归功于Reflector堪称完美的智能反编译能力,使用它不只能看到反编译后的IL源码甚至能直接反编译出C#源码,并且和编写时的代码几无二致,若是须要还能够直接另存为工程文件用Visual Studio打开。
Reflector是RedGate开发的.Net逆向工具,单纯的Reflector程序只有反编译功能,能够查看IL或C#源码,以及导出源码。并不能修改.Net程序。幸亏咱们有sailro编写的Reflexil插件,Reflexil基于Mono.Cecil,是一个强大的程序集编辑器。Reflector + Reflexil 可谓是强强联合,和 ilasm + ildasm 这个组合比起来简直是大巫见小巫。
若是是第一次加载Reflexil插件,打开Reflector,在 Tools -> Add-Ins -> Add -> 选择Reflexil.dll,之后就能够直接在Reflector的Tools菜单中打开了。用Reflector打开test.exe,选择某个函数能够发现IL代码显示在下方的Reflexil窗口中,能够点击右键Edit,Delete,Create等操做。还能够修改类或方法的访问权限等,好比将private改为public。
另外,在编辑IL的操做中还有一个Replace all with code
选项,经过这个能够直接用C#代码来对程序进行修改,无需你熟悉MSIL语法,相似于上一节介绍的“偷梁换柱”的方法,只不过集成在Reflexil中让咱们的操做更方便了。以下图所示:
Reflexil的做者在codeproject上写了一长篇Reflexil的各类实用技巧,能够去这里看看。Reflexil惟一的缺憾是并无和Reflector无缝结合,使用Reflexil修改完IL源码或类的属性后,上面Reflector中显示的IL或C#源码并无当即更新,必须保存修改后使用Reflector从新打开才能看到所作的修改。这多少有点让人感受不爽,但比起 ilasm + ildasm 这种纯手工逆向工具来说已经好太多了。
还有一点要说明的是:.Net Reflector很早就转向收费软件了,并且价格不菲,普通版95刀每用户,专业版甚至要199刀。对于咱们大多数开发人员来讲逆向并非咱们的平常工做,可能只是偶尔好奇而为之,这样为了偶尔的好奇而须要支付这么多的money实在是让人有点舍不得。因而一部分人走上了破解和盗版的路,而另外一部分人走上了开源的路。这也是下一节将要介绍的ILSpy工具的由来。
ILSpy 是为了彻底替代收费的Reflector而生,它是由 iCSharpCode 团队出品,这个团队开发了著名的 SharpDevelop 。ILSpy 彻底开源,目前还处于开发阶段,不少功能还不够完善,可是具备强大的反编译功能对于咱们来讲已经足够了。对于ILSpy的使用和上面的Reflector彻底相似,此处再也不赘述。
在我写这篇博客的时候,ILSpy最新的发布版本为3/9/2015 Version 2.3
,尚未和Reflexil具备相似功能的代码修改插件。可是在ILSpy的Further Down the Road能够看到,这样的功能也已经在计划之中了。
虽然官方的发布版本尚未提供Reflexil的功能,可是Reflexil的做者sailro很早就在项目描述中介绍了对ILSpy的支持:
Reflexil is an assembly editor and runs as a plug-in for Red Gate's Reflector, ILSpy and Telerik's JustDecompile. Reflexil is using Mono.Cecil, written by Jb Evain and is able to manipulate IL code and save the modified assemblies to disk. Reflexil also supports C#/VB.NET code injection.
得益于ILSpy和Reflexil都是开源的,咱们从GitHub上把最新的代码Clone下来并进行编译,Reflexil\Plugins\Reflexil.ILSpy
这个目录下是Reflexil插件的源码,咱们将编译后的全部dll文件拷贝到ILSpy的bin目录,运行ILSpy就能在View选项中看到Reflexil了,以下图:
关于ILSpy和Reflexil的操做和上面介绍的Reflector几乎同样,不过有一点很让人振奋,ILSpy提供了更新对象模型的功能,这样Reflexil插件就能够在修改完代码后直接更新ILSpy的代码了,而不用像Reflector那样须要从新加载才能看到所作的修改。以下图所示,点击“Update ILSpy object model”,上面ILSpy的代码会当即更新:
相信很多人都听过 Telerik 公司,该公司很是关注于.Net平台下的控件研发,而且发布了不少著名的开发工具,例如:Fiddler 和 JustDecompile。JustDecompile 正是 Telerik 的一款.Net反编译工具,和ILSpy不一样的是,它并非彻底开源的,可是它有着商业化的技术支持,这一点很是可贵。不只如此,Telerik 也开源了JustDecompile的引擎部分:JustDecompile Engine,这也是很是不错的。
JustDecompile在使用上和其余的反编译工具差很少,并且它也具备插件系统,官方目前提供了三个插件,以下:
其中Assembly Editor正是Reflexil。从菜单Plugins中调出Reflexil,enjoy it!
JetBrains是捷克的一家软件开发公司,出品了大量著名的开发工具,包括:IntelliJ IDEA、PHPStorm、ReSharper、TeamCity、YouTrack等等,每一款产品都如雷贯耳。dotPeek 是 JetBrains 开发的一款.Net反编译工具,是.Net工具套件中的一个,其余的还有dotTrace、dotCover 和 dotMemory。相比于前面几款工具来讲,dotPeek算比较小众的一款。我的感受它最大的特点就是Visual Studio风格,这对于那些长期在Visual Studio下进行开发的人来讲应该更亲切一点。
不过dotPeek目前好像尚未相似于Reflexil这样的编辑插件,自己也并无编辑功能。若是咱们须要修改程序集的话,能够另存为工程文件,使用Visual Studio打开直接修改源码从新编译。
实际上,利用上面介绍的这些工具已经彻底可以知足你的需求了。可是咱们老是有更多选择(等有时间的时候再玩这些吧):
另外,本文中的一些工具能够在此下载。
这篇博客的主要目的原本只是在无源码的状况下修改.Net程序集,但到这里已经彻底演变成了.Net反编译工具的罗列清单。Never mind,关于.Net程序集的修改,上面最耀眼的非Reflexil莫属。而Reflexil依赖于Jb Evain所写的Mono.Cecil,Cecil 是一个对于Mono项目具备战略意义的函数库。它为不少项目(包括:Mono Debugger、Gendarme 和 MoMA 等)提供了内部处理的能力,并且 Cecil 也能操做编译好的CIL,并把修改后的程序集保存到磁盘里。
做为一个.Net程序员,修改.Net程序集最终极的方法莫过于本身动手写出修改程序集的代码,利用Mono.Cecil能够轻松实现这个目的。暂且给本身挖个坑,之后填上吧。
【转自】http://www.aneasystone.com/archives/2015/06/net-reverse-decompiling.html