Android / iOS




Posted: December 2006
Updated: October 20, 2015

The PE File Format

PE is the file format used by Microsoft Windows EXE, DLL, OCX, and other files. If you have a Windows EXE or DLL or such it is in the PE format. I wrote print_pe to pull out some header information from a PE file. It will show you all kinds of important information including imported and export functions.

This program will also dump all DOS code segments and Windows executable segments. Resource segments will also be dumped, but the filename is chosen in a bad way (not by resource id.. my fault). This will be fixed in the future. Just a warning for people using this program to rip .ico images out of an executable file: .ico files are not saved in the resource section like you would think. ICO files (normally) are basically bitmaps wrapped in .ico headers along with the height being double what it should be (good job on really making things messy Microsoft). Anyway, it appears in the resource file (unless I did something wrong) that the .ico file that comes out is the .ico file as it was with the ico headers ripped out. Nice. Still my biggest issue with this file format are the "offset" fields. Offset from where? From the begining of the file? From the begining of the section? From the virtual or physical address? Very disorganized.

Related Projects

File Parsers: print_pe, magic_elf, dump_fat, amiga_recovery, dump_d64

Key Features (from the version below)

  • Ability to rip out dos exe code
  • Ability to rip out windows exe code
  • Ability to rip out resource files (.ico,.bmp,etc)
  • Ability to output version info from resource sections
  • Ability to output some COM info including CLSID's
  • Ability to output debug file info
  • View imported symbols
  • View exported symbols
  • Added a -modify option to modify exported functions. Read below for more info

Future Possible Features

  • Ability to turn .pdb files back into full source
  • Ability to change CLSID's of COM objects to regain compatibility
  • View all methods of each COM class

If anyone is interested in studying the PE file format, I got most of my information from this page:

How To Use

This is a command line tool, so simply open up your favorite console terminal program (or if you're on windows, use the DOS/Command prompt or MSYS) and type:

./print_pe whatever.exe

Where whatever.exe is the name of your executable or dll that you want to analyze. It would probably be a good idea to pipe the output into more, like so:

./print_pe whatever.exe | more

If you're still confused, take a look at my help page.

As of March 29, 2006, I added a -modify command line option. This gives print_pe the ability to modify an exported function so that in C it looks like this { return value; } where the value is whatever you want. So let's say you have a function called blah() in a DLL called testing.dll, if you wanted this function to do nothing except return the value 100, you can do:

./print_pe -modify blah 100 testing.dll

Note that none of the code that was previously in that function will execute. This is also experimental so if you try this, make sure you have a backup copy of your original DLL :).


GitHub: git clone


October 20, 2015 - Cleaned up source code. Started adding ability to dump .NET info. Hoping to have a disassembler for .NET soon.

June 14, 2007 - Cleaned up the resource parsing. Indented resource data and fixed a bug that could cause print_pe to hang.

May 17, 2007 - Added some more info to the resource section parsing. Anal_pe will now tell what kind of resource it is and if it's a FileInfo resource (Copyright info and stuff) it will print out. I must say once again, Microsoft never ceases to amaze me how hackish and not very well thought out their file formats and API's can end up being. This one is so bad that VB doesn't even follow the spec I found on their webpage. In the StringInfo section which actually holds the KEY:VALUE info, the length of the value part is stored as a word count (2 bytes). So if the KEY:VALUE was Name: Mike, the length of Mike in the file format would be 5 (Mike being actually 10 bytes since it's unicode and null terminated). VisualStudio 6 does this correctly, but VB6 would store the length of "Mike" to be 10. Once again, nice job on quality control Microsoft.

January 18, 2007 - LGPL'd code.

April 18, 2006 - Originally print_pe could only read CLSID's from .exe files. Devin Smith sent me a patch making it possible to get CLSID's from .ocx and .dll files also.

March 29, 2006 - Added the -modify command line option

Copyright 1997-2021 - Michael Kohn