Annotated Dump of a Tiny PE File


The file nano.exe is an attempt to generate the smallest possible CLI executable using Microsoft's tools. This was done by Arch Robison, of Intel Corporation, and a member of the ECMA technical committee working on this standard. Following is the CIL assembly source:

 
 .assembly donothing {} .method static public void main() cil managed { .entrypoint   .maxstack 0   ret } 

The resulting nano.exe file was 2,048 bytes long when assembled with the .NET 1.0 ilasm. That's not quite the smallest size allowed by the ECMA specification. Indeed, the .NET 1.1 beta version generates 1,536 bytes.

The descriptions that follow are in order of ascending offset within the file. The intent is to explain the reason for every byte in the file. This exercise uncovered multiple errors in the first edition of the ECMA specification, which were then corrected.

MS-DOS Header

The MS-DOS header matches that in the ECMA specification, with the lfanew field set to "0x80 00 00 00".

PE File Header

The PE signature is at offset 0x80, with the ECMA-documented value of "PE\0\0".

The PE file header is at offset 0x84, with the values shown in Table 4-1.

Table 4-1. PR File Header

File Offset

RVA

Field

Contents

0x84

0x84

Machine

0x14C

0x86

0x86

Number of Sections

2

0x88

0x88

Time/Date Stamp

0x3C18B9D8

0x8C

0x8C

Pointer to Symbol Table

0

0x90

0x90

Number of Symbols

0

0x94

0x94

Optional Header Size

0xE0

0x96

0x96

Characteristics

0x10E

The PE header standard fields have the values shown in Table 4-2.

Table 4-2. Standard Fields in the PE Header

File Offset

RVA

Field

Contents

0x98

0x98

Magic

0x10B

0x9A

0x9A

LMajor

6

0x9B

0x9B

LMinor

0

0x9C

0x9C

Code Size

0x400

0xA0

0xA0

Initialized Data Size

0x200

0xA4

0xA4

Uninitialized Data Size

0

0xA8

0xA8

Entry Point RVA

0x21FE

0xAC

0xAC

Base Of Code

0x2000

0xB0

0xB0

Base Of Data

0x4000

The PE header Windows NT specific fields have the values shown in Table 4-3.

Table 4-3. Windows NT-Specific Fields in the PE Header

File Offset

RVA

Field

Contents

0xB4

0xB4

Image Base

0x400000

0xB8

0xB8

Section Alignment

0x2000

0xBC

0xBC

File Alignment

0x200

0xC0

0xC0

OS Major

4

0xC2

0xC2

OS Minor

0

0xC4

0xC4

User Major

0

0xC6

0xC6

User Minor

0

0xC8

0xC8

SubSys Major

4

0xCA

0xCA

SubSys Minor

0

0xCC

0xCC

Reserved

0

0xD0

0xD0

Image Size

0x6000

0xD4

0xD4

Header Size

0x200

0xD8

0xD8

File Checksum

0

0xDC

0xDC

SubSystem

0x3 (...CE_GUI)

0xDE

0xDE

DLL Flags

0

0xE0

0xE0

Stack Reserve Size

0x100000

0xE4

0xE4

Stack Commit Size

0x1000

0xE8

0xE8

Heap Reserve Size

0x100000

0xEC

0xEC

Heap Commit Size

0x1000

0xF0

0xF0

Loader Flags

0

0xF4

0xF4

Number of Data Directories

0x10

The PE header data directories are shown in Table 4-4.

Table 4-4. PE Header Data Directories

File Offset

RVA

Field

Contents

0xF8

0xF8

Export Table

0

0x100

0x100

Import Table

RVA=0x21A8 Size=0x53

0x108

0x108

Resource Table

0

0x110

0x110

Exception Table

0

0x118

0x118

Certificate Table

0

0x120

0x120

Base Relocation Table

RVA=0x4000 Size=0xC

0x128

0x128

Debug

0

0x130

0x130

Copyright

0

0x138

0x138

Global Ptr

0

0x140

0x140

TLS Table

0

0x148

0x148

Load Config Table

0

0x150

0x150

Bound Import

0

0x158

0x158

IAT

RVA=0x2000 Size=8

0x160

0x160

Delay Import Descriptor

0

0x168

0x168

CLI Header

RVA=0x2008 Size=0x48

0x170

0x170

Reserved

0

PE Section Headers

The section table contains two sections. The first part is shown in Table 4-5; the second, in Table 4-6.

Table 4-5. PE Section Headers: Part 1

File Offset

RVA

Field

Contents

0x178

0x178

Name

".text"

0x180

0x180

VirtualSize

0x204

0x184

0x184

VirtualAddress

0x2000

0x188

0x188

SizeOfRawData

0x400

0x18A

0x18A

PointerToRawData

0x200

0x18E

0x18E

PointerToRelocations

0

0x192

0x192

PointerToLinenumbers

0

0x196

0x196

NumberOfRelocations

0

0x198

0x198

NumerOfLinenumbers

0

0x19A

0x19A

Characteristics

0x60020 (...CODE, ...EXECUTE, ...READ)

Table 4-6. PE Section Headers: Part 2

File Offset

RVA

Field

Contents

0x1A0

0x1A0

Name

".reloc"

0x1A8

0x1A8

VirtualSize

0xC

0x1AC

0x1AC

VirtualAddress

0x4000

0x1B0

0x1B0

SizeOfRawData

0x200

0x1B4

0x1B4

PointerToRawData

0x600

0x1B8

0x1B8

PointerToRelocations

0

0x1BC

0x1BC

PointerToLinenumbers

0

0x1C0

0x1C0

NumberOfRelocations

0

0x1C2

0x1C2

NumerOfLinenumbers

0

0x1C4

0x1C4

Characteristics

0x42000040 (...INITIALIZED_DATA, ?, ...READ)

The section header tables are followed by zero-fill all the way up to and including offset 0x1FF.

Import Address Table

From file offset 0x200 to 0x400 is the .text section. It starts with the Import Address Table (Table 4-7) at 0x200. Note that the beginning RVA for this section is 0x2000, as specified by the VirtualAddress field of the .text section (at file offset 0x184) in the the section table (see Table 4-5).

Table 4-7. Import Address Table

File Offset

RVA

Field

Contents

0x200

0x2000

Hint/Name Table RVA

0x21E0

0x204

0x2004

(Zero-fill for two bytes)

0

0x206

0x2006

2 zeros for sake of alignment

0

CLI Header

The CLI header (Table 4-8) immediately follows at 0x208 (which agrees with the corresponding entry in the data directory):

Table 4-8. CLI Header

File Offset

RVA

Field

Contents

0x208

0x2008

Cb

0x48

0x20C

0x200C

MajorRuntimeVersion

2

0x20E

0x200E

MinorRuntimeVersion

0

0x210

0x2010

MetaData

0x2060

0x214

0x2014

Size of the Metadata

0x148 =(RVA of Import Table) (RVA of MetaData)

0x218

0x2018

Flags

1

0x218

0x201C

EntryPointToken

0x06000001 (Method #1 in TypeDef table)

0x220

0x2020

Resources

0

0x228

0x2028

StrongNameSignature

0

0x230

0x2030

CodeManagerTable

0

0x238

0x2038

VTableFixups

0

0x240

0x2040

ExportAddressTableJumps

0

0x248

0x2048

ManagedNativeHeader

0

Method Header and CIL

Immediately following the CLI header is a fat method header (Table 4-9) and CIL instructions:

Table 4-9. Method Header

File Offset

RVA

Field

Contents

0x250

0x2050

Flags (lower 12 bits)

0x013 ...Fat, ...InitLocals

+12 bits

 

Size (upper 4 bits)

0x3

0x252

0x2052

MaxStack

0

0x254

0x2054

CodeSize

0x1

0x258

0x2058

LocalVarSigTok

0

0x25C

0x205C

CIL "ret" instruction

0x2A

0x25D

0x205D

Zero fill for sake of alignment

0

Metadata Root

Next comes the metadata root (Table 4-10).

Table 4-10. Metadata Root

File Offset

RVA

Field

Contents

0x260

0x2060

Signature

0x424A5342

0x264

0x2064

MajorVersion

1

0x266

0x2066

MinorVersion

1

0x268

0x2068

Reserved

0

0x26C

0x206C

Length (of version string)

0xC

0x270

0x2070

Version

"1.0.2914"

0x27C

0x207C

Flags

0

0x27D

0x207D

Streams

4

Metadata Stream Headers

The four stream headers (see Table 4-11) immediately follow.

Table 4-11. Metadata Stream Headers

File Offset

RVA

Field

Contents

0x280

0x2080

Offset

0x60

0x284

0x2084

Size

0x68

0x286

0x2086

Name

"#~\0\0"

File Offset

RVA

Field

Contents

0x28C

0x208C

Offset

0xC8

0x290

0x2090

Size

0x68

0x294

0x2094

Name

"#Strings\0\0\0\0"

File Offset

RVA

Field

Contents

0x2A0

0x20A0

Offset

0x130

0x2A4

0x20A4

Size

0x10

0x2A8

0x20A8

Name

"#GUID\0\0\0"

File Offset

RVA

Field

Contents

0x2B0

0x20B0

Offset

0x140

0x2B4

0x20B4

Size

0x8

0x2B8

0x20B8

Name

"#Blob"

The #~ Stream

The data for the #~ stream (Table 4-12) immediately follows.

Table 4-12. The #~ Stream

File Offset

RVA

Field

Contents

0x2C0

20C0

Reserved

0

0x2C4

20C4

MajorVersion

1

0x2C5

20C5

MinorVersion

0

0x2C6

20C6

HeapSizes

0 (all heap indices are 16 bits wide)

0x2C7

20C7

Reserved

1

0x2C8

20C8

Valid

0x100000045 (Assembly, Method, TypeDef, Module)

0x2D0

20D0

Sorted

0x2003301FA00

0x2D8

20D8

Rows [Module]

1

0x2DC

20DC

Rows [TypeDef]

1

0x2E0

20E0

Rows [Method]

1

0x2E4

20E4

Rows [Assembly]

1

The Module table (Table 4-13) immediately follows.

Table 4-13. Module Table

File Offset

RVA

Field

Contents

0x2E8

20E8

Generation

0

0x2EA

20EA

Name

0x4D

0x2EC

20EC

Mvid

1

0x2EE

20EE

EncId

0

0x2F0

20F0

EncBaseId

0

The TypeDef table (Table 4-14) immediately follows.

Table 4-14. TypeDef Table

File Offset

RVA

Field

Contents

0x2F2

0x20F2

Flags

0

0x2F4

0x20F4

Name

0x44

0x2F6

0x20F6

Namespace

0

0x2F8

0x20F8

Extends

0

0x2FA

0x20FA

FieldList

1

0x2FC

0x20FC

MethodList

1

The Method table (Table 4-15) immediately follows.

Table 4-15. Method Table

File Offset

RVA

Field

Contents

0x300

0x2100

RVA

0x2050

0x304

0x2104

ImpFlags

0x44

0x306

0x2106

Flags

0x0016

0x308

0x2108

Name

0x60

0x30A

0x210A

Signature

1

+12

0210C

ParamList

1

The Assembly table (Table 4-16) immediately follows.

Table 4-16. Assembly Table

File Offset

RVA

Field

Contents

0x30E

0x210E

HashAlgId

0

0x312

0x2112

MajorVersion

0

0x314

0x2114

MinorVersion

0

0x316

0x2116

BuildNumber

0

0x318

0x2118

RevisionNumber

0

0x31A

0x211A

Flags

0

0x31E

0x211E

PublicKey

0

0x320

0x2120

Name

0x56 (index of string "donothing")

0x322

0x2122

Culture

0

String Heap

The String heap (Table 4-17) follows.

Table 4-17. String Heap

File Offset

RVA

String

0x328

0x2128

"\0"

0x329

0x2129

"Version of runtime against which the binary is built : 1.0.2914.16\0"

0x36C

0x216C

"<Module>"

0x375

0x2175

"nano.exe"

0x37E

0x217E

"donothing"

0x388

0x2188

"main"

0x38D

0x218D

0 fill for 3 bytes

Guid Heap

Next comes the Guid heap (Table 4-18).

Table 4-18. Guid Heap

File Offset

RVA

GUID

0x390

0x2190

0xE22D90FB 0x446C1C25 0x5D9D0B95 0x4D6C243E

Blob Heap

Immediately afterward is the Blob heap (Table 4-19).

Table 4-19. Blob Heap

File Offset

RVA

Blob

0x3A0

0x21A0

{}

0x3A1

0x21A1

{0,0,1}

0x3A5

0x21A5

0 fill for 3 bytes

At this point we are at the end of the metadata.

Import Table

We have reached the Import Table (Partition II, section 24.3.1) pointed to by the data directory. The Import Table's contents are as shown in Table 4-20.

Table 4-20. Import Table

File Offset

RVA

Field

Contents

0x3A8

0x21A8

ImportLookupTable

0x21D0

0x3A8

0x21AC

DateTimeStamp

0

0x3B0

0x21B0

ForwarderChain

0

0x3B4

0x21B4

Name

0x21EE

0x3B8

0x21B8

ImportAddressTable

0x2000

0x3BC

0x21BC

Filled with twenty zeros

 

Immedately following is the Import Lookup Table (Table 4-21).

Table 4-21. Import Lookup Table

File Offset

RVA

Field

Contents

0x3D0

0x21D0

Hint/Name Table RVA

0x21E0

0x3D4

0x21D4

Filled with two zeros

0

0x3DA

0x21DA

Undocumented

Ten zeros not documented in II.24.3.1

Following the Import Lookup Table is the Hint/Name table (Table 4-22) and some miscellanea.

Table 4-22. Hint/Name Table

File Offset

RVA

Field

Contents

0x3E0

0x21E0

Hint

0x21E0

0x3E2

0x21E2

Name

"_CorExeMain\0"

0x3EE

0x21EE

 

"mscoree.dll\0"

0x3FA

0x21FA

4 undocumented zero bytes

 

0x3FE

0x21FE

Entry point per II.24.2.3.1

0xFF 0x25

0x400

0x2200

RVA that must follow

0x402000

Relocation Section

The rest of the file is zeros until we reach offset 0x600, which is the raw data for the relocation section (.reloc) (see Table 4-23).

Table 4-23. Raw Data for Relocation

File Offset

RVA

Field

Contents

0x600

0x4000

RVA for page

0x2000

0x604

0x4004

Size of this structure

0xC

0x608

0x4008

Relocation

0x3200 IMAGE_REL_BASED_HIGHLOW at 0x200

0x60A

0x400A

Placeholder

0

This is a request for the loader to add a fix-up delta to the RVA following the "0xFF 0x25" stub.

The rest of the file is zeros, up to the last offset of 0x7FF.



The Common Language Infrastructure Annotated Standard (Microsoft. NET Development Series)
The Common Language Infrastructure Annotated Standard (Microsoft. NET Development Series)
ISBN: N/A
EAN: N/A
Year: 2002
Pages: 121

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net