• Aucun résultat trouvé

File Format

Dans le document Wikibooks.org X86Disassembly (Page 47-52)

The PE portable executable file format includes a number of informational headers, and is arranged in the following format:

Figure 3

The basic format of a Microsoft PE file

5.5.1 MS-DOS header

Open any Win32 binary executable in a hex editor, and note what you see: The first 2 letters arealways the letters "MZ". To some people, the first few bytes in a file that determine the type of file are called the "magic number," although this book will not use that term, because there is no rule that states that the "magic number" needs to be a single number.

Instead, we will use the term "File ID Tag", or simply, File ID. Sometimes this is also known as File Signature.

After the File ID, the hex editor will show several bytes of either random-looking symbols, or whitespace, before the human-readable string "This program cannot be run in DOS mode".

What is this?

Figure 4

Hex Listing of an MS-DOS file header

What you are looking at is the MS-DOS header of the Win32 PE file. To ensure either a) backwards compatibility, or b) graceful decline of new file types, Microsoft has engineered a series of DOS instructions into the head of each PE file. When a 32-bit Windows file is run in a 16-bit DOS environment, the program will terminate immediately with the error message: "This program cannot be run in DOS mode".

The DOS header is also known by some as the EXE header. Here is the DOS header presented as a C data structure:

struct DOS_Header {

char signature[2] = "MZ";

short lastsize;

short nblocks;

short nreloc;

short hdrsize;

short minalloc;

short maxalloc;

void *ss;

void *sp;

short checksum;

void *ip;

void *cs;

short relocpos;

short noverlay;

short reserved1[4];

short oem_id;

short oem_info;

short reserved2[10];

long e_lfanew;

}

File Format Immediately following the DOS Header will be the classic error message "This program cannot be run in DOS mode".

5.5.2 PE Header

At offset 60 from the beginning of the DOS header is a pointer to the Portable Executable (PE) File header (e_lfanew in MZ structure). DOS will print the error message and terminate,

but Windows will follow this pointer to the next batch of information.

Figure 5

Hex Listing of a PE signature, and the pointer to it

The PE header consists only of a File ID signature, with the value "PE\0\0" where each '\0' character is an ASCII NUL character. This signature shows that a) this file is a legitimate PE file, and b) the byte order of the file. Byte order will not be considered in this chapter, and all PE files are assumed to be in "little endian" format.

The first big chunk of information lies in the COFF header, directly after the PE signature.

5.5.3 COFF Header

The COFF header is present in both COFF object files (before they are linked) and in PE files where it is known as the "File header". The COFF header has some information that is useful to an executable, and some information that is more useful to an object file.

Here is the COFF header, presented as a C data structure:

struct COFFHeader {

short Machine;

short NumberOfSections;

long TimeDateStamp;

long PointerToSymbolTable;

long NumberOfSymbols;

short SizeOfOptionalHeader;

short Characteristics;

}

Machine

This field determines what machine the file was compiled for. A hex value of 0x14C (332 in decimal) is the code for an Intel 80386.

NumberOfSections

The number of sections that are described at the end of the PE headers.

TimeDateStamp

32 bit time at which this header was generated: is used in the process of "Binding", see below.

SizeOfOptionalHeader

this field shows how long the "PE Optional Header" is that follows the COFF header.

Characteristics

This is a field of bit flags, that show some characteristics of the file.

• 0x02 = Executable file

• 0x200 = file is non-relocatable (addresses are absolute, not RVA).

• 0x2000 = File is a DLL Library, not an EXE.

5.5.4 PE Optional Header

The "PE Optional Header" is not "optional" per se, because it is required in Executable files, but not in COFF object files. The Optional header includes lots and lots of information that can be used to pick apart the file structure, and obtain some useful information about it.

The PE Optional Header occurs directly after the COFF header, and some sources even show the two headers as being part of the same structure. This wikibook separates them out for convenience.

Here is the PE Optional Header presented as a C data structure:

struct PEOptHeader {

short signature; //decimal number 267.

char MajorLinkerVersion;

char MinorLinkerVersion;

long SizeOfCode;

long SizeOfInitializedData;

long SizeOfUninitializedData;

long AddressOfEntryPoint; //The RVA of the code entry point long BaseOfCode;

long BaseOfData;

long ImageBase;

long SectionAlignment;

long FileAlignment;

short MajorOSVersion;

short MinorOSVersion;

short MajorImageVersion;

short MinorImageVersion;

short MajorSubsystemVersion;

short MinorSubsystemVersion;

long Reserved;

long SizeOfImage;

long SizeOfHeaders;

File Format

long Checksum;

short Subsystem;

short DLLCharacteristics;

long SizeOfStackReserve;

long SizeOfStackCommit;

long SizeOfHeapReserve;

long SizeOfHeapCommit;

long LoaderFlags;

long NumberOfRvaAndSizes;

data_directory DataDirectory[16]; //Can have any number of elements, matching the number in NumberOfRvaAndSizes.

} //However, it is always 16

in PE files.

struct data_directory {

long VirtualAddress;

long Size;

}

Some of the important pieces of information:

MajorLinkerVersion, MinorLinkerVersion

The version, in x.y format of the linker used to create the PE.

AddressOfEntryPoint

The RVA of the entry point to the executable. Very important to know.

SizeOfCode

Size of the .text (.code) section SizeOfInitializedData

Size of .data section BaseOfCode

RVA of the .text section BaseOfData

RVA of .data section ImageBase

Preferred location in memory for the module to be based at Checksum

Checksum of the file, only used to verify validity of modules being loaded into kernel space.

The formula used to calculate PE file checksums is proprietary, although Microsoft provides API calls that can calculate the checksum for you.

Subsystem

the Windows subsystem that will be invoked to run the executable

• 1 = native

• 2 = Windows/GUI

• 3 = Windows non-GUI

• 5 = OS/2

• 7 = POSIX DataDirectory

Possibly the most interesting member of this structure. Provides RVAs and sizes which locate various data structures, which are used for setting up the execution environment of a module. The details of what these structures do exist in other sections of this page, but the most interesting entries in DataDirectory are below:

• IMAGE_DIRECTORY_ENTRY_EXPORT (0) : Location of the export directory

• IMAGE_DIRECTORY_ENTRY_IMPORT (1) : Location of the import directory

• IMAGE_DIRECTORY_ENTRY_RESOURCE (2) : Location of the resource directory

• IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (11) : Location of alternate import-binding directory

Dans le document Wikibooks.org X86Disassembly (Page 47-52)