Portable executable format

Description of this format used in .NET development.


.NET Developer Tip
(Receive this column in your inbox,
click Edit your Profile to subscribe.)

Portable executable format
Kevin Burton

It is always necessary when you're developing a program, to understand the structure of the code you're going to generate. This tip, which is excerpted from an article on InformIT, discusses the Portable executable format generated in a .NET assembly.

Much of this tip, and its parent article, comes from .NET Common Language Runtime Unleashed, published by SAMs.


When you compile a JAVA program, you typically get a .class file that in turn is run using the java.exe, which loads your program into the JVM, and starts it running. When you compile a program in .NET, you get an assembly. If it is a library, you will get a .DLL file. If it is an executable, you will get an .EXE file. To run a .NET program, Microsoft has taken the extra step to incorporate a .NET assembly into a standard Windows PE file. For example, take the simple Hello World program, shown in Listing 1:

Listing 1—C# Hello World

using System;
class Hello 
{
  public static void Main()
  {
    System.Console.WriteLine("Hello world!");
  }
}

Compiling this program with 'csc HelloWorld.cs' generates a HelloWorld.exe. This file is a .NET assembly, but it is also a standard PE file.

There have been numerous articles written about the PE file format. Two of my favorites are both by Matt Pietrek. He first wrote about the PE file format in March of 1994: "Peering Inside the PE: A Tour of the Win32 Portable Executable File Format." Then, he updated the pedump.exe utility in his article that began in the February 2002 edition of MSDN Magazine: "Inside Windows: An In-Depth Look into the Win32 Portable Executable File Format."

You can view the contents of an assembly as a PE file using Matt Peitrek's PEDump utility, or you can use the the dumpbin utility that has been shipping with every development environment for some time now. Dumpbin is more readily available, but using the PEDump utility, you have the advantage of source along with Matt Pietrek's discussion of PE file format. With VC7, dumpbin is in Program FilesMicrosoft Visual Studio .Netvc7bin. You can easily set up your environment to follow along with the rest of this article by executing Program FilesMicrosoft Visual Studio .NetCommon7ToolsVSVARS32.bat. Running 'dumpbin /ALL HelloWorld.exe' generates something like the output shown in Listing 2.

Listing 2—Dumpbin Output

Dump of file HelloWorld.exe

PE signature found

File Type: EXECUTABLE IMAGE

FILE HEADER VALUES
. . .

OPTIONAL HEADER VALUES
. . .
      22DE entry point (004022DE)

 clr Header:

       48 cb
      2.00 runtime version
      207C [   214] RVA [size] of MetaData Directory
        1 flags
     6000001 entry point token
. . .

 Section contains the following imports:

  mscoree.dll
        402000 Import Address Table
        4022B8 Import Name Table
           0 time date stamp
           0 Index of first forwarder reference

          0 _CorExeMain

In order to save space, the listing has been truncated considerably to include only the portions of the file that pertain to .NET. Starting at the end of the listing first, the imports make sure that the mscoree.dll is loaded into the process. This is the standard way of allowing a PE file to specify which DLLs it depends on. For .NET assemblies, there is only one dependency: mscoree.dll. If you remove or rename mscoree.dll, you will receive the standard DLL cannot be found error. Looking at the OPTIONAL HEADER VALUES section, there is one entry in particular that is interesting -- the entry point. For this file, the entry point is 22DE, or if the load does not have any conflicts, the address translates to 04022DE. Looking at that address in the dumpbin output:

 004022C0: 00 00 5F 43 6F 72 45 78 65 4D 61 69 6E 00 6D 73 .._CorExeMain.ms
 004022D0: 63 6F 72 65 65 2E 64 6C 6C 00 00 00 3B 00 FF 25 coree.dll...;.ÿ%
 004022E0: 00 20 40 00                   . @.

At address 04022DE, there is the following set of bytes: FF 25 00 20 40 00. These bytes roughly translate into a jump indirect 00402000. So the only code so far is a hook that starts the code running in the CLR. Now when the CLR starts to run, it examines the CLR Header section, loads the metadata and then starts running at the token specified as entry point token. Once decoded, the CLR can determine from the tables where the entry point token is and start a managed execution at that point. In this case, the token is 0x06000001, which corresponds to the first entry of table #6, which is the MethodDef table that corresponds to Main.


Read more of this article at InformIT. Registration is required, but it's free.

For More Information:

  • Looking for free research? Browse our comprehensive White Papers section by topic, author or keyword.
  • Are you tired of technospeak? The Web Services Advisor column uses plain talk without the hype.
  • For insightful opinion and commentary from today's industry leaders, read our Guest Commentary columns.
  • Hey Codeheads! Start benefiting from other time-saving XML Developer Tips and .NET Developer Tips.
  • Visit our huge Best Web Links for Web Services collection for the freshest editor-selected resources.
  • Choking on the alphabet soup of industry acronyms? Visit our helpful Glossary for the latest lingo.
  • Visit Ask the Experts for answers to your Web services, SOAP, WSDL, XML, .NET, Java and EAI questions.
  • Discuss this issue, voice your opinion or just talk with your peers in the SearchWebServices Discussion Forums.

This was first published in December 2002

Dig deeper on VB code downloads

0 comments

Oldest 

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to:

SearchCloudComputing

SearchSoftwareQuality

SearchSOA

TheServerSide

SearchCloudApplications

Close