我们都知道用 ildasm 可以反编译出中间文件来,再用 ilasm 可以再将中间文件编译回 dll 。对于简单的 dll 破解来说, ildasm + ilasm 就是基本工具了。
为了进一步学习IL,本人也小试了一下,并记录下本次 ildasm + ilasm 的过程,也算是初级入门了吧。先准备一个Winform的小程序,程序很简单,一个Label用来显示文字,一个PictureBox用来显示图片。3个图片由Timer控制循环显示。程序如下,编译成 MyApp.exe。
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private int imageIndex = 1; private void timer1_Tick(object sender, EventArgs e) { Assembly asm = Assembly.GetExecutingAssembly(); string pngName = string.Format("MyApp.Images.{0}.png", imageIndex); this.pictureBox1.BackgroundImage = Image.FromStream(asm.GetManifestResourceStream(pngName)); imageIndex++; if (imageIndex > 3) imageIndex = 1; } private void Form1_Load(object sender, EventArgs e) { this.timer1.Enabled = true; } }
运行效果如下:
第一步,我要修改这个Label的内容,把"ildasm before"改为"ildasm after"。
下面详细介绍一下修改过程:
1. 使用 ildasm.exe 反编译生成的程序。
【准备】 ildasm.exe 的位置 --> [系统盘]/Program Files/Microsoft SDKs/Windows/v6.0A/Bin
ildasm.exe 会把指定的 exe 或者 dll 反编译出这个程序或者程序集的 il 文件和所用到的 resource。
2. 用文本编辑器打开 il 文件,直接进行修改。(就是 MyApp.il)
搜寻要修改的关键词: "ildasm before"。 (因为这个DEMO做得很简单,很容易就能找到,有些加上混淆的代码就不容易找到了。
还有些是用Base64加密的版本信息就需要多花点时间了。)
修改这个字符串为"ildasm after",保存。
3. 再用 ilasm.exe 将修改完的 MyApp.il 编译回 exe。
【准备】 ilasm.exe 的位置 --> [系统盘]/WINDOWS/Microsoft.NET/Framework/v2.0.50727
中间有编译过程的信息,最后提示: Operation completed successfully 就OK了。在新的目录下,得到一个新的 MyApp.exe,运行看看:
成功修改了。 (资源的修改也非常简单,只要替换榨出来的资源文件(比如图片等)就可以了。)为了实验 ilmerge 的功能, 笔者又把 MyApp 用到的 3个图片单独放到一个工程中,重新编译成一个 MyAppRes.dll 同时把 MyApp.exe 里资源名修改为 MyAppRes.XXX 重新打回 exe, 最后用 ilmerge 进行合并。
下面继续:
查看 MyApp.il 发现,程序所使用的图片是embeded在exe里的,所以引用图片的代码是这样的:
而存放在 exe 里的图片的定义,在 il 里的 mresource 部分可以看到:
这个 "MyApp" 就是程序的命名空间了。 因为要把图片都“拿”出去,而拿出去的图片的程序集变了(同namespace的exe,dll不能合并,分离出去的namespace不能相同)。所以 MyApp.il 里的使用图片的代码需要修改。
MyApp.Images.{0}.png 改为: MyAppRes.Images.{0}.png (MyAppRes是重新定义的dll的名字,也是图片新的namespace)
新建工程: 从刚才榨取出来的图片直接拷贝到新的工程,并把图片的 Build Action 设置为 embed。最后把不要的引用全部清空。因为这个工程只有图片。
好,编译生成 MyAppRes.dll , 用刚才的 ildasm.exe 打开看看:
这个资源dll准备就OK了。接下来要处理一下 MyApp.il, 首先把原来的资源定义删除。
就是上面的mresource定义,因为图片已经分离出去了。这里不再需要它们了。
.mresource public 'MyApp.Images.1.png'
.mresource public 'MyApp.Images.2.png'
.mresource public 'MyApp.Images.3.png'
再把 MyApp.Images.{0}.png 改为: MyAppRes.Images.{0}.png
按照上面的方式重新编译回 MyApp.exe (命令行同上,这里不再重复)
这里编译完的 MyApp.exe 运行肯定出错,因为图片都已经拿掉了。 MyAppRes命名空间下找不到指定的图片。
4. 用 ilmerge.exe 把之前准备好的 MyAppRes.dll 打到 MyApp.exe 中,让图片有效。
【准备】 ilmerge.exe 的下载地址 当然市面上已经有很多不错的 GUI 工具了,推荐下一个GUI工具进行merge。
比如: Visual ILMerge.exe 感谢 ROOVENT.YANG 提供的好工具。
这个小工具简单易懂,无需介绍。。。合并操作如下图。
为了表示区别,合并后的程序为 MyApp_Merge.exe 。 先用 ildasm.exe 打开看看:
3个图片都已经合并进来了。再运行下程序,OK。程序一切正常。
总结,我们通过 ildasm.exe 可以将编译好的dll或者exe反编译为 il文件,并通过修改 il文件再利用ilasm.exe编译回dll或者exe。同时,利用ilmerge.exe的合并功能,还可以将多个dll,exe进行合并。本文示例中的程序和il都很简单,包括资源文件生成il文件中的定义等都是基本知识。希望通过这次小实验能够打开灵感,寻找 il 中更加高级的知识。