Common Intermediate Language and ILDASM

Common Intermediate Language and ILDASM

As mentioned earlier, the C# compiler converts C# code to CIL code and not to machine code that the processor can understand. Given an assembly (either a DLL or an executable), it is possible to view the CIL code using a CIL disassembler utility to deconstruct the assembly into its CIL representation. (The CIL disassembler is commonly referred to by its Microsoft-specific filename, ILDASM, which stands for IL Disassembler.) This program will disassemble a program or its class libraries, displaying the CIL generated by the C# compiler.

The exact command used for the CIL disassembler depends on which implementation of the CLI is used. You can execute the .NET CIL disassembler from the command line as shown in Output 1.8.

Output 1.8.

>ildasm /text HelloWorld.exe

The /text portion is used so that the output appears on the command console rather than in a new window. Similarly, the Mono disassembler implementation, which defaults to the command console, is shown in Output 1.9.

Output 1.9.

 >monodis HelloWorld.exe

The stream of output that results by executing these commands is a dump of CIL code included in the HelloWorld.exe program. Note that CIL code is significantly easier to understand than machine code. For many developers, this may raise a concern because it is easier for programs to be decompiled and algorithms understood without explicitly redistributing the source code.

As with any program, CLI based or not, the only foolproof way of preventing disassembly is to disallow access to the compiled program altogether (for example, only hosting a program on a web site instead of distributing it out to a user's machine). However, if decreased accessibility to the source code is all that is required, there are several obfuscators. These obfuscators prevent the casual developer from accessing the code and instead create assemblies that are much more difficult and tedious to decompile into comprehensible code. Unless a program requires a high degree of algorithm security, these obfuscators are generally sufficient.

Advanced Topic: CIL Output for HelloWorld.exe

Listing 1.18 shows the CIL code created by ILDASM.

Listing 1.18. Sample CIL Output

// Metadata version: v2.0.50727 .assembly extern mscorlib {   .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..   .ver 2:0:0:0 } .assembly HelloWorld {   .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxations Attribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )   .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAt tribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E     45 78 // ....T..WrapNonEx 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.   .hash algorithm 0x00008004   .ver 0:0:0:0   }   .module HelloWorld.exe   // MVID: {49C96993-E12B-4DD2-A127-34909F7C9A15}   .imagebase 0x00400000   .file alignment 0x00000200   .stackreserve 0x00100000   .subsystem 0x0003         // WINDOWS_CUI   .corflags 0x00000001      //  ILONLY   // Image base: 0x02EA0000   .class private auto ansi beforefieldinit HelloWorld          extends [mscorlib]System.Object   {     .method private hidebysig static void Main() cil managed     {       .entrypoint       // Code size      13 (0xd)       .maxstack 8       IL_0000: nop       IL_0001: ldstr    "Hello. My name is Inigo Montoya."       IL_0006: call     void   [mscorlib]System.Console::WriteLine(string)       IL_000b: nop       IL_000c: ret     } // end of method HelloWorld::Main     .method public hidebysig specialname rtspecialname             instance void .ctor() cil managed     {       // Code size      7 (0x7)       .maxstack 8       IL_0000: ldarg.0       IL_0001: call     instance void  [mscorlib]System.Object::.ctor()      IL_0006: ret    } // end of method HelloWorld::.ctor  } // end of class HelloWorld

The beginning of the listing is the manifest information. It includes not only the full name of the disassembled module (HelloWorld.exe), but also all the modules and assemblies it depends on, along with their version information.

Perhaps the most interesting thing that can be gleaned from such a listing is how relatively easy it is to follow what the program is doing compared to trying to read and understand machine code (assembler). In the listing, an explicit reference to System.Console.WriteLine() appears. There is a lot of peripheral information to the CIL code listing, but if a developer wanted to understand the inner workings of a C# module (or any CLI-based program) without having access to the original source code, it would be relatively easy unless an obfuscator is used. In fact, several free tools are available (such as Lutz Roeder's Reflector for .NET) that can decompile from CIL to C# automatically.

Essential C# 2.0
Essential C# 2.0
ISBN: 0321150775
EAN: 2147483647
Year: 2007
Pages: 185 © 2008-2017.
If you may any questions please contact us: