stuff to click

Know your program: introduction to PE/COFF

difficulty 2 comments 1 added Mar 11, 2011 category system

I decided to write a series of articles which deal with topics that are slightly beyond interests of entry level programmer, but are essential for moving ahead. It would be overview giving general idea of how your programs actually work from operational system perspective. Therefore I named this series "Know your program ...".

Today's subject is the format of Windows executable file. Windows as dominating desktop OS has an enormous army of software developers including myself. But the product of compilation and linking for many programmers is a black box. I would admit that it is a bit tangled, but not to the extent that would repulse us from enjoying its disassembling. To start with let's consider the basics.

Basics

The way executable is loaded and the very format of it may tell a lot about operational system. For example, MS-DOS .COM format which contained code and data in one 64K memory segment was good for systems that operated with little memory available. It didn't contain any headers and was loaded to a fixed address. When time passed and size of memory available for software increased, other formats were introduced, which allowed to place code and data in different memory regions and load executable file at different locations.

More advanced formats divide file into sections, so that when the file is loaded, sections are loaded into split up memory regions. Dissecting the executable file helped managing its parts and reduced safety issues, because operational system could set specific access permissions for different memory regions. It is quite reasonable, for example, to revoke write access from code section or forbid execution of instructions located in data sections.

The most important high-level sections are code and data sections. Since we are speaking about Microsoft's standard, let's cling to the their naming convention:

  • code section .text
  • data sections .data
  • read-only data section .rdata

The designation of code section is quite clear, but probably it is worth stopping at data sections to look what kind of data they contain.

Section .data is read-write area containing global and static variables, while automatic variables are allocated on stack at runtime. As you remember, uninitialized global variables are automatically initialized with zeros. Such region with uninitialized global variables was historically called .bss section, which when allocated was fully zeroed. But Microsoft linker despite disabled optimization may merge .bss section with .data. So both initialized and uninitialized global variables may go to the .data section. That was the case with the program I used for demo, the only reason for this may be saving in image size.

Section .rdata is read-only memory region, it keeps, for example, string literals which you use in your program or global constant arrays. If you think that other global constant variables also go to this section, you may be wrong. Constant variables of built-in types most likely will be subject for direct substitution, while user defined classes or structures which you make global and constant will go together with uninitialized global variables. And violation of their constancy is guarded by compiler at compile time, while trying to overwrite string literal in .rdata is a run-time error generated by memory page protection mechanism. As an illustration to what was said look at the following snippet with global variables and comments where they could be found:

 
// this is global scope!
int a=1; //goes to .data 
int b;	//goes to .data (should go to .bss)
const int c=0x00ff00ff;	//is not allocated, substituted by value  
 
const int constArray[] = {1,2,3,4,5,6,7,8,9}; //goes to .rdata
int mutableArray[] = {0xa, 0xb, 0xc, 0xd, 0xe, 0xf}; //goes to .data 
int uninitArray[10]; //goes to .data (should go to .bss)
 
char str1[]= "Hello read-write world!"; //string literal is not allocated, array goes to .data
char *str2 = "Hello read-only world!"; //string literal goes to .rdata, pointer goes to .data
 
SomeClass t;		//goes to .data (should go to .bss)
const SomeClass ct; //goes to .data (should go to .bss)
 

If you declared some global variables and don't use them in your code, most probably you won't find them in data sections, it depends on linker's optimization settings.

In addition to read-only data defined by user and startup code .rdata section contains a number of special sections and data structures defined by Microsoft such as import and export data. Some of these data structures will be discussed later.

Beside sections another important concept is relocations. Generally relocation means overwriting some address in the code with another value, by which we achieve "relocating" referenced object. When for example you want to pass some variable to your function, address of that variable is used (if passing by value, address is required to read and copy the value, if passing by reference the address itself is passed). As I mentioned contemporary operational system may load an executable at address that may differ from one set by linker. In that case all absolute address references in the code must be rewritten with the fixed values which take into account the difference between default and actual loading addresses. This is called "base relocation" and we will stop at this a bit later.

Brief history

One of the first executable formats that supported sections and relocations was "a.out". It was actively used in Unix systems in the era of PDP machines and some time later. It got its name after the default name of file that would be produced by a linker. After some time a.out was replaced with COFF format which made possible to support a variable number of sections and name them. This was big step ahead, it allowed to use shared libraries. But still there were limitations which caused different system vendors to "expand" the COFF standard. In Windows world such an extension became PE/COFF format introduced by Microsoft with Windows NT 3.1, where PE stands for "Portable Executable".

For Microsoft it was important milestone, it was cheap extendable solution that met the requirements of changing world. After DOS .COM, MZ executable and NE formats, old and tested in UNIX environment COFF was adopted to Windows. Later it was extended to support 64-bit platforms, this modification was named PE+ or PE32+. Since we have been using this format over 15 years, we can say it wasn't a bad choice.

Some details

First let's look at an executable file layout. The COFF format is respectively simple: in the beginning there is some header area which tells the OS loader what and where is located in the file. This header area contains three headers: COFF header, Optional Header and Section Table. Header area is followed by sections data.

Microsoft slightly changed layout and placed in the very beginning small DOS program which displays the message "This program cannot be run in DOS mode" (if run in DOS, of course). Another place that was significantly extended was Optional header, where specific windows fields were appended as well as Data Directories Table:

General layout of PE/COFF file
General layout of PE/COFF file

Lower is a brief headers overview where I intentionally don't go to distractive details such as offset and sizes. Some of this information is provided in demo section and you can also find full specification and more detailed descriptions by links in Reference section.

COFF header

This header is the most general. It doesn't contain much useful for programmer information, but it contains two important for us values:

  • size of the following header
  • size of Sections table (more exact number of sections).

See demo section for more details.

Optional header

It consists of three areas:

Standard fields

Mostly these header contains generalized information about code and data section. The most interesting fields are:

  • magic number (tells what we have: PE or PE+)
  • size of code sections
  • size of data sections
  • base of code
  • base of data (not present in PE32+)
  • entry point

Since PE file may contain a number of data sections, the section size fields contain the sum of all sections of corresponding type (code or data). This information generalize data that we can get from Section Table. See demo section for more details.

Windows-specific fields

This header is much more interesting, it has 21 fields, but one third of them are version numbers. Among others I would draw your attention to the following fields:

  • image base
  • size of image (when loaded)
  • size of headers
  • subsystem (as native, GUI, console and others including XBOX!)
  • stack sizes (commit and reserve)
  • heap sizes (commit and reserve)
  • number of directories (effective size of next header)

Here you find a whole bunch of fields that you can affect with linker options such as:

  • /SUBSYSTEM
  • /BASE
  • /HEAP
  • /STACK

Data directories

Data directories is a simple array of 8-byte structures:

struct
{
DWORD VirtualAddress;
DWORD Size;
};

Each record corresponds to some data structure defined by Microsoft. They have different formats and meanings but are essential for Windows loader and their order in the array is predefined. For example, zero index is directory for export section, next is import section, then follows resource section and so on. The format of each entry is described in PE/COFF specification. Normally the size of directories header is 16 entries. You can see the order of directories in the demo.

Section table

Section table is native COFF header and it is an array of more complex (than data directory) structures which describes the high-level sections. I use word high-level because these sections are "accessible" from section table (native COFF high-level header) and some of them may contain other special sections and data tables defined by Microsoft and referenced by directories. For example, .rdata may contain export, import, debug and other section. Some special sections (managed by directories header) may be also referenced in COFF section table (i.e. be high-level), for example, .reloc and .rsrc.

Typical section layout
Typical section layout

To discuss sections we need first consider how the image file is loaded into the process memory space. The virtual address at which the image mapping starts is called image base. But this mapping is not direct. After mapping headers area, "file sections" are mapped separately to memory regions, and as was mentioned special access permissions may be set for those regions. Real sections usually have different size (it may be greater or less) and are split up.

Because image base may be different, it is convenient to address objects by RVA (relative virtual address) which is there offset from the base. At the illustration below you can see "real scale" image mapping, some RVAs are also shown. It is clearly shown that sections are split into memory regions which are at 1K distance from each other and the size of loaded image is more than three times greater than the file size. The file used for the example is dumped below in the demo part of the article.

Mapping sections onto process virtual memory (real scaling)
Mapping sections onto process virtual memory (real scaling)

Now let's return to the section table. As it was said, it is an array of the structures, each of which corresponds with a section. The most important for us fields of the structures are:

  • section name
  • RVA (offset from the base when loaded)
  • size when loaded
  • pointer within file (to raw data)
  • size in the file (of raw data)
  • characteristics

Having the knowledge of offsets and sizes we easily can locate sections in the file and in the process memory. The characteristics field contains flags specifying the section properties. For executable files these properties tell what kind of data is contained in the section: code, initialized data, uninitialized data; what access rights are set for the section : read, write, execute; here also go some special attributes defining if the section can be shared, cached or paged.

I'd like also mention that beside regular sections provided by compiler and linker, you can define in your program your own sections. It can be done with help of DEF file or with #pragma directives. Microsoft compiler supports the following directives for working with sections: section, bss_seq, code_seq, const_seq, data_seq. Here is an example of how they could be used:

 
//specifying sections with predefined attributes:
#pragma bss_seg(".myBss")
int i;                         // stored in "myBss"
#pragma bss_seg()                //restoring section
int j;                         // stored in ".bss"
 
void func1(){}                 // stored in .text
 
#pragma code_seg(".myText")
void func2() { }               // stored in "myText"
 
const char str1[]= "str1";     // stored in .rdata
 
#pragma const_seg(".myRdata")
const char str2[]= "str2";     // stored in .myRdata
 
#pragma data_seg(".myData")
int k = 1;                     // stored in "myData"
#pragma data_seg()               //restoring ".data"
 
//specifying custom set of attributes: creating shared section
 
#pragma section("shared",read,write,shared)
 
__declspec(allocate("shared")) // affects only the following declaration
int l = 0;                     // stored in "shared"
int m = 1;                     // stored in ".data"
 

Reasons for creating additional sections may be different. In my practice I used custom sections for sharing data among processes originated from one image and it looked like very effective solution.

This ends the headers overview, but the specification contains a number of special sections and structures that are important for programmers. Among them there are import, export and tls sections; sections used in object files also deserve some attention. But in this article I'm going to make a little stop at relocations.

Relocations

Let's look how relocations work.

Suppose we have the following code:

 
int a=1; //goes to .data 
int b;	//goes to .data (should go to .bss)
 
int sum(int a, int b) {return a+b;}
int main(int argc, char** argv)
{
	b=2;
	a=sum(a,b);
        return 0;
}
 

let's disassemble the sum() function call:

 
0x40107D: A1CC334000             MOV         EAX, [0x4033CC] 
0x401082: 50                     PUSH        EAX             ;pushing b   
0x401083: 8B0D18304000           MOV         ECX, [0x403018]
0x401089: 51                     PUSH        ECX             ;pushing a
0x40108A: E8B1FFFFFF             CALL        0x401040        ;calling sum() 
0x40108F: 83C408                 ADD         ESP,0x8  
 

this excerpt of .text section contains 3 address references: addresses of variables a and b which are absolute, and address of sum() which is relative because E8 CALL uses offset from next instruction. Relative address doesn't require relocation because it doesn't depend on image base.

As we see, linker calculated absolute addresses assuming that image base is 0x400000:
&a = base +RVA(a) = 0x400000+0x3018 = 0x403018 //RVA is in .data
&b = base +RVA(b) = 0x400000+0x33cc = 0x4033cc //RVA ss in .data uninitialized region

You can look at the last picture (section mapping) to see that the RVAs belong to .data section (as was expected). Now assume that somehow image is loaded not to the 0x400000. This can happen if executable is loaded as dll (it's quite possible, why not?). Since default base is already occupied by image of the host program, OS loader will load our image at another location, say, to the 0x1000000. In this case absolute addresses should be increased by 0x600000, how could this be done? The only way is to remember all address occurrences in a table, relocation table. The relocation section contains all these occurrences, if we decrypt it, we will find the following records:
RVA TYPE
...
0x0000107E, HIGHLOW
0x00001085, HIGHLOW
...
, where RVA is address of occurrence and TYPE is the way how to apply changes to an address. Since the loader knows difference between image base specified by linker and real one, it is easy to go through the relocation tables and apply changes to all addresses referenced there (according to TYPE value).

Relocation tables in PE files are called "base relocation" tables, they are used only if image is loaded to other base than is specified in Optional Header. If loader managed to load image to base specified by linker, the relocation section is completely ignored by loader.

Of course, relocation process slows down image loading and sometimes it could be avoided. Usually you can speed up loading DLL's specifying for them different image bases. If you know that your executable will load some of your DLLs, you can look at Optional Headers of these DLLs, see how big they are when loaded, and map them manually, specifying at linking time appropriate image base for these DLLs. If you don't do this the first DLL will be loaded at address 0x1000000 and all others will go through relocation process.

Hex dump demo

It's time to take a look at a small demo I prepared to illustrate my story. It is marked hex dump of a real file, you can hover the marked blocks to make their description visible (I hope you have JavaScript turned on). In these brief descriptions you can find more details than I provided above and they may serve for quick lookup. The demo fully covers the headers area and section markup, not touching sections' internals. My goal was to give you one look overview of a file, which is hard to get with a reference book aside or using PE browsing programs that use separate windows with data fields for each header.

As a lab rat I used a simple program, parts of which you could see in the article. It contains various global variables, private and exported functions:

#include "stdio.h"
 
class SomeClass
{
public:
	int first;
	char *second;
	SomeClass(): first(0), second("Second\n")
	{
		printf("%s", second);
	}
};
 
int a=1; //goes to .data 
int b;	//goes to .data (should go to .bss)
const int c=0x00ff00ff;	//is not allocated, substituted by value  
 
const int constArray[] = {1,2,3,4,5,6,7,8,9}; //goes to .rdata
int mutableArray[] = {0xa, 0xb, 0xc, 0xd, 0xe, 0xf}; //goes to .data 
int uninitArray[10]; //goes to .data (should go to .bss)
 
char str1[]= "Hello read-write world!"; //string literal is not allocated, array goes to .data
char *str2 = "Hello read-only world!"; //string literal goes to .rdata, pointer goes to .data
 
SomeClass t;		//goes to .data (should go to .bss)
const SomeClass ct; //goes to .data (should go to .bss)
 
 
int sum(int a, int b) {return a+b;}
__declspec(dllexport) void hello() {printf("Hello!\n");}
 
int main(int argc, char** argv)
{
	b=2;
	a=sum(a,b);
	printf("%d\n", c);
	printf("%d\n", constArray[1]);
	printf("%d\n", mutableArray[1]);
	printf("%d\n", uninitArray[1]);
	printf("%s", str1);
	printf("%s", str2);
	printf("%s", t.second);
	printf("%s", ct.second);
	hello();
	return 0;
}

It was build with Microsoft Visual Studio as 32-bit application, I didn't play much with project settings except disabling compiler's optimization. Release version of executable which I got was 7680 bytes. It is quite modest size which allowed me to publish the hex dump in full:

000000
000010
000020
000030
000040
000050
000060
000070
000080
000090
0000a0
0000b0
0000c0
0000d0
0000e0
0000f0
000100
000110
000120
000130
000140
000150
000160
000170
000180
000190
0001a0
0001b0
0001c0
0001d0
0001e0
0001f0
000200
000210
000220
000230
000240
000250
000260
000270
000280
000290
0002a0
0002b0
0002c0
0002d0
0002e0
0002f0
000300
000310
000320
000330
000340
000350
000360
000370
000380
000390
0003a0
0003b0
0003c0
0003d0
0003e0
0003f0
000400
000410
000420
000430
000440
000450
000460
000470
000480
000490
0004a0
0004b0
0004c0
0004d0
0004e0
0004f0
000500
000510
000520
000530
000540
000550
000560
000570
000580
000590
0005a0
0005b0
0005c0
0005d0
0005e0
0005f0
000600
000610
000620
000630
000640
000650
000660
000670
000680
000690
0006a0
0006b0
0006c0
0006d0
0006e0
0006f0
000700
000710
000720
000730
000740
000750
000760
000770
000780
000790
0007a0
0007b0
0007c0
0007d0
0007e0
0007f0
000800
000810
000820
000830
000840
000850
000860
000870
000880
000890
0008a0
0008b0
0008c0
0008d0
0008e0
0008f0
000900
000910
000920
000930
000940
000950
000960
000970
000980
000990
0009a0
0009b0
0009c0
0009d0
0009e0
0009f0
000a00
000a10
000a20
000a30
000a40
000a50
000a60
000a70
000a80
000a90
000aa0
000ab0
000ac0
000ad0
000ae0
000af0
000b00
000b10
000b20
000b30
000b40
000b50
000b60
000b70
000b80
000b90
000ba0
000bb0
000bc0
000bd0
000be0
000bf0
000c00
000c10
000c20
000c30
000c40
000c50
000c60
000c70
000c80
000c90
000ca0
000cb0
000cc0
000cd0
000ce0
000cf0
000d00
000d10
000d20
000d30
000d40
000d50
000d60
000d70
000d80
000d90
000da0
000db0
000dc0
000dd0
000de0
000df0
000e00
000e10
000e20
000e30
000e40
000e50
000e60
000e70
000e80
000e90
000ea0
000eb0
000ec0
000ed0
000ee0
000ef0
000f00
000f10
000f20
000f30
000f40
000f50
000f60
000f70
000f80
000f90
000fa0
000fb0
000fc0
000fd0
000fe0
000ff0
001000
001010
001020
001030
001040
001050
001060
001070
001080
001090
0010a0
0010b0
0010c0
0010d0
0010e0
0010f0
001100
001110
001120
001130
001140
001150
001160
001170
001180
001190
0011a0
0011b0
0011c0
0011d0
0011e0
0011f0
001200
001210
001220
001230
001240
001250
001260
001270
001280
001290
0012a0
0012b0
0012c0
0012d0
0012e0
0012f0
001300
001310
001320
001330
001340
001350
001360
001370
001380
001390
0013a0
0013b0
0013c0
0013d0
0013e0
0013f0
001400
001410
001420
001430
001440
001450
001460
001470
001480
001490
0014a0
0014b0
0014c0
0014d0
0014e0
0014f0
001500
001510
001520
001530
001540
001550
001560
001570
001580
001590
0015a0
0015b0
0015c0
0015d0
0015e0
0015f0
001600
001610
001620
001630
001640
001650
001660
001670
001680
001690
0016a0
0016b0
0016c0
0016d0
0016e0
0016f0
001700
001710
001720
001730
001740
001750
001760
001770
001780
001790
0017a0
0017b0
0017c0
0017d0
0017e0
0017f0
001800
001810
001820
001830
001840
001850
001860
001870
001880
001890
0018a0
0018b0
0018c0
0018d0
0018e0
0018f0
001900
001910
001920
001930
001940
001950
001960
001970
001980
001990
0019a0
0019b0
0019c0
0019d0
0019e0
0019f0
001a00
001a10
001a20
001a30
001a40
001a50
001a60
001a70
001a80
001a90
001aa0
001ab0
001ac0
001ad0
001ae0
001af0
001b00
001b10
001b20
001b30
001b40
001b50
001b60
001b70
001b80
001b90
001ba0
001bb0
001bc0
001bd0
001be0
001bf0
001c00
001c10
001c20
001c30
001c40
001c50
001c60
001c70
001c80
001c90
001ca0
001cb0
001cc0
001cd0
001ce0
001cf0
001d00
001d10
001d20
001d30
001d40
001d50
001d60
001d70
001d80
001d90
001da0
001db0
001dc0
001dd0
001de0
001df0
4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00
b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 e8 00 00 00
0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68
69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f
74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20
6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00
0e de 3e eb 4a bf 50 b8 4a bf 50 b8 4a bf 50 b8
54 ed c3 b8 49 bf 50 b8 54 ed c5 b8 4b bf 50 b8
54 ed d3 b8 5e bf 50 b8 54 ed d4 b8 48 bf 50 b8
6d 79 2b b8 48 bf 50 b8 4a bf 51 b8 62 bf 50 b8
54 ed da b8 4b bf 50 b8 54 ed c2 b8 4b bf 50 b8
54 ed c1 b8 4b bf 50 b8 52 69 63 68 4a bf 50 b8
00 00 00 00 00 00 00 00
50 45 00 00 4c 01 05 00
4f c6 88 4d 00 00 00 00 00 00 00 00 e0 00 02 01
0b 01 09 00 00 0a 00 00 00 10 00 00 00 00 00 00
f3 13 00 00 00 10 00 00 00 20 00 00
00 00 40 00
00 10 00 00 00 02 00 00 05 00 00 00 00 00 00 00
05 00 00 00 00 00 00 00 00 60 00 00 00 04 00 00
c8 f5 00 00 03 00 40 81 00 00 10 00 00 10 00 00
00 00 10 00 00 10 00 00 00 00 00 00 10 00 00 00
40 26 00 00 4e 00 00 00 84 22 00 00 3c 00 00 00
00 40 00 00 b0 02 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 50 00 00 94 01 00 00
d0 20 00 00 1c 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
68 21 00 00 40 00 00 00 00 00 00 00 00 00 00 00
00 20 00 00 a8 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

2e 74 65 78 74 00 00 00 5f 09 00 00 00 10 00 00
00 0a 00 00 00 04 00 00 00 00 00 00 00 00 00 00
00 00 00 00 20 00 00 60
2e 72 64 61 74 61 00 00
8e 06 00 00 00 20 00 00 00 08 00 00 00 0e 00 00
00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 40
2e 64 61 74 61 00 00 00 f8 03 00 00 00 30 00 00
00 02 00 00 00 16 00 00 00 00 00 00 00 00 00 00
00 00 00 00 40 00 00 c0
2e 72 73 72 63 00 00 00
b0 02 00 00 00 40 00 00 00 04 00 00 00 18 00 00
00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 40
2e 72 65 6c 6f 63 00 00 d0 01 00 00 00 50 00 00
00 02 00 00 00 1c 00 00 00 00 00 00 00 00 00 00
00 00 00 00 40 00 00 42
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
55 8b ec 51 89 4d fc 8b 45 fc c7 00 00 00 00 00
8b 4d fc c7 41 04 58 21 40 00 8b 55 fc 8b 42 04
50 68 60 21 40 00 ff 15 a0 20 40 00 83 c4 08 8b
45 fc 8b e5 5d c3 cc cc cc cc cc cc cc cc cc cc
55 8b ec 8b 45 08 03 45 0c 5d c3 cc cc cc cc cc
55 8b ec 68 30 21 40 00 ff 15 a0 20 40 00 83 c4
04 5d c3 cc cc cc cc cc cc cc cc cc cc cc cc cc
55 8b ec c7 05 cc 33 40 00 02 00 00 00 a1 cc 33
40 00 50 8b 0d 18 30 40 00 51 e8 b1 ff ff ff 83
c4 08 a3 18 30 40 00 68 ff 00 ff 00 68 38 21 40
00 ff 15 a0 20 40 00 83 c4 08 8b 15 f8 20 40 00
52 68 3c 21 40 00 ff 15 a0 20 40 00 83 c4 08 a1
20 30 40 00 50 68 40 21 40 00 ff 15 a0 20 40 00
83 c4 08 8b 0d a8 33 40 00 51 68 44 21 40 00 ff
15 a0 20 40 00 83 c4 08 68 34 30 40 00 68 48 21
40 00 ff 15 a0 20 40 00 83 c4 08 8b 15 4c 30 40
00 52 68 4c 21 40 00 ff 15 a0 20 40 00 83 c4 08
a1 d4 33 40 00 50 68 50 21 40 00 ff 15 a0 20 40
00 83 c4 08 8b 0d dc 33 40 00 51 68 54 21 40 00
ff 15 a0 20 40 00 83 c4 08 e8 12 ff ff ff 33 c0
5d c3 3b 0d 00 30 40 00 75 02 f3 c3 e9 ac 02 00
00 68 3c 16 40 00 e8 a4 04 00 00 a1 98 33 40 00
c7 04 24 64 30 40 00 ff 35 94 33 40 00 a3 64 30
40 00 68 54 30 40 00 68 58 30 40 00 68 50 30 40
00 ff 15 94 20 40 00 83 c4 14 a3 60 30 40 00 85
c0 7d 08 6a 08 e8 ba 03 00 00 59 c3 6a 10 68 28
22 40 00 e8 24 06 00 00 33 db 89 5d fc 64 a1 18
00 00 00 8b 70 04 89 5d e4 bf e8 33 40 00 53 56
57 ff 15 24 20 40 00 3b c3 74 19 3b c6 75 08 33
f6 46 89 75 e4 eb 10 68 e8 03 00 00 ff 15 28 20
40 00 eb da 33 f6 46 a1 e4 33 40 00 3b c6 75 0a
6a 1f e8 5d 03 00 00 59 eb 3b a1 e4 33 40 00 85
c0 75 2c 89 35 e4 33 40 00 68 c8 20 40 00 68 bc
20 40 00 e8 ac 05 00 00 59 59 85 c0 74 17 c7 45
fc fe ff ff ff b8 ff 00 00 00 e9 dd 00 00 00 89
35 6c 30 40 00 a1 e4 33 40 00 3b c6 75 1b 68 b8
20 40 00 68 a8 20 40 00 e8 71 05 00 00 59 59 c7
05 e4 33 40 00 02 00 00 00 39 5d e4 75 08 53 57
ff 15 2c 20 40 00 39 1d f4 33 40 00 74 19 68 f4
33 40 00 e8 88 04 00 00 59 85 c0 74 0a 53 6a 02
53 ff 15 f4 33 40 00 a1 54 30 40 00 8b 0d 80 20
40 00 89 01 ff 35 54 30 40 00 ff 35 58 30 40 00
ff 35 50 30 40 00 e8 c5 fd ff ff 83 c4 0c a3 68
30 40 00 39 1d 5c 30 40 00 75 37 50 ff 15 84 20
40 00 8b 45 ec 8b 08 8b 09 89 4d e0 50 51 e8 8f
03 00 00 59 59 c3 8b 65 e8 8b 45 e0 a3 68 30 40
00 33 db 39 1d 5c 30 40 00 75 07 50 ff 15 8c 20
40 00 39 1d 6c 30 40 00 75 06 ff 15 90 20 40 00
c7 45 fc fe ff ff ff a1 68 30 40 00 e8 00 05 00
00 c3 b8 4d 5a 00 00 66 39 05 00 00 40 00 74 04
33 c0 eb 4d a1 3c 00 40 00 8d 80 00 00 40 00 81
38 50 45 00 00 75 e9 0f b7 48 18 81 f9 0b 01 00
00 74 1b 81 f9 0b 02 00 00 75 d5 83 b8 84 00 00
00 0e 76 cc 33 c9 39 88 f8 00 00 00 eb 0e 83 78
74 0e 76 bc 33 c9 39 88 e8 00 00 00 0f 95 c1 8b
c1 6a 01 a3 5c 30 40 00 ff 15 40 20 40 00 6a ff
ff 15 3c 20 40 00 59 59 a3 ec 33 40 00 a3 f0 33
40 00 ff 15 38 20 40 00 8b 0d a0 33 40 00 89 08
ff 15 4c 20 40 00 8b 0d 9c 33 40 00 89 08 a1 6c
20 40 00 8b 00 a3 e0 33 40 00 e8 57 02 00 00 e8
b1 04 00 00 83 3d 14 30 40 00 00 75 0c 68 75 18
40 00 ff 15 70 20 40 00 59 e8 6c 04 00 00 83 3d
10 30 40 00 ff 75 09 6a ff ff 15 74 20 40 00 59
33 c0 c3 e8 80 04 00 00 e9 9f fd ff ff 8b ff 55
8b ec 81 ec 28 03 00 00 a3 78 31 40 00 89 0d 74
31 40 00 89 15 70 31 40 00 89 1d 6c 31 40 00 89
35 68 31 40 00 89 3d 64 31 40 00 66 8c 15 90 31
40 00 66 8c 0d 84 31 40 00 66 8c 1d 60 31 40 00
66 8c 05 5c 31 40 00 66 8c 25 58 31 40 00 66 8c
2d 54 31 40 00 9c 8f 05 88 31 40 00 8b 45 00 a3
7c 31 40 00 8b 45 04 a3 80 31 40 00 8d 45 08 a3
8c 31 40 00 8b 85 e0 fc ff ff c7 05 c8 30 40 00
01 00 01 00 a1 80 31 40 00 a3 7c 30 40 00 c7 05
70 30 40 00 09 04 00 c0 c7 05 74 30 40 00 01 00
00 00 a1 00 30 40 00 89 85 d8 fc ff ff a1 04 30
40 00 89 85 dc fc ff ff ff 15 10 20 40 00 a3 c0
30 40 00 6a 01 e8 44 04 00 00 59 6a 00 ff 15 14
20 40 00 68 ec 20 40 00 ff 15 18 20 40 00 83 3d
c0 30 40 00 00 75 08 6a 01 e8 20 04 00 00 59 68
09 04 00 c0 ff 15 1c 20 40 00 50 ff 15 20 20 40
00 c9 c3 8b ff 55 8b ec 8b 45 08 8b 00 81 38 63
73 6d e0 75 2a 83 78 10 03 75 24 8b 40 14 3d 20
05 93 19 74 15 3d 21 05 93 19 74 0e 3d 22 05 93
19 74 07 3d 00 40 99 01 75 05 e8 d5 03 00 00 33
c0 5d c2 04 00 68 03 15 40 00 ff 15 14 20 40 00
33 c0 c3 cc ff 25 98 20 40 00 6a 14 68 48 22 40
00 e8 66 02 00 00 ff 35 f0 33 40 00 8b 35 5c 20
40 00 ff d6 59 89 45 e4 83 f8 ff 75 0c ff 75 08
ff 15 58 20 40 00 59 eb 67 6a 08 e8 96 03 00 00
59 83 65 fc 00 ff 35 f0 33 40 00 ff d6 89 45 e4
ff 35 ec 33 40 00 ff d6 59 59 89 45 e0 8d 45 e0
50 8d 45 e4 50 ff 75 08 8b 35 3c 20 40 00 ff d6
59 50 e8 59 03 00 00 89 45 dc ff 75 e4 ff d6 a3
f0 33 40 00 ff 75 e0 ff d6 83 c4 14 a3 ec 33 40
00 c7 45 fc fe ff ff ff e8 09 00 00 00 8b 45 dc
e8 1c 02 00 00 c3 6a 08 e8 1d 03 00 00 59 c3 8b
ff 55 8b ec ff 75 08 e8 4e ff ff ff f7 d8 1b c0
f7 d8 59 48 5d c3 8b ff 56 b8 18 22 40 00 be 18
22 40 00 57 8b f8 3b c6 73 0f 8b 07 85 c0 74 02
ff d0 83 c7 04 3b fe 72 f1 5f 5e c3 8b ff 56 b8
20 22 40 00 be 20 22 40 00 57 8b f8 3b c6 73 0f
8b 07 85 c0 74 02 ff d0 83 c7 04 3b fe 72 f1 5f
5e c3 ff 25 88 20 40 00 cc cc cc cc cc cc cc cc
8b ff 55 8b ec 8b 4d 08 b8 4d 5a 00 00 66 39 01
74 04 33 c0 5d c3 8b 41 3c 03 c1 81 38 50 45 00
00 75 ef 33 d2 b9 0b 01 00 00 66 39 48 18 0f 94
c2 8b c2 5d c3 cc cc cc cc cc cc cc cc cc cc cc
8b ff 55 8b ec 8b 45 08 8b 48 3c 03 c8 0f b7 41
14 53 56 0f b7 71 06 33 d2 57 8d 44 08 18 85 f6
76 1b 8b 7d 0c 8b 48 0c 3b f9 72 09 8b 58 08 03
d9 3b fb 72 0a 42 83 c0 28 3b d6 72 e8 33 c0 5f
5e 5b 5d c3 cc cc cc cc cc cc cc cc cc cc cc cc
8b ff 55 8b ec 6a fe 68 68 22 40 00 68 25 18 40
00 64 a1 00 00 00 00 50 83 ec 08 53 56 57 a1 00
30 40 00 31 45 f8 33 c5 50 8d 45 f0 64 a3 00 00
00 00 89 65 e8 c7 45 fc 00 00 00 00 68 00 00 40
00 e8 2a ff ff ff 83 c4 04 85 c0 74 55 8b 45 08
2d 00 00 40 00 50 68 00 00 40 00 e8 50 ff ff ff
83 c4 08 85 c0 74 3b 8b 40 24 c1 e8 1f f7 d0 83
e0 01 c7 45 fc fe ff ff ff 8b 4d f0 64 89 0d 00
00 00 00 59 5f 5e 5b 8b e5 5d c3 8b 45 ec 8b 08
8b 01 33 d2 3d 05 00 00 c0 0f 94 c2 8b c2 c3 8b
65 e8 c7 45 fc fe ff ff ff 33 c0 8b 4d f0 64 89
0d 00 00 00 00 59 5f 5e 5b 8b e5 5d c3 cc ff 25
7c 20 40 00 ff 25 78 20 40 00 cc cc 68 25 18 40
00 64 ff 35 00 00 00 00 8b 44 24 10 89 6c 24 10
8d 6c 24 10 2b e0 53 56 57 a1 00 30 40 00 31 45
fc 33 c5 50 89 65 e8 ff 75 f8 8b 45 fc c7 45 fc
fe ff ff ff 89 45 f8 8d 45 f0 64 a3 00 00 00 00
c3 8b 4d f0 64 89 0d 00 00 00 00 59 5f 5f 5e 5b
8b e5 5d 51 c3 8b ff 55 8b ec ff 75 14 ff 75 10
ff 75 0c ff 75 08 68 42 11 40 00 68 00 30 40 00
e8 e7 00 00 00 83 c4 18 5d c3 8b ff 56 68 00 00
03 00 68 00 00 01 00 33 f6 56 e8 d9 00 00 00 83
c4 0c 85 c0 74 0d 56 56 56 56 56 e8 c2 00 00 00
83 c4 14 5e c3 33 c0 c3 8b ff 55 8b ec 83 ec 10
a1 00 30 40 00 83 65 f8 00 83 65 fc 00 53 57 bf
4e e6 40 bb bb 00 00 ff ff 3b c7 74 0d 85 c3 74
09 f7 d0 a3 04 30 40 00 eb 60 56 8d 45 f8 50 ff
15 30 20 40 00 8b 75 fc 33 75 f8 ff 15 00 20 40
00 33 f0 ff 15 04 20 40 00 33 f0 ff 15 08 20 40
00 33 f0 8d 45 f0 50 ff 15 0c 20 40 00 8b 45 f4
33 45 f0 33 f0 3b f7 75 07 be 4f e6 40 bb eb 0b
85 f3 75 07 8b c6 c1 e0 10 0b f0 89 35 00 30 40
00 f7 d6 89 35 04 30 40 00 5e 5f 5b c9 c3 ff 25
44 20 40 00 ff 25 48 20 40 00 ff 25 9c 20 40 00
ff 25 50 20 40 00 ff 25 54 20 40 00 ff 25 60 20
40 00 ff 25 64 20 40 00 ff 25 68 20 40 00 cc cc
55 8b ec b9 d0 33 40 00 e8 b3 f6 ff ff 5d c3 cc
55 8b ec b9 d8 33 40 00 e8 a3 f6 ff ff 5d c3 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

fa 25 00 00 e4 25 00 00 d4 25 00 00 ba 25 00 00
a6 25 00 00 88 25 00 00 6c 25 00 00 58 25 00 00
44 25 00 00 26 25 00 00 1e 25 00 00 08 25 00 00
10 26 00 00 00 00 00 00 34 24 00 00 42 24 00 00
54 24 00 00 66 24 00 00 7c 24 00 00 24 24 00 00
9a 24 00 00 a8 24 00 00 b0 24 00 00 ba 24 00 00
cc 24 00 00 e6 24 00 00 f8 24 00 00 14 24 00 00
00 24 00 00 ea 23 00 00 dc 23 00 00 d0 23 00 00
c4 23 00 00 bc 23 00 00 ae 23 00 00 a6 23 00 00
9c 23 00 00 8c 23 00 00 7e 23 00 00 90 24 00 00
68 23 00 00 00 00 00 00
00 00 00 00 51 11 40 00
40 19 40 00 50 19 40 00 00 00 00 00 00 00 00 00
12 13 40 00 45 15 40 00 00 00 00 00 00 00 00 00
00 00 00 00 4f c6 88 4d 00 00 00 00 02 00 00 00
57 00 00 00 b0 21 00 00 b0 0f 00 00
70 30 40 00
c8 30 40 00 01 00 00 00 02 00 00 00 03 00 00 00
04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00
08 00 00 00 09 00 00 00 48 65 6c 6c 6f 20 72 65
61 64 2d 6f 6e 6c 79 20 77 6f 72 6c 64 21 00 00
48 65 6c 6c 6f 21 0a 00 25 64 0a 00 25 64 0a 00
25 64 0a 00 25 64 0a 00 25 73 00 00 25 73 00 00
25 73 00 00 25 73 00 00 53 65 63 6f 6e 64 0a 00
25 73 00 00 00 00 00 00 48 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 30 40 00
10 22 40 00 01 00 00 00
52 53 44 53 42 cd 3d 79 0c 75 7a 4e ac 6c a8 90
87 e6 02 57 1c 00 00 00 65 3a 5c 50 72 6f 6a 65
63 74 73 5c 56 69 73 75 61 6c 20 53 74 75 64 69
6f 20 32 30 30 38 5c 53 69 6d 70 6c 65 41 70 70
5c 52 65 6c 65 61 73 65 5c 53 69 6d 70 6c 65 41
70 70 2e 70 64 62 00 00 00 00 00 00 00 00 00 00
25 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 fe ff ff ff 00 00 00 00
d0 ff ff ff 00 00 00 00 fe ff ff ff c2 12 40 00
d6 12 40 00 00 00 00 00 fe ff ff ff 00 00 00 00
cc ff ff ff 00 00 00 00 fe ff ff ff 00 00 00 00
f6 15 40 00 00 00 00 00 fe ff ff ff 00 00 00 00
d8 ff ff ff 00 00 00 00 fe ff ff ff 8b 17 40 00
9f 17 40 00 f8 22 00 00 00 00 00 00 00 00 00 00
72 23 00 00 38 20 00 00 c0 22 00 00 00 00 00 00
00 00 00 00 2a 26 00 00 00 20 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

fa 25 00 00 e4 25 00 00 d4 25 00 00 ba 25 00 00
a6 25 00 00 88 25 00 00 6c 25 00 00 58 25 00 00
44 25 00 00 26 25 00 00 1e 25 00 00 08 25 00 00
10 26 00 00 00 00 00 00 34 24 00 00 42 24 00 00
54 24 00 00 66 24 00 00 7c 24 00 00 24 24 00 00
9a 24 00 00 a8 24 00 00 b0 24 00 00 ba 24 00 00
cc 24 00 00 e6 24 00 00 f8 24 00 00 14 24 00 00
00 24 00 00 ea 23 00 00 dc 23 00 00 d0 23 00 00
c4 23 00 00 bc 23 00 00 ae 23 00 00 a6 23 00 00
9c 23 00 00 8c 23 00 00 7e 23 00 00 90 24 00 00
68 23 00 00 00 00 00 00 2e 05 70 72 69 6e 74 66
00 00 4d 53 56 43 52 39 30 2e 64 6c 6c 00 15 01
5f 61 6d 73 67 5f 65 78 69 74 00 00 9f 00 5f 5f
67 65 74 6d 61 69 6e 61 72 67 73 00 2c 01 5f 63
65 78 69 74 00 00 7c 01 5f 65 78 69 74 00 66 00
5f 58 63 70 74 46 69 6c 74 65 72 00 cc 04 65 78
69 74 00 00 a0 00 5f 5f 69 6e 69 74 65 6e 76 00
04 02 5f 69 6e 69 74 74 65 72 6d 00 05 02 5f 69
6e 69 74 74 65 72 6d 5f 65 00 3c 01 5f 63 6f 6e
66 69 67 74 68 72 65 61 64 6c 6f 63 61 6c 65 00
e3 00 5f 5f 73 65 74 75 73 65 72 6d 61 74 68 65
72 72 00 00 0b 01 5f 61 64 6a 75 73 74 5f 66 64
69 76 00 00 cb 00 5f 5f 70 5f 5f 63 6f 6d 6d 6f
64 65 00 00 cf 00 5f 5f 70 5f 5f 66 6d 6f 64 65
00 00 6a 01 5f 65 6e 63 6f 64 65 5f 70 6f 69 6e
74 65 72 00 e0 00 5f 5f 73 65 74 5f 61 70 70 5f
74 79 70 65 00 00 4b 01 5f 63 72 74 5f 64 65 62
75 67 67 65 72 5f 68 6f 6f 6b 00 00 43 00 3f 74
65 72 6d 69 6e 61 74 65 40 40 59 41 58 58 5a 00
e6 03 5f 75 6e 6c 6f 63 6b 00 96 00 5f 5f 64 6c
6c 6f 6e 65 78 69 74 00 76 02 5f 6c 6f 63 6b 00
1c 03 5f 6f 6e 65 78 69 74 00 60 01 5f 64 65 63
6f 64 65 5f 70 6f 69 6e 74 65 72 00 73 01 5f 65
78 63 65 70 74 5f 68 61 6e 64 6c 65 72 34 5f 63
6f 6d 6d 6f 6e 00 0b 02 5f 69 6e 76 6f 6b 65 5f
77 61 74 73 6f 6e 00 00 3f 01 5f 63 6f 6e 74 72
6f 6c 66 70 5f 73 00 00 bd 02 49 6e 74 65 72 6c
6f 63 6b 65 64 45 78 63 68 61 6e 67 65 00 21 04
53 6c 65 65 70 00 ba 02 49 6e 74 65 72 6c 6f 63
6b 65 64 43 6f 6d 70 61 72 65 45 78 63 68 61 6e
67 65 00 00 2d 04 54 65 72 6d 69 6e 61 74 65 50
72 6f 63 65 73 73 00 00 a9 01 47 65 74 43 75 72
72 65 6e 74 50 72 6f 63 65 73 73 00 3e 04 55 6e
68 61 6e 64 6c 65 64 45 78 63 65 70 74 69 6f 6e
46 69 6c 74 65 72 00 00 15 04 53 65 74 55 6e 68
61 6e 64 6c 65 64 45 78 63 65 70 74 69 6f 6e 46
69 6c 74 65 72 00 d1 02 49 73 44 65 62 75 67 67
65 72 50 72 65 73 65 6e 74 00 54 03 51 75 65 72
79 50 65 72 66 6f 72 6d 61 6e 63 65 43 6f 75 6e
74 65 72 00 66 02 47 65 74 54 69 63 6b 43 6f 75
6e 74 00 00 ad 01 47 65 74 43 75 72 72 65 6e 74
54 68 72 65 61 64 49 64 00 00 aa 01 47 65 74 43
75 72 72 65 6e 74 50 72 6f 63 65 73 73 49 64 00
4f 02 47 65 74 53 79 73 74 65 6d 54 69 6d 65 41
73 46 69 6c 65 54 69 6d 65 00 4b 45 52 4e 45 4c
33 32 2e 64 6c 6c 00 00 00 00 00 00 00 00 00 00
00 00 00 00 4f c6 88 4d 00 00 00 00 72 26 00 00
01 00 00 00 01 00 00 00 01 00 00 00 68 26 00 00
6c 26 00 00 70 26 00 00 50 10 00 00 80 26 00 00
00 00 53 69 6d 70 6c 65 41 70 70 2e 65 78 65 00
3f 68 65 6c 6c 6f 40 40 59 41 58 58 5a 00
00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

4e e6 40 bb b1 19 bf 44 ff ff ff ff ff ff ff ff
fe ff ff ff 01 00 00 00 01 00 00 00 0a 00 00 00
0b 00 00 00 0c 00 00 00 0d 00 00 00 0e 00 00 00
0f 00 00 00 48 65 6c 6c 6f 20 72 65 61 64 2d 77
72 69 74 65 20 77 6f 72 6c 64 21 00 18 21 40 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 04 00 00 00 00 00 01 00
18 00 00 00 18 00 00 80 00 00 00 00 00 00 00 00
04 00 00 00 00 00 01 00 01 00 00 00 30 00 00 80
00 00 00 00 00 00 00 00 04 00 00 00 00 00 01 00
09 04 00 00 48 00 00 00 58 40 00 00 56 02 00 00
e4 04 00 00 00 00 00 00 3c 61 73 73 65 6d 62 6c
79 20 78 6d 6c 6e 73 3d 22 75 72 6e 3a 73 63 68
65 6d 61 73 2d 6d 69 63 72 6f 73 6f 66 74 2d 63
6f 6d 3a 61 73 6d 2e 76 31 22 20 6d 61 6e 69 66
65 73 74 56 65 72 73 69 6f 6e 3d 22 31 2e 30 22
3e 0d 0a 20 20 3c 74 72 75 73 74 49 6e 66 6f 20
78 6d 6c 6e 73 3d 22 75 72 6e 3a 73 63 68 65 6d
61 73 2d 6d 69 63 72 6f 73 6f 66 74 2d 63 6f 6d
3a 61 73 6d 2e 76 33 22 3e 0d 0a 20 20 20 20 3c
73 65 63 75 72 69 74 79 3e 0d 0a 20 20 20 20 20
20 3c 72 65 71 75 65 73 74 65 64 50 72 69 76 69
6c 65 67 65 73 3e 0d 0a 20 20 20 20 20 20 20 20
3c 72 65 71 75 65 73 74 65 64 45 78 65 63 75 74
69 6f 6e 4c 65 76 65 6c 20 6c 65 76 65 6c 3d 22
61 73 49 6e 76 6f 6b 65 72 22 20 75 69 41 63 63
65 73 73 3d 22 66 61 6c 73 65 22 3e 3c 2f 72 65
71 75 65 73 74 65 64 45 78 65 63 75 74 69 6f 6e
4c 65 76 65 6c 3e 0d 0a 20 20 20 20 20 20 3c 2f
72 65 71 75 65 73 74 65 64 50 72 69 76 69 6c 65
67 65 73 3e 0d 0a 20 20 20 20 3c 2f 73 65 63 75
72 69 74 79 3e 0d 0a 20 20 3c 2f 74 72 75 73 74
49 6e 66 6f 3e 0d 0a 20 20 3c 64 65 70 65 6e 64
65 6e 63 79 3e 0d 0a 20 20 20 20 3c 64 65 70 65
6e 64 65 6e 74 41 73 73 65 6d 62 6c 79 3e 0d 0a
20 20 20 20 20 20 3c 61 73 73 65 6d 62 6c 79 49
64 65 6e 74 69 74 79 20 74 79 70 65 3d 22 77 69
6e 33 32 22 20 6e 61 6d 65 3d 22 4d 69 63 72 6f
73 6f 66 74 2e 56 43 39 30 2e 43 52 54 22 20 76
65 72 73 69 6f 6e 3d 22 39 2e 30 2e 32 31 30 32
32 2e 38 22 20 70 72 6f 63 65 73 73 6f 72 41 72
63 68 69 74 65 63 74 75 72 65 3d 22 78 38 36 22
20 70 75 62 6c 69 63 4b 65 79 54 6f 6b 65 6e 3d
22 31 66 63 38 62 33 62 39 61 31 65 31 38 65 33
62 22 3e 3c 2f 61 73 73 65 6d 62 6c 79 49 64 65
6e 74 69 74 79 3e 0d 0a 20 20 20 20 3c 2f 64 65
70 65 6e 64 65 6e 74 41 73 73 65 6d 62 6c 79 3e
0d 0a 20 20 3c 2f 64 65 70 65 6e 64 65 6e 63 79
3e 0d 0a 3c 2f 61 73 73 65 6d 62 6c 79 3e 50 41
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47
50 41 44 44 49 4e 47 58 58 50 41 44 44 49 4e 47

00 10 00 00 64 01 00 00 16 30 22 30 28 30 54 30
5a 30 75 30 7e 30 85 30 93 30 9d 30 a3 30 ac 30
b2 30 b8 30 c0 30 c6 30 cc 30 d5 30 db 30 e1 30
e9 30 ee 30 f4 30 fd 30 03 31 09 31 11 31 17 31
1d 31 26 31 2c 31 32 31 44 31 52 31 5c 31 63 31
69 31 6e 31 73 31 78 31 7d 31 83 31 8b 31 9f 31
ba 31 c3 31 de 31 e8 31 fb 31 05 32 0a 32 0f 32
31 32 36 32 3f 32 44 32 51 32 62 32 68 32 6f 32
83 32 88 32 8e 32 96 32 9c 32 a2 32 af 32 b5 32
be 32 dd 32 e5 32 ee 32 f4 32 fc 32 08 33 1a 33
25 33 2b 33 74 33 7a 33 82 33 89 33 8e 33 94 33
9a 33 a2 33 a8 33 af 33 b6 33 c6 33 ce 33 d4 33
e0 33 eb 33 09 34 0f 34 15 34 1b 34 21 34 27 34
2e 34 35 34 3c 34 43 34 4a 34 51 34 58 34 60 34
68 34 70 34 7c 34 85 34 8a 34 90 34 9a 34 a3 34
ae 34 ba 34 bf 34 cf 34 d4 34 da 34 e0 34 f6 34
fd 34 46 35 4c 35 56 35 5d 35 68 35 6e 35 82 35
97 35 a2 35 ba 35 d0 35 dd 35 1a 36 1f 36 40 36
45 36 64 36 08 37 0d 37 1f 37 3d 37 51 37 57 37
c0 37 c6 37 cd 37 ea 37 37 38 3c 38 81 38 a4 38
b1 38 bd 38 c5 38 cd 38 d9 38 fd 38 05 39 10 39
16 39 1c 39 22 39 28 39 2e 39 34 39 3a 39 44 39
54 39 00 00 00 20 00 00 24 00 00 00 ac 30 b0 30
b4 30 c0 30 c4 30 ec 30 f0 30 a4 31 a8 31 3c 32
40 32 60 32 7c 32 80 32 00 30 00 00 0c 00 00 00
4c 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

close

Legend

______ DOS stub
______ PE signature
______ COFF header
______ Optional header
______ Sections table

______ .text
______ .rdata
______ .data
______ .rsrc
______ .reloc

Dos stub

Offset: 0
Size: lasts to PE signature (almost)

Dos stub is a small DOS application which if run in DOS will display "This program cannot be run in DOS mode". You can specify a different stub when linking.

Important:
At location 0x3c you find the offset of the PE signature, here it is 0xe0.

PE signature

Offset: given by [0x3c] in Dos stub
Size: 4 bytes

Four bytes which always are "PE\0\0" or 50 45 00 00.

COFF header

Offset:[0x3c]+4 (follows PE signature)
Size: 20 bytes

Contains most general information about the file, such as processor architecture type, timestamp and others.

SizeField
2Machine type
2Number of sections
4Timestamp
4Address of symbol table
4Number of symbols
2Size of Optional Header
2Characteristics

Field description:
Machine type specifies the CPU type of the machine where the program can run, most popular values are:
0x8664 - AMD64
0x1c0 - ARM little endian
0xebc - EFI byte code
0x14c - Intel 386 compatible
0x200 - Intel Itanium

Field description:
Number of sections indicates the size of section table.

Field description:
Unix time of file creation which is the number of seconds since 00:00 January 1,1970. This value 0x4dc6884d = 1300809295 corresponds to Tue, 22 Mar 2011 15:54:55 GMT.

Field description:
Pointer to symbol table is zero, because Microsoft doesn't use COFF debug information.

Field description:
Number of symbols table is zero, because Microsoft doesn't use COFF debug information.

Field description:
Size of Optional Header that follows the COFF Header.

Field description:
Characteristics are flags that specify image attributes. Here value 0x102 indicates that it is valid (flag 0x2) 32-bit (flag 0x100) image.

Optional header (standard fields)

Offset:[0x3c]+24 (follows COFF header)
Size: 28 bytes

Mostly contains general information about code and data sections

SizeField
2Magic number
1Major linker version
1Minor linker version
4Size of code
4Size of initialized data
4Size of uninitialized data
4Address of entry point(loaded)
4Base of code (loaded)
4Base of data (loaded)

Field description:
Magic number the most common values of which are:
0x10B - PE32 executable
0x20B - PE32+ executable

Field description:
The size of code section or sum of sizes of code sections if multiple. Sizes of sections may be found in section table.

Field description:
The size of initialized data section or sum of sizes of such sections if multiple. Sizes of sections may be found in section table.

Field description:
The size of uninitialized data section (.bss) or sum of sizes of such sections if multiple. Sizes of sections may be found in section table.

Field description:
RVA of entry point of loaded image.

Field description:
RVA of the beginning of the loaded code section. Information about sections can also be found in section table.

Field description:
RVA of the beginning of the loaded data section Information about sections can also be found in section table.

Optional header (windows fields)

Offset:[0x3c]+120 (follows standard fields)
Size: 68 bytes

Contains essential information for Windows images

SizeField
4Image Base
4Section alignment
4File alignment
2Major OS version
2Minor OS version
2Major image version
2Minor image version
2Major subsystem version
2Minor subsystem version
4Win32 version
4Image size (loaded)
4Size of headers
4Checksum
2Subsystem
2Dll characteristics
4Size of stack (reserve)
4Size of stack (comitted)
4Size of heap (reserve)
4Size of heap (comitted)
4Loader flags
4Number of data directories

Field description:
Preferred address for image loading, default address for DLLs is0x1000000, for EXE file -0x400000.

Field description:
The alignment of sections when they are loaded in the memory.

Field description:
The alignment of sections (raw data) in the image file.

Field description:
Reserved, must be 0.

Field description:
The size of loaded image, must be multiple of Section Alignment.

Field description:
The size of all headers including dos stub up to section data. Must be multiple of File Alignment.

Field description:
Windows subsystem required to run the program:
1 - native
2 - GUI
3 - console
...

Field description:
Additional flags indicating image attributes:
0x0040 - Can be relocated
0x0080 - Integrity check enforced (program signing)
0x0100 - NX compatible (execution of code from data sections can be disabled)
0x0200 - Do not isolate image
0x0400 - No SEH
0x0800 - Do not bind the image
0x2000 - WDM driver
0x8000 - Terminal server aware

Field description:
Reseved, must be zero.

Field description:
The number of entries in data directories table.

Optional header (Data directories)

Offset:[0x3c]+188 (follows windows specific fields)
Size: 8 x [[0x3c]+184] (number of directories)

Contains RVA and sizes of Microsoft defined data structures. Each directory is 8 bytes (DWORD RVA, DWORD size). Order of directories:

OffsetStructure
0Export table
8Import table
16Resource table
24Exception table
32Certificate table
40Base relocation table
48Debug
56Reserved
64Global Ptr
72TLS table
80Load Config table
88Bound Import
96IAT
104Delay Import descriptor
112CLR runtime header
120Reserved

Sections table

Offset:follows optional header
Size:40 bytes multiplied ny number of sections

.text section entry

.rdata section entry

.data section entry

.rsrc section entry

.reloc section entry

Section entry format:

SizeField
8Section name
4Size (loaded)
4Relative address (loaded)
4Size in file
4Offset in file
4Pointer to relocations
4Pointer to line numbers
2Number of relocations
2Number of line numbers
4Characteristics

Field description:
Null terminated UTF-8 string containing the name of the section.

Field description:
For executables is always zero. This relocation table is related to linking relocations, not to base relocations.

Field description:
For executables should be zero, because COFF debugging information is depricated and Microsoft defined debug structures are used instead.

Field description:
For executables is always zero. This relocation table is related to linking relocations, not to base relocations.

Field description:
For executables should be zero, because COFF debugging information is depricated and Microsoft defined debug structures are used instead.

Field description:
Set of flag indicating section attributes. For executable files following flags are used:
0x00000020 - contains executable code
0x00000040 - contains initialized data
0x00000080 - contains uninitialized data
0x01000000 - contains extended relocations
0x02000000 - can be discarded
0x04000000 - cannot be cached
0x08000000 - cannot be paged
0x10000000 - can be shared
0x20000000 - can be executed as code
0x40000000 - can be read
0x80000000 - can be written to

Conclusion

This article was designed as a gentle introduction to the PE/COFF format. I touched the ideas behind the format and simple practical implications. The general layout of PE/COFF was shown, the legacy part of it and Microsoft extensions of headers were covered. I didn't touch the big part of the specification dealing with special sections and data structures planning to write other articles where they could be approached from the practical side. To look a bit deeper into the format I recommend great articles by Matt Pietrek mentioned in Reference section and the specification itself.

References and links

  1. Freeware tool for exploring PE files from SmidgeonSoft: PEBrowsePro
  2. Microsoft Portable Executable and Common Object File Format Specification
  3. Great Matt Pietrek's article about PE/COFF format (MSDN Magazine, March 1994)
  4. An In-Depth Look into the Win32 Portable Executable File Format, Part 1 (MSDN Magazine, February 2002)
  5. An In-Depth Look into the Win32 Portable Executable File Format, Part 2 (MSDN Magazine, February 2002)
  6. COFF format
  7. The NE EXE File Format
  8. The MZ EXE File Format
  9. The MS-DOS COM Executable File Format

Comments

devtools korzh: http://devtools.korzh.com/

added Thu, 03 Oct 2013 03:51:19 -0400
Great work!
Place a comment