In this post:
1.
Introduction
2.
Lifecycle of .Net application
3.
PE – Portable Executable
4.
Assembly/PE file – Metadata
5.
DEMO – inspect MSIL code, modified it, and reassemble
Introduction
In
this post I'll simply demonstrate how to use the following tools to inspect Microsoft
Intermediate Language – MSIL of our programs:
1. ILDASM – IL Disassembler
2. ILASM –
IL Assembler (IL Roundtripping)
We
could use these disassemblers (de-compilers) tools to observe .Net Assemblies (*.dll,
*.exe) MSIL code, or to review the language code (C# & VB).
They
are part of the Visual Studio and the .Net framework SDK:
E:\Program
Files\Microsoft Visual Studio 14.0>where ildasm
C:\Program
Files\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\ildasm.exe
E:\Program
Files\Microsoft Visual Studio 14.0>where ilasm
C:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe
|
Remark: Additional Disassemblers
There
are of course additional de-compiler tools, such as: .Net
Reflector, ILSpy, dotPeek etc., but for this post I'll only demonstrate the
ILDASM & ILASM tools.
Lifecycle of .Net application
When
we compile our C# code, using a C# compiler (MSBuild/CSC), we are actually
creating an assembly, also considered as PE – Portable Executable file.
The
assembly is a DLL or EXE file, which contains our code in MSIL
& relevant Metadata.
The
MSIL code is not executable; it's only an intermediate language. The CLR
(Common Language Runtime) compiles the assembly at runtime, using the JIT
(Just-in-time) complier, into native\machine code, and then execute it on
the target machine.
Prior
to demonstrating the use of ILDASM & ILASM (to review MSIL code), I'd like
to cover few additional topics:
PE – Portable Executable
A
PE file is a file format (data structure) that contains relevant
information necessary for 32\64-bit Windows OS, when executing this file.
The
PE file contains the MSIL code & relevant Metadata in binary
form.
The
extensions of a PE file are: DLL, EXE.
The
PE format was taken and modified from the Unix COFF (Common Object File
Format), and is also known as PE/COFF in Windows OS.
Remark: PE Analysis
Tools (dumpbin.exe)
There
are several PE Analysis tools we could use to inspect the PE File information.
For
this post, I'll present the dumpbin.exe command line tool, which could
be found under: C:\Program Files\Microsoft Visual Studio 12.0\VC\bin.
C:\Program
Files\Microsoft Visual Studio 12.0\VC\bin>where dumpbin.exe
C:\Program
Files\Microsoft Visual Studio 12.0\VC\bin\dumpbin.exe
C:\Program
Files\Microsoft Visual Studio 12.0\VC\bin>dumpbin /headers E:\MyCode\
MyName.exe
Microsoft
(R) COFF/PE Dumper Version 12.00.30501.0
Copyright
(C) Microsoft Corporation. All rights
reserved.
Dump
of file E:\MyCode\MyName.exe
PE
signature found
File
Type: EXECUTABLE IMAGE
FILE
HEADER VALUES
14C machine (x86)
2 number of sections
58495B8D time date stamp Thu Dec 08
15:09:33 2016
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
…
|
Assembly/PE file – Metadata
As
stated above the Assembly/PE file (*.exe, *.dll) contains the MSIL code, and
the Metadata.
What
is the metadata?
A
metadata is a set of data describing other data.
The
.Net Assembly metadata describes our code types and members. (The assembly
content)
There
are 2 types of metadata:
1. Assembly Manifest –
the metadata of the assembly:
-
Name, Version, Culture, Public Key.
-
External assemblies that this assembly uses.
-
Etc.
2. Type metadata
-
Name, visibility, base class, interfaces implemented.
-
Members: properties, fields, methods, constants.
-
Etc.
Demo - planning
In
the following demo we'll perform the following:
1. We'll created
a simple *.cs file and compiled it to *.exe using the C# compiler (csc.exe) in
the Visual Studio - Developer Command Prompt.
2. We'll inspect
the MSIL content of the *.exe file using the ILDASM tool.
3. We'll emit the
MSIL of the *.exe to a text file, using the ILDASM tool.
4. We'll modify
the IL file in notepad.
5. We'll
recompile the modified IL file, using the ILASM tool (IL round-tripping).
Demo:
1. Create a simple class:
I've
written the following code in notepad, and created a *.cs file: MyName.cs.
2. Save the file:
I've
saved the file in: E:\MyCode
3. Developer Command Prompt:
-
I've opened the Developer Command Prompt for VS2015
(from the Visual Studio Tools folder).
-
I compiled the code using the C# compiler (csc.exe).
-
And reviewed the new MyName.exe file.
E:\MyCode>csc
MyName.cs
Microsoft
(R) Visual C# Compiler version 1.1.0.51204
Copyright
(C) Microsoft Corporation. All rights reserved.
E:\MyCode>dir
/b
MyName.cs
MyName.exe
E:\MyCode>
|
4. Execute the compiled file:
E:\MyCode>MyName.exe
Hello,
my name is: Yonatan
E:\MyCode>
|
5. Open the ILDASM tool:
Now I've opened the
ILDASM tool, to review the IL file:
E:\MyCode>ildasm
MyName.exe
E:\MyCode>
|
-
Once typing the command above, the ILDASM tool is
opened with the relevant assembly, in this case the MyName.exe.
6. Explore the assembly IL:
Now we
could explore the assembly content and relevant information, such as:
-
Manifest
-
Classes
-
Methods
-
Etc.
-
The assembly's Manifest:
-
Program.Main() method:
7. Review the MSIL code:
In the output we could
review the MSIL code, e.g. loading a string:
IL_0001:
ldstr "Hello, my name
is: Yonatan"
8. Modify the IL Code:
Now,
let's modify the IL code and later recompile it again:
-
First, I'll emit the IL into a text file, using the
ILDASM tool.
E:\MyCode>ildasm
/out=MyName.il MyName.exe
E:\MyCode>dir
/b
MyName.cs
MyName.exe
MyName.il
MyName.res
|
-
We could review the new IL file:
E:\MyCode>type
MyName.il
// Microsoft (R) .NET Framework IL
Disassembler. Version 4.6.1055.0
// Copyright (c) Microsoft Corporation. All rights reserved.
// Metadata
version: v4.0.30319
.assembly extern
mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89
) // .z
..
.ver 4:0:0:0
}
.assembly MyName
{
.custom instance void
[mscorlib]System.Runtime.CompilerServices.Compilatio
axationsAttribute::.ctor(int32)
= ( 01 00 08 00 00 00 00 00 )
.custom instance void
[mscorlib]System.Runtime.CompilerServices.RuntimeCom
bilityAttribute::.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.
…
|
-
We could open the MyName.il file in notepad, and
modify it, for example: I'll change the output string in the
Console.WriteLine() method:
E:\MyCode>notepad
MyName.il
|
9. Recompile the modified IL Code, using ILASM tool:
-
This operation is called: IL Roundtripping
E:\MyCode>ilasm
/exe MyName.il
Microsoft (R) .NET Framework IL
Assembler. Version 4.6.1055.0
Copyright (c) Microsoft
Corporation. All rights reserved.
Assembling 'MyName.il' to EXE --> 'MyName.exe'
Source file is ANSI
Assembled method
DisassemblersExample.Program::Main
Assembled method
DisassemblersExample.Program::.ctor
Creating PE file
Emitting classes:
Class 1: DisassemblersExample.Program
Emitting fields and methods:
Global
Class 1 Methods: 2;
Emitting events and properties:
Global
Class 1
Writing PE file
Operation completed successfully
E:\MyCode>
|
10. Execute the new MyName.exe file:
E:\MyCode>MyName.exe
Hello, my new name is: YoniFed
E:\MyCode>
|
The End
Hope you enjoyed!
Appreciate your comments…
Yonatan Fedaeli