Page cover image

Essentials

PE Primer

PE stands for "Portable Executable"

It's a way to organize executable code in a file which usually have the extension ".exe"

When we run the PE file the OS loader reads it from disk and loads it into memory as a process:

This picture shows details of the PE structure, the main points here:

  • header: Contains metadata, information about where everything is located.

  • sections: Contains executable code, data and imports used by executable code.

Practical PE-bear

Let's run PE-bear and load C:/Windows/System32/calc.exe:

Here, we went to "Section Hdrs" and there are interesting things here, lets take a look at them:

  • .text: Contains executable code

  • .rdata: Contains read only data

  • .data: Contains application global variables

  • .pdata: Information about exceptions

  • .rsrc: It's a section that contains different objects

  • .reloc: Contains relocation information which allows windows loader to safely load the DLL/exe file into memory with randomized address space

The objects in resources section might be:

  • Pictures

  • Icons

  • Other PE files (.exe)

  • Other DLLs

It's so important for us as malware developers:

In summary, the 3 most important sections for us are:

  • .text

  • .data

  • .rsrc

As an alternative to PE-bear you can use "dumpbin" in visual studio native tools command line

Generating PE File

We will be working on both exe and DLLs:

  • exe are separate programs which can be loaded into memory as independent process

  • DLLs are PE modules that are loaded into existing processes and cannot live independently in memory, the main purpose of DLL is to deliver some functionality a calling process needs

We need the following to generate a PE file:

  • Source code

  • A compiler

There is a difference in writing C program for exe and DLL:

  • How you call your code?

1) In exe there must be a main() function:

The main function usually contains functions that either call external functions from the DLL or do internal stuff

2) In DLL its a different story and this happens:

2.1) A loader reads DLL from disk

2.2) Reserve some space in target process (exe)

2.3) Then calls DLL function called "Dllmain" which initialize the library

2.4) Loader hands over the control back to the process (exe)

2.5) Process then can call the functions from the loaded DLL

When you implement the malware as a DLL, you need to implement a Dllmain and export atleast one function that can be called externally

Now, lets run our generated exe:

Lets open Process Hacker and start looking around the current running process:

We can see alot of information here about the current process

Lets go to modules which have the loaded DLLs:

These are standard DLLs that gets loaded by default on every process so nothing special here

Lets check the memory tab which has the process layout in memory:

Here we can see the process RX (Read only and Execute) which holds read only and executable code

Here is the code in memory:

Let's check out the source code of the DLL:

Dllmain can be called for different situations, for example:

  • When loader loads DLL into a process

  • When loader unloads DLL into a process

This also applies on threads and we handle these cases using a switch which allows to implement different behavious on specific event, for example:

  • If DLL is being loaded for a process, the case will be DLL_PROCESS_ATTACH, and its up to the developer to decide what happens when this event occurs

Also, there is a function called "RunME()" which is being exported as an external function and can be called by an external function written in the calling process (exe)

Let's compile the DLL and run it using rundll32 and specifying the function we want to call:

We can now check it out in Process Hacker:

Last updated