GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing www.retroreversing.com — Windows Executables (NE, LE and PE Files) - Retro Reversing (Reverse Engineering)
Windows Executables (NE, LE and PE Files)Edit on Github | Updated: 10th November 2026This page provides a comprehensive guide to reverse engineering Windows executable files, focusing on the evolution from classic New Executable (NE) and Linear Executable (LE) formats to the modern Portable Executable (PE) format used in all current Windows systems. Whether you are interested in reverse engineering, game modding, or simply curious about how Windows programs work under the hood, you’ll find practical information about:
By the end of this guide, you’ll have a solid foundation for exploring and dissecting Windows executables, with resources and examples tailored for retro game reverse engineering and technical analysis. Reverse Engineering Windows ExecutablesThis section focuses on the core information that you need to get started reversing a windows game or other windows software. How to dump a Windows (PE) executable?Dumping a Portable Executable (PE) file refers to extracting information from the file, such as its headers, sections, and other metadata. This process is often used for debugging and analysis. You can dump a PE file from the command line using either Dumpbin or objdump. Dumpbin (Microsoft SDK): If you have the Microsoft Visual Studio Development Tools installed, you can use the dumpbin utility to display information about a PE file. Open a Command Prompt and run the following command: objdump (GNU Binutils): If you’re using a Unix-like environment, the objdump tool from the GNU Binutils can be used to examine PE files. Run the following command: How to check for interesting dataWindows executables can sometimes contain hidden or unexpected data embedded within them. This can include debug symbols, developer notes, secret messages, copyright strings, easter eggs, or artifacts from the build process. This data can be extremely valuable for reverse engineering and game hacking as it can give clues as to what each function does or even what its original name might have been. Checking for Plain Text StringsThe simplest way to find hidden text is by scanning for printable ASCII or Unicode strings. This can reveal embedded messages, URLs, error messages, or even references to tools and libraries used during development. This command will print out all printable strings found in the binary to the text file, you can then open it to do a brief skip for any interesting looking strings. Checking for embedded filesExecutables can also contain other files embedded inside them such as images, archives or even other executables, you can check with the binwalk command: If you did find data then you can extract with Checking for overlaysAn overlay is data appended to the end of the executable, this command returns true if there is an overlay: Checking for Debug Data in PE executablesThe executable may have been built with debug information includes, one way to check is to use the rabin2 command like so: The output looks like this: Note that just because stripped is false or linenum/lsyms is true does not mean you have access to the information, it may have been put in a external .pdb file which will likely not have been included with the game. Note that if its not stripped and the dbg_file is a blank string then there is a good chance the debug symcols are embedded inside the executable in a section, see the CodeView section of this page. Here is what each of these fields means and how rabin2 got the value:
For more information on Debug Data inside PE executables please see the section below. Rich Header - Metadata on what tools were used to build the executableExecutables produced by Microsoft toolchains (e.g Visual Studio) contain a hidden structure called the Rich Header, located between the DOS stub and the PE signature. What is in the Rich Header?Each entry in the Rich Header corresponds to a specific tool (compiler, assembler, resource converter, linker, etc.) that emitted one or more objects during the build.
Together, these entries form a fingerprint of the binary’s compilation lineage, can be used for compiler version identification which is very useful for decompilation projects which are aiming for an exact match when re-compiling.
How do I extract the Rich Header Information?You can use richprint an open source tool by dishather that you can find here: dishather/richprint: Print compiler information stored in Rich Header of PE executables. You can also use rabin2/radare2 to get the information, and even export as JSON like so: You will get output like: So from the above we can see that there were 17 .cpp source files compiled with Visual Studio 6.0 that made up the final executable. Not quite sure what Utc stands for, its possible an internal codename such as Universal Tool Compiler but this is not confirmed, the 12 is the Microsoft C Version number (_MSC_VER) which maps to Visual Studio 6.0 the 12th release of Microsoft C. Windows Executable File Formats (NE, LE and PE)Over the years there was a number of different file formats for storing executable programs, luckily unless you are dealing with Windows 3.1 games you can safely ignore them all apart from the most recent Portable Executable (PE) file format. The Executable file formats for Windows are:
Since the only time you will encounter LE executables is in DOS Extenders, we will not take a deep dive into the format here, but it was based on the original NE format. If you are reversing a Windows PC game (not DOS) then the format you need to know about is the Portable Executable (PE) format. MZ Executable Header - Common to all Windows executable formatsAll DOS and Windows executables start with an MZ header, named after Mark Zbikowski, who designed the format for MS-DOS. Every NE, LE, and PE file also begins with an MZ header and a DOS stub program (usually printing “This program cannot be run in DOS mode”), followed by a pointer to the next header which will say what the rest of the exe format will be such as NE or PE.
Since the MZ format is for DOS and not Windows in will not be covered in this page. This structure is known as IMAGE_DOS_HEADER in Microsoft’s For a deep dive into the MZ header and the DOS stub check out 0xRick’s excellent page: A dive into the PE file format - DOS Header, DOS Stub and Rich Header - 0xRick’s Blog New Executable Format (NE) - Windows 1.0 to Windows 3.1The New Executable (NE) format was introduced with 16-bit Windows (starting from Windows 1.0 and 2.0) and OS/2 1.x. It extended the earlier MZ DOS format to support multiple code and data segments, dynamic linking, and relocations suitable for protected-mode environments. How many windows games use the New Executable format (NE)?Only 16-bit games from Windows 3.x that were not DOS executables (MZ format), so it is likely maybe just a couple thousand games, MobyGames lists about 2,236 titles on the the List of all Windows 16-bit games - MobyGames page. Some example games that use the NE executable format are:
Although a small subset of Windows 3.1x games were actually using PE format instead, so not all games on that list will be NE format but the vast majority will be. There are about 1,429 unique executables in the New Executable (NE) format in the eXoWin3x Project project so if you are interested in taking a look at the format that is a greak place to start: . How to extract information for NE executable?You will notice that many reverse engineering tools don’t have good support for NE format executables, they may load them but the analysis is very weak and often incorrect. Some tools such as cvdump.exe will refuse to work with such an old format: Other tools like dumpbin.exe will think its a MS DOS executable and refer you to EXEHDR: Are there embedded debug symbols?In NE format executables, there are typically no symbols in the traditional debugging sense. NE executables don’t have a built-in debug symbol format like modern PE files (which can contain PDB references or COFF symbols). If you needed debug symbols for 16-bit Windows development, they were stored separately in a .SYM or .MAP file. However all is not lost there are some exported functions inside the executable including both the name and module description. These map function names to ordinal numbers, which then map to entry points via the Entry Table Although local variables, function parameters, and internal function names are not stored in the executable. You can view any exported functions using the rabin2 command: In the game Tetris for windows it prints this: So you can at least see the procedures such as TETRIS, ADDHIGHSCOREPROC, HIGHSCOREDLGPROC etc NE Executable HeaderAn NE file still starts with an MZ header and DOS stub, followed by a pointer to the NE header. There is a lot of interesting metadata that you can use to learn about your executable in the header, such as the version of the linker used to produce it, the entry point for knowing where to start disassembling and all the offsets to the various interesting parts of the executable. Most offsets in the table below are from the “NE” header as the DOS stub could be of variable size, but some are offsets relative to the start of the file so be careful.
Here is the a C structure for the New Executable header from the MinGW version of winnt.h (Under GPL license): File: winnt.h - IMAGE_OS2_HEADER Portable Executable - Windows NT3.1+ - The modern executableYou can find the structure of the PE file format in the C Header file called The following is the Portable Executable header structure from the MinGW version of winnt.h (Under GPL license): You can also find out more about the Portable Executable format on the official Windows SDK Documentation site: PE Format - Win32 apps DOS CompatibilityIn the past, many classic video games were developed for and played on DOS-based PCs. With the introduction of the Windows operating system, many DOS games continued to run using compatibility features provided by Windows. Since both DOS and Windows executables used the .EXE file extension, users would inevitabling get confused by trying to run a Windows executable on DOS. So the Windows executable format even to this very day still has a small DOS executable at the top to tell users that they need windows to run the executable. This would start a long line of backwards compatibility features built into the various windows executable formats that have evolved over the years. What are Relative Virtual Addresses (RVAs)?RVA stands for “Relative Virtual Address”. It is a term commonly used in the context of Windows Portable Executable (PE) files and refers to the address of a particular location within the virtual address space of a program or a module. RVAs are used to express positions or offsets relative to the base address of a module (executable or DLL) rather than as an absolute memory address. RVA helps programs find things in their memory without needing to know exactly where everything is stored in memory. It’s like a helpful set of directions. RVA is a fundamental concept in Windows programming, as it allows for position-independent code and the ability to load modules at different base addresses in memory, enhancing the compatibility and flexibility of Windows applications. CodeView Debugging Symbols (1985-2025+)The Microsoft CodeView Debugger stores its debug symbols in different places (and formats) depending on the version of Microsoft Visual C was used, if you are lucky enough to find a windows game that has debug symbols it is possible that they are in a CodeView format. Depending on the age of the game (what version of Visual Studio was used) the debug symbols could either be stored embedded inside the executable itself or in a separate .pdb file. You can find a table of the rough time frame when you can find each version of CodeView Debug symbols:
If the executable is pre-1995 e.g Microsoft C 6.0 and compiled with debug mode on then it is likely to contain debug symbols directly inside the executable in the .rdata section of the exe file. If the executable was built using Visual C++ 4.x to 6.0 the symbols could be either inside the executable or as a separate .PDB file, both using the same CodeView 4.x record format ( It all depended on the compile switch used for building the executable:
For example the game Mike Stewart’s Pro Bodyboarding from 1999 was compiled with the Inline CodeView information. However opening it in Ghidra or radare they are unable to do anything with this information so its very easy to miss if you don’t know where to look. It if very common to just rely on reversing tools like Ghidra to look for debug symbols and presume they are not there if it doesn’t find them, but this can miss vital information. Checking for embedded CodeView symbols in an executableThe easiest way for a quick check if you have any embedded debug symbols is just to run the strings command over the executable and look for any strings that look like mangled function names e.g If this is the case then we just need a way to extract the information, as just running strings will miss out vital information such as how to link the function name to the actual function in assembly code and other debugging information such as line number to assembly mapping. If you a copy of dumpbin.exe from a version of Visual Studio you can run the following in either wine or windows: You will get a bunch of headers printed out, look for the You can see that this executable has debug directories in the NB11 format! However dumpbin.exe does not emit the CodeView blob as binary and will not decode the NBxx format records. It can help you locate them, but you need to read the bytes yourself. First of all the file pointer to CV data is very useful, if you open the executable in a hex editor and jump to offset But there is an even easier way with microsoft-pdb/cvdump/cvdump.exe you can give your executable directly to cvdump and it will tell you what all the debug information means. Embedded CodeView 4.x symbolsThe CVTRES 5.x linker (Visual Studio 6.0) often embedded CodeView 4 format directly into . You can find these blocks of data by looking for the “CV” string in a hex editor, for CodeView 4 it would then be followed by the version number Also Table of the subtypes:
You can find out more here: DebugInfo.com - Matching debug information Windows Object File Formats - The foundation of executables and librariesBefore an executable file ( What is an Object file?An object file is an intermediate binary that contains machine code, data, relocation entries, and symbol information - but it is not yet executable. In order to make it executable it needs to be linked together with the other compiled translation units (objects) to become a single executable or library, this is what a linker does. Why care about Object file formats?So you might wonder why you should care about the object file formats, as after all it is unlikely that the developers would distribute their intermediate .obj files along with a retail game, and that is true. The reason is simple, executable formats are based on the object file format, for example the Portable Executable (PE) format was essentially built as an extension of the COFF object format. So to understand the executable formats you really need to understant the formats they are based on, this gives the added benefit of when you decide to do a full decompilation you understand how all the object files link together in the executable making it easier to re-compile into a near byte-accurate replica. What file format do Object files use?Object files follow a defined object format, which specifies how sections, symbols, and relocations are stored on disk. On Windows, several object formats have been used over time, reflecting the evolution of the platform and its toolchains:
Unless you are reverse engineering an early windows or DOS game, the format you will most likely encounter is COFF. Also a side note if you are compiling with GCC the intermedia object files are actually in ELF format and then when they are linked together they get converted to a COFF-based PE executable. COFF Object Files (1990s–present) - The foundation of PE executablesCommon Object File Format (COFF) is the object module format produced by Microsoft and LLVM toolchains on Windows before linking into a PE image. The Portable Executable (PE) and Common Object File Format (COFF) are directly related - the PE format is essentially an extension of COFF. Microsoft built PE on top of COFF to support Windows’ runtime loader while keeping compatibility with existing compiler and linker infrastructure. What is in a COFF .obj?A COFF object contains the following data:
For more information check out the official specification: PE Format - Win32 apps Sections in COFF .obj filesSection names and purposes are similar to PE images, but .obj sections are not yet assigned final RVAs and can include many small, tool-generated sections. Typical examples:
Section flags in the header (e.g. COFF symbol table and auxiliary recordsEvery .obj has a COFF symbol table describing external names, section definitions, functions, and compiler artifacts. This is information required to link all the objects together, and final executables only include a COFF symbol table if linked with | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |