www.xbdev.net
xbdev - software development
Wednesday January 15, 2025
Home | Contact | Support

Chptr-1- PE File Format From a Distance.

Now you have to remember when you start to learn the secrets of any file format, especially one that is as complex and intimidating as this one!  Your the boss... you can delete it, change the bits or what ever you want!  Its only a big array of 1's and 0's.

In we go... a 350g jar of coffee and a kettle full of hot water and we're ready :)

PE = Portable Executable, yup that's what it stands for.  Its the native format for all Win32's OS, which means whether your running linux or windows or unix etc, it follows the PE file format!  So by learning this its going to give you a lot of power :)

In we go, lets see what it looks like underneath the bonet:

DOS MZ header
DOS stub
PE header
Section table
Section 1
Section 2
Section ..
Section n

 

Well there you go, I bet your getting scared already... well don't worry.. once I tell you what's in those parts you'll feel better.  So now all PE's even DLL's use this structure.  The first part which is the includes DOS MZ header is our entry point.. the start of our journey.

Okay the first two sections are for DOS, well it goes back to the days of dos, as when windows came along so that if you run the exectuable in dos you'll get the message "This program cannot run in DOS mode".  So the DOS MZ header contains the offset into the DOS stub, and the DOS stub is a mini dos program... in case your wondering where it comes from... the compiler/linker inserts it automatically when you build an exe/dll.

Next as you can see from above, is the PE header.  If you open up the winnt.h files you'll find a struct called IMAGE_NT_HEADER which is a structure which represnts our PE header.  This structure tells us a lot of things about our PE, its type, the number of sections (e.g. code pieces) how big it is etc.

The real parts of our PE, the parts which contain our code!  The code that your going to compile soon.. in later chapters, well its all in the blocks called sections.  Very very important that you remember this, a section is nothing more than a block of data.... repeat after me... "block of data" ;)  Each section has attributes for itself, e.g. code/data, read/write etc.

So that you don't get lost, think of the header as a boot sector, and the sections as folders... as you would for a disk.  And as you can set the file attributes for folders such as hidden, read only etc... the same applies here.

Important news ->The grouping of data into sections is done on the common attribute basis, not on a logical basis<-  It doesn't matter how the code/data are used, if it has the same attributes they can be lumped together into a section.  Remember a section similar to a folder can can contain a variety of stuff... so when you think of a section, it can contain code/data etc... it is grouped based on the attributes.

Well up to this point we have the PE Header, this doesn't tell us where our data/code is...and what the sections are!  We must look at the next part which is "Section table"... where nearly there so hang on a little more.  Now immediately following the PE Header is an 'array' of structures.  When I mean an array of structures I mean, the the Section table is made up of loads of little identical structures.  Just think of a box full of apples.  The section table is the box, and its full of apples (I'll expand on this theory later).

Each sub-section (apple) of the section table will contain the information on one of our sections, its offset, its attribues etc.  So if we have 3 sections, we will have an array of 3 structures in our section table... does that make sense?  Have I lost you?

 

In a nutshell thats the PE layout!  At the moment there's usually questions of "why" and "what's that for" and "what if's" .. well keep with me on this journey of discovery and we'll answer your questions.

Lets review what actually happens when you run an PE (or exe/dll).

  1. The PE file is run, then the PE Loader looks at our PE file and examines the DOS MZ header for the offset to the PE header.  If it finds it it then jumps to our PE Header.

  2. PE Loader again checks that the PE header is valid.

  3. The PE Loader goes to the end of the PE Header and starts to read in the the information from the section table.  Now the PE Loader knows how many sections we have an what there attribues are.  It loads our sections into memory (using file mapping) with there designated attribues, e.g. read only etc.  -- When I use the word file mapping, I mean a the data from the section is copied into memory exactly as it is!  So if you can access the memory you'd see that is an exact copy of your PE Section. :)

  4. The PE Loader then moves on a notch and checks for imports from other files etc.... which is part of the import table which we'll get to in a bit.

Thats it... as easy as "one-two-three"... or "a-b-c" ... :)   Yup I may have oversimplified it... but those are the facts and as you move on you'll soon see that its as easy as that.

 

 

 

 

 

 

 
Advert (Support Website)

 
 Visitor:
Copyright (c) 2002-2024 xbdev.net - All rights reserved.
Designated articles, tutorials and software are the property of their respective owners.