VLCheats CSGO League Cheats Advertise With GuidedHacking

Guide PE File Format & Windows PE Loader

Rake

Cesspool CEO
Administrator
Jan 21, 2014
9,899
77,998
2,171
Game Name
N/A
Anticheat
N/A
Coding Language
N/A
After learning the basics of game hacking and reverse engineering you will have a very vague understanding of the PE File Format and the Windows Loader. After 6-12 months of learning you will want to take some time to get a better understanding of these things as they will be important for dealing with anticheat and antidebug.

Required Experience
Complete the Guide - START HERE Beginners Guide to Learning Game Hacking
Have a basic understanding of everything in Guide - Beginners Guide To Reverse Engineering Tutorial

Steps to Learn about PE Files and the Windows Loader
  1. Learn about PE File Format & PE Header using our collection of links
  2. Take a look at some binaries in PEStudio / pe-bear / PEExplorerV2
  3. Life of Binaries Youtube Playlist
  4. Try a few sample source codes which parse the PE header
  5. Learn how to Manual Map a DLL
  6. Checkout ReactOS's CreateProcessInternal function

PE File Format & Header Resources

pe101.png
(the awesome image is from corkami)

The PE File Format is essentially defined by the PE Header so you will want to read about that first, you don't need to understand every single part of it but you should get an idea about it's structure and be able to identify the parts that are most important.

I will briefly talk about some of the important parts of the header, but refer you to the list of links below which will have a much better explanation. I will not go into depth here, view the resources for more specifics.

DOS Header
The first two bytes of the header are the magic bytes which identify the file type, 4D 5A or "MZ" which are the initials of Mark Zbikowski who worked on DOS at Microsoft. These magic bytes define it as a PE file. You will also find the string "This program cannot be run in DOS mode" which will appear if you try to run a Windows PE file in DOS. This is here for backwards compatibility.

At offset 0x60 of the DOS HEADER there is a variable named e_lfanew which contains the offset to the PE header

C++:
 struct DOS_Header
{
// short is 2 bytes, long is 4 bytes
     char signature[2] = { 'M', 'Z' };
     short lastsize;
     short nblocks;
     short nreloc;
     short hdrsize;
     short minalloc;
     short maxalloc;
     void *ss; // 2 byte value
     void *sp; // 2 byte value
     short checksum;
     void *ip; // 2 byte value
     void *cs; // 2 byte value
     short relocpos;
     short noverlay;
     short reserved1[4];
     short oem_id;
     short oem_info;
     short reserved2[10];
     long  e_lfanew; // Offset to the 'PE\0\0' signature relative to the beginning of the file
}
PE Header
This portion is small and simply contains a file signature which are the magic bytes 'PE\0\0' or 50 45 00 00.

COFF Header
COFF = Common Object File Format which is the format which predates the PE file format.
C++:
 struct COFFHeader
{
    short Machine;
    short NumberOfSections;
    long TimeDateStamp;
    long PointerToSymbolTable;
    long NumberOfSymbols;
    short SizeOfOptionalHeader;
    short Characteristics;
}
Optional Header
Now we're getting into the actual meat of the PE header. This is not actually optional, it's optional in context of COFF object files but not PE files. It contains many important variables such as AddressOfEntryPoint, ImageBase, Section Alignment, SizeOfImage, SizeOfHeaders and the DataDirectory. This structure has 32 bit and 64 bit versions.

Section Table
Contains an array of IMAGE_SECTION_HEADER structs which define the sections of the PE file such as the .txt and .data sections

C++:
 struct IMAGE_SECTION_HEADER
{
// short is 2 bytes
// long is 4 bytes
  char  Name[IMAGE_SIZEOF_SHORT_NAME]; // IMAGE_SIZEOF_SHORT_NAME is 8 bytes
  union {
    long PhysicalAddress;
    long VirtualSize;
  } Misc;
  long  VirtualAddress;
  long  SizeOfRawData;
  long  PointerToRawData;
  long  PointerToRelocations;
  long  PointerToLinenumbers;
  short NumberOfRelocations;
  short NumberOfLinenumbers;
  long  Characteristics;
}
After the section table comes the actual sections

Learn more specifics in the resources below

PE Resources

PE File Tools
pestudio is one of the best tools for examining PE files and the PE header for binaries, download it and checkout a view binaries with it.
PE-bear is also amazing, if you like it check out hasherezade's pe-sieve and her other repos she has some amazing stuff
PEExplorerV2 is my third favorite PE tool

We also have a collection of various PE related tools here Hacking Tools

Life of Binaries Video Series
This is a great playlist that will teach you alot about the PE file format and the Windows OS. You can also download the slides, graphics & more from their site LifeOfBinaries


Example of Parsing the PE Header

Parsing the Export Table

To give you an idea of what you can do by parsing the PE header here is a function from @iPower which shows you how to walk the export table and find the address of the exported function

C++:
uintptr_t helpers::get_module_export( const char* module_name, const char* export_name )
{
    if ( !module_name || !export_name )
        return 0;
  
    auto module_base = reinterpret_cast< uintptr_t >( GetModuleHandleA( module_name ) );
  
    if ( !module_base )
        return 0;
  
    auto pimage_dos_header = reinterpret_cast< PIMAGE_DOS_HEADER >( module_base );
  
    if ( pimage_dos_header->e_magic != IMAGE_DOS_SIGNATURE )
        return 0;
  
    auto pimage_nt_headers = reinterpret_cast< PIMAGE_NT_HEADERS >( module_base + pimage_dos_header->e_lfanew );
  
    if ( pimage_nt_headers->Signature != IMAGE_NT_SIGNATURE )
        return 0;
  
    auto export_directory_rva = pimage_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
  
    if ( !export_directory_rva )
        return 0;
  
    auto pimage_export_directory = reinterpret_cast< PIMAGE_EXPORT_DIRECTORY >( module_base + export_directory_rva );
    auto peat = reinterpret_cast< PDWORD >( module_base + pimage_export_directory->AddressOfFunctions );
    auto pent = reinterpret_cast< PDWORD >( module_base + pimage_export_directory->AddressOfNames );
    auto peot = reinterpret_cast< PWORD >( module_base + pimage_export_directory->AddressOfNameOrdinals );
  
    unsigned short ordinal = 0;
  
    for ( DWORD i = 0; i < pimage_export_directory->NumberOfNames; ++i )
    {
        if ( !lstrcmpiA( export_name, reinterpret_cast< const char* >( module_base + pent[i] ) ) )
        {
            ordinal = peot[i];
            break;
        }
    }
    return ordinal ? module_base + peat[ordinal] : 0;
}
C# Export Table Parsing
C# Get Address of Exported Function

Import Address Table Hooking
C++ IAT Hooking Source Code

Windows PE Loader

Here's some info from ARTeam's PE File Format Compendium which is an excellent resource for learning about this. This is the best little explanation of the PE Loader to get you started:

The Loader
When an executable is run, the windows loader creates a virtual address space for the process and maps the executable module from disk into the process' address space. It tries to load the image at the preferred base address and maps the sections in memory. The loader goes through the section table and maps each section at the address calculated by adding the RVA of the section to the base address. The page attributes are set according to the section’s characteristic requirements. After mapping the sections in memory, the loader performs base relocations if the load address is not equal to the preferred base address in ImageBase.

The import table is then checked and any required DLLs are mapped into the process' address space. After all of the DLL modules have been located and mapped in, the loader examines each DLL's export section and the IAT is fixed to point to the actual imported function address. If the symbol does not exist (which is very rare), the loader displays an error. Once all required modules have been loaded execution passes to the app's entry point

The area of particular interest in RCE is that of loading the DLLs and resolving imports. This process is complicated and is accomplished by various internal (forwarded) functions and routines residing in ntdll.dll which are not documented by Micro$oft. As we said previously function forwarding is a way for M$ to expose a common Win32 API set and hide low level functions which may differ in different versions of the OS. Many familiar kernel32 functions such as GetProcAddress are simply thin wrappers around ntdll.dll exports such as LdrGetProcAddress which do the real work

Learn how to Manual Map a DLL
Learning manual mapping is a great way to learn alot of it, but it's not for noobs. Make sure you have a solid understanding before diving into this. Manual mapping a DLL is essentially emulating everything LoadLibrary() does, by learning how to manual map you are learning how the Windows Loader loads a DLL.


The source code for the manual mapping routine in the GH Injector has been updated, you can download it here Guided Hacking DLL Injector

ReactOS
ReactOS can be regarded as a Windows clone, it can load PE files just like Windows so there source code is super helpful for learning about the internal workings of Windows. While we're talking about the Windows Loader, this function specifically is a great resource: CreateProcessInternal


Undocumented Windows API Functions & Structures
This isn't 100% on topic but I think it's something you will want to touch on at the same time you are learning about the things in this guide. You will need to access and use many undocumented Windows API functions and structures in the course of your hacking career. In the Windows SDK there is a file called winternl.h which has many structures which are important to us, but many of them have "Reserved" member variables that Microsoft doesn't want us to know about and doesn't want us to use so they are left undefined. Using the winternl.h versions will not allow you complete access to everything you may need.

One of the easiest things you can do to get experience dealing with Windows Internals is to play with some of these undocumented structures and functions. You can learn more about them in this tutorial
 
Last edited:

Rake

Cesspool CEO
Administrator
Jan 21, 2014
9,899
77,998
2,171
ok this is 80% complete gonna drop it like this before I lose my mind. As always, contribute to this guide in the replies and I can update the guide with whatever information, links etc... you provide

This isn't part of the main guide but was something interesting shared to me on Twitter Tiny PE File

Thank you to those of you who shared resources with me via Twitter
 
Last edited:
  • Love
Reactions: Kleon742

IXSO

Newbie
Full Member
Nobleman
Dec 30, 2017
197
2,108
22
ok but what am i learning here?
btw i remember there used to be a simple yet useful tool called LordPE(e)
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

VLCheats CSGO League Cheats Advertise With GuidedHacking