Chptr-2- Start of a PE.
Well the journey must start somewhere as they say....
To start with we must create a little application, a small Win32 exe that
we can use to explore, as I mentioned earlier I was going to use notepad.exe,
but I think its better if we start with our own code first.
The code and its output:
#include
<windows.h>
#pragma
comment(lib,
"user32.lib")
int
__stdcall
WinMain(HINSTANCE, HINSTANCE, char*,
int)
{
int i = 0;
i++;
MessageBox(0,
"Hello World", "Title Box", 0);
return 0;
};
|
 |
So there you have it a simple piece of code - now if you compile it you'll
get to files, "simple.obj(851 bytes)" and a "simple.exe(36,864 bytes)" (e.g. I
called the file simple.cpp).
Note the differences in size, next what happens if we run our .exe in dos?
On with our exploration.... So now we have our PE file which we can play
with, we've sort of got an idea of whats in there... a simple library call for
a message box and an int i which is incremented once.
Lets dig out the PE header, see what it atucally lucks like a structure
(its contained in winnt.h):
struct IMAGE_NT_HEADERS
{
DWORD
Signature;
IMAGE_FILE_HEADER
FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
};
Well as you can see the PE Header is pretty simple... Let me just explain
the sections.
Signature is a dword that contains
the value "50h, 45h, 00h, 00h". In human terms it contains the text "PE"
followed by two null's. This member is the PE signature so we can use it
to verify that we have a PE on our hands.
FileHeader is another structure
that contains information about the physical layout of the PE file such as the
number of sections, the machine the file is targeted at (e.g. UNIX, Intel etc)
.. and so on.
OptionalHeader is a structure that
is in "all" PE's and contains information about the logical layout of the PE
file. Remember despite the word "Optional" in its name it is always
there :)
Comment:
The signature may vary from PE to
PE and can define other OS it was compiled for, e.g.:
4Dh 5Ah 00h 00h -
Dos Signature
4Eh 45h 00h 00h -
OS2 Signature
4Ch 45h 00h 00h -
VxD Signature
50h 45h 00h 00h
- WindowsNT Signature
So I know what your wondering now.... how do we even know where the PE
Header begins.. because of this DOS Header and DOS Stub. Well the DOS MZ
Header is defined in winnt.h as well as:
struct
IMAGE_DOS_HEADER // DOS .EXE header
{
WORD e_magic;
// Magic number (e.g. 5A 4Dh)
WORD e_cblp;
// Bytes on last page of file
WORD e_cp;
// Pages in file
WORD e_crlc;
// Relocations
WORD
e_cparhdr; // Size of header in
paragraphs
WORD
e_minalloc; // Minimum extra
paragraphs needed
WORD
e_maxalloc; // Maximum extra
paragraphs needed
WORD e_ss;
// Initial (relative) SS value
WORD e_sp;
// Initial SP value
WORD e_csum;
// Checksum
WORD e_ip;
// Initial IP value
WORD e_cs;
// Initial (relative) CS value
WORD e_lfarlc;
// File address of relocation table
WORD e_ovno;
// Overlay number
WORD
e_res[4]; // Reserved words
****2*4=8bytes***
WORD e_oemid;
// OEM identifier (for e_oeminfo)
WORD
e_oeminfo; // OEM information;
e_oemid specific
WORD
e_res2[10]; // Reserved words ***
10*2=20bytes**
LONG e_lfanew;
// File address of new exe header
(its an offset value from the beginning of the file!!!!)
}; |
Okay I've listed the whole structure for IMAGE_DOS_HEADER above, but the
only parts of it you'll really need to know is e_lfanew
and e_magic. The rest is just useless to us
for the moment... and we can skip over it for now.
Let coding begin...
#include
<windows.h>
#include
<stdio.h>
// Output to a
text file.
void
output(char*
str)
{
FILE *fp =
fopen("output.txt", "a+");
fprintf(fp,
"%s\n", str);
fclose(fp);
}
char
buff[500];
// Entry point
(its a windows entry point).
int
_stdcall
WinMain(HINSTANCE, HINSTANCE, char*
k, int l)
{
// Open our file called simple.exe
FILE *pFile =
fopen("simple.exe", "rb");
short
unsigned
int DOS_SIG;
fread(&DOS_SIG,
2, 1, pFile);
sprintf(buff,
"DOS Signature at start of file: %x", DOS_SIG);
output(buff);
fclose(pFile);
} |
And the output of this program would be to a text file called "output.txt"
in the same directory... don't forget our PE that we compiled earlier has to
be in the same directory as well. The output in the output.txt file is:
DOS Signature at start of file: 5a4d
Wow, yup, its as I told you... we have the e_magic value of 5a4d in hex
which is equal to IMAGE_DOS_SIGNATURE. So next we have to get the
e_lfanew value, which is a further 58 bytes along, so we'll read this value in
now. (the 58 bytes you can work out if you count the number of WORDs in
the structure, remember 2 bytes per word, and remember to check for arrays).
#include
<windows.h>
#include
<stdio.h>
// Output to a
text file.
void
output(char*
str)
{
FILE *fp =
fopen("output.txt", "a+");
fprintf(fp,
"%s\n", str);
fclose(fp);
}
char
buff[500];
// Entry point
(its a windows entry point).
int
_stdcall
WinMain(HINSTANCE, HINSTANCE, char*
k, int l)
{
// Open our file called simple.exe
FILE *pFile =
fopen("simple.exe", "rb");
short
unsigned
int DOS_SIG;
fread(&DOS_SIG,
2, 1, pFile);
sprintf(buff,
"DOS Signature at start of file: %x", DOS_SIG);
output(buff);
// Skip the next 58 bytes.
fseek(pFile,
58, SEEK_CUR);
unsigned
int e_lfanew;
fread(&e_lfanew,
2, 1, pFile);
sprintf(buff,
"e_lfanew value is: %x", e_lfanew);
output(buff);
// Use the e_lfanew value to seek to the
start of the PE Header
fseek(pFile,
e_lfanew, SEEK_SET);
// See if we have a PE Header signature
short
unsigned
int NT_SIG;
fread(&NT_SIG,
2, 1, pFile);
sprintf(buff,
"NT Signature at start of PE Header: %x", NT_SIG);
output(buff);
fclose(pFile);
} |
And what does this wonderful program output?
DOS Signature at start of file: 5a4d
e_lfanew value is: e0
NT Signature at start of PE Header: 4550
Well there you go, I've got you to the start of the PE Header... we can see
that the value 0x4550 is the value of an NT (windows) PE Header... its also
defined as IMAGE_NT_SIGNATURE.
So what have we accomplished? A lot, we've opened a PE and had a look
in there, we've confirmed the DOS Signature and go tthe e_lfanew value and
found out PE Header. Remember though, the e_lfanew value is the offset
relative to the beginning of the file.
|