www.xbdev.net xbdev - software development
Friday December 14, 2018
home | about | contact | Donations

Chptr-3- FileHeader isnt' scary its our friend.

So here we are luke, use the force...the force!!... :)

Here we are, at the FileHeader, this is the actual start of our journey you might say... as the rest of the code upto know is just DOS padding...checking that we have a PE.  I better refresh your minds:

  • We had the DOS_MZ header called IMAGE_DOS_HEADER.  Only two of its members where important the e_magic which had the string "MZ" and the e_lfanew, which was a offset from the start of the file to the PE header.
  • Using the IMAGE_DOS_SIGNATURE value ("MZ" or 0x543D) as a check value to confirm its a PE.
  • Get the e_lfanew value from the file and use it to find the start of our PE header.
  • Check the first dword (4-bytes) of our PE header to see if it contained the string "PE" (a.k.a 0x4550).

So now on with the story... The PE Header's offical name is IMAGE_NT_HEADERS and can be found in the winnt.h file for visual c users.  But I'll show you it below:

struct IMAGE_NT_HEADERS

{

DWORD Signature;

IMAGE_FILE_HEADER FileHeader;

IMAGE_OPTIONAL_HEADER32 OptionalHeader;

};

 

Signature - is the PE signature, "PE" followed by two zero's.  You should already know this!

FileHeader - is a strucre that contains the information about the physical layout/properties of the PE fie in general.

OptionalHeader is also a structure that contains the information about the logical layout inside the PE (Note the word logical.)

So to start with I think we should have a look inside FileHeader, crack this nut open and see what it contains :)

struct IMAGE_FILE_HEADER

{

WORD Machine;

WORD NumberOfSections;

DWORD TimeDateStamp;

DWORD PointerToSymbolTable;

DWORD NumberOfSymbols;

WORD SizeOfOptionalHeader;

WORD Characteristics;

};

Well there isnt' any thing in there thats special... nothing to make us jump!

I think I should tell you what some of the values mean... so that you have a greater understanding as they say...

Machine - The CPU platform the file is intended for.  For intel platform, the value is (0x014Ch) and is defined as IMAGE_FILE_MACHINE_I386 in the winnt.h file.  Note: if you go into a hex editor and change this value windows will refuse to run your program.

 

NumberOfSections - Well it should be obvious from the name, it tells us how many sections are in our file... we could increase this value if we add a section to our file.

TimeDateStamp - The date and time the file is created.

PointerToSymbolTable - Used in debugging.

NumberOfSymbols - Used in debugging.

SizeOfOptionalHeader - The size of the OptionalHeader member that immediately follows this structure.  Must be a valid value.

Characteristics - List of flags that tell us about the file, e.g. if its an .exe or .dll etc.

 

 

Well shall we wet our feet and do some coding to examine the .exe file some more.

#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, 4, 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

unsigned int NT_SIG;

fread(&NT_SIG, 4, 1, pFile);

sprintf(buff, "NT Signature at start of PE Header: %x", NT_SIG);

output(buff);

struct stIMAGE_FILE_HEADER

{

WORD Machine;

WORD NumberOfSections;

DWORD TimeDateStamp;

DWORD PointerToSymbolTable;

DWORD NumberOfSymbols;

WORD SizeOfOptionalHeader;

WORD Characteristics;

};

stIMAGE_FILE_HEADER FileHeader;

// Well lets just read in the whole lot in one go in to our defined structure

fread(&FileHeader, sizeof(FileHeader), 1, pFile);

// Output what we have found.

sprintf(buff, "FileHeader - Machine value: %x", FileHeader.Machine);

output(buff);

sprintf(buff, "FileHeader - NumberOfSections: %x", FileHeader.NumberOfSections);

output(buff);

sprintf(buff, "FileHeader - NumberOfSymbols: %x", FileHeader.NumberOfSymbols);

output(buff);

sprintf(buff, "FileHeader - SizeOfOptionalHeader: %x", FileHeader.SizeOfOptionalHeader);

output(buff);

sprintf(buff, "FileHeader - Characteristics: %x", FileHeader.Characteristics);

output(buff);

fclose(pFile);

}

 

And if you run the above code and read in the FileHeader information, the output.txt contains:

DOS Signature at start of file: 5a4d
e_lfanew value is: e0
NT Signature at start of PE Header: 4550
FileHeader - Machine value: 14c
FileHeader - NumberOfSections: 3
FileHeader - NumberOfSymbols: 0
FileHeader - SizeOfOptionalHeader: e0
FileHeader - Characteristics: 10f

The value of FileHeader-Machine tells us that this code was compiled for an intel machine (14c), we also now know that there are three sections (e.g. NumberOfSections).

 

 

 
 Visitor: 9534626  { 209.237.238.175 } Copyright (c) 2002-2017 xbdev.net - All rights reserved.
Designated tutorial and software are the property of their respective owners.