CIL和ILDASM
(2008-10-07 16:27:24)
标签:
it |
分类: 程序开发 |
前面说过,C#编译器将C#代码转换成CIL代码,而不是处理器能够理解的机器码。给定一个程序集(DLL文件或可执行文件),则可以使用一个CIL反汇编实用程序将程序集析构成对应的CIL表示,从而查看它的CIL代码(通常使用Microsoft特有的文件名ILDASM来称呼CIL反汇编程序,ILDASM是IL Disassembler的简称)。该程序能对一个程序或者它的类库执行反汇编处理,显示由C#编译器生成的CIL代码。
在不同的CLI实现中,使用CIL反汇编程序的命令也有所区别。可以像输出1-8展示的那样,在命令行中执行.NET CIL反汇编程序:
输出1-8
>ildasm /text HelloWorld.exe
使用/text选项的目的是让输出在命令控制台上显示,而不是在一个新窗口中显示。类似地,Mono反汇编程序实现默认在命令控制台上显示,如输出1-9所示。
输出1-9
>monodis HelloWorld.exe
执行上述命令得到的输出流是包含在HelloWorld.exe程序中的CIL代码的一个转储(dump)。注意,CIL代码要比机器码容易理解得多。许多开发者会因此而担心,因为这样的程序更容易被反编译,而且无需拿到源码,别人即可理解程序所采用的算法。
任何程序,不管是不是基于CLI的,防止反编译的唯一安全的方法就是禁止用户访问编译好的程序(例如,只在一个网站上存放程序,而不是把它分发到用户机器上)。然而,假如你的目的只是减小别人获得源代码的可能性,那么可以考虑使用一些混淆器(obfuscator)产品。这些混淆器能防止别人随便就访问到代码。它创建的程序集经过了特殊处理,很难被反编译成容易理解的代码。除非一个程序需要对算法进行高级的安全保护,否则混淆器就足够了。
高级主题:HelloWorld.exe的CIL输出 代码清单1-18展示了ILDASM创建的CIL代码。 代码清单1-18 示例CIL输出 // Metadata version: v2.0.50727 .assembly extern mscorlib { } .assembly HelloWorld { [mscorlib]System.Runtime.CompilerServices.CompilationRelaxations Attribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAt tribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
程序最开头是清单(manifest)信息。其中不仅包括被反编译的模块的全名(HelloWorld.exe),还包括它依赖的所有模块和程序集及其版本信息。 基于这样的一个CIL代码清单,最有趣的事可能就是我们能相对比较轻松地理解程序所做的事情,这可比阅读并理解机器码(程序集)容易多了。在上述代码中,出现了对System.Console. WriteLine()的一个显式引用。 在CIL代码清单中,包含许多暂时没有什么用处的外围信息。但是,如果开发者想要理解C#模块(或者任何基于CLI的程序)的内部工作原理,但又无法拿到作者的源码,那么除非作者使用了一个混淆器,否则像这样的CIL代码清单理解起来是相对比较容易的。事实上,有一些免费工具(比如Lutz Roeder的.NET Reflector),可以将CIL自动反编译成C#。 |