Table of Contents
This is a tutorial to program a PE packer : we will learn about the PE file format, headers and the inner workings of loading and packing binaries.
Introduction
A packer is a binary that transforms itself when running, from within its own memory. A common, well known packer is UPX: it zips a binary into a smaller one. When the packed binary is executed, it unzip itself and runs the original code.
Packing has generaly 3 main usage:
- Reduce a exe file size (like UPX does). This is a legitimate and actually common usage.
- Obfuscate the code: make it harder to reverse engineer, to protect proprietary software.
- Hide malicious code, to avoid detection by an antivirus software for example.
In this tutorial we are going to write a very simple packer to demonstrate how it works, and some very basic obfuscations techniques.
Learning objectives / Requirements
Doing this exercise, you will learn:
- The PE file format: All the important and necessary parts will be detailled.
- How Windows loads binaries in memory and executes them: we are going to write a loader in C, using the Win32 structures related to PE headers.
- PE file maniplation in python: the packing program will be programmed in python, using the library lief.
The packer can be written eiher on Linux or Windows, but needless to say the final binary should be run on Windows (it is a Windows .exe
file after all …). This tutorial will be using only Windows, Linux users should have no dificulty to adapt.
Here is what you should already know before proceeding through this tutorial:
- C programming
- Some python programming: nothing fancy here, we’re going to use a library to handle almost everything.
- Basic x86 assembly: while not absolutely necessary (no asm code will be written), some debugging might be usefull.
You should have installed on your system:
- A C compiler, we’re going for Mingw32: here for windows. I highly recommand adding it to your PATH.
- Python, we’ll be using version 3.
- CFF explorer, a PE header viewer (for Windows), which can be found here (it’s called “Explorer Suite”)
- A Windows debugger, my favorite being x64dbg
General objective
We’re going to write a basic packer that works as follow:
- A PE File will be copied as-is (at first) in a custom section.
- The unpacker will load this PE in memory and jump on it.
This very simple packer will work as a basis for further enhancemens, like encryption, obfuscation, etc … But making it work will require to wollow the same steps a more complex one would require.
We’ll start by writing a loader: a program that loads another one in its own memory.
Then, with some changes, we’ll make a first version of the packer, using Python.
After that, as an exercie, we will handle the case where the packed binary cannot be moved.
And finally, we’ll have some fun with basic obfuscation.
Table of content
- Part 1: load a PE in memory
- Part 2: imports and relocations
- Part 3: packing with python
- Part 4: packing with no relocations
- Part 5: simple obfuscation
TL;DR
The final code can be found here :
https://github.com/jeremybeaume/packer-tutorial