New Executable
The New Executable (NE), also known as NewEXE, is a 16-bit segmented executable file format developed by Microsoft as an extension of the earlier MS-DOS MZ format, supporting executable files (.exe), dynamic-link libraries (.dll), and resource-only modules.[1] Introduced in 1985 alongside Windows 1.0, it enables dynamic linking, multiple code and data segments, and integrated resource storage for graphical elements like menus and icons, facilitating the creation of multitasking applications in protected-mode environments.[2][1] The NE format begins with a standard MS-DOS 2.0-compatible stub header (identified by the "MZ" signature), followed by a pointer at offset 0x3C to the NE-specific header starting with the "NE" signature.[1] This header includes critical metadata such as the linker's version, entry point address, segment count, and minimum data allocation, along with tables for segments (defining attributes like movability and preloading), resources (categorized by type and name), module references, imported names, and resident name offsets.[1] Flags within the header specify operational modes, including real mode, protected mode, or support for OS/2 compatibility, while relocation records handle address fixes for loaded segments.[1] Historically, the NE format powered 16-bit Windows from versions 1.0 through 3.1 (1985–1992), as well as OS/2 1.x (1987–1991), and remained compatible in later systems like Windows 9x and NT via emulation layers such as WOW.[2] It addressed limitations of the flat MZ format by supporting up to 64K segments for code, data, and resources, enabling larger and more modular programs essential for the graphical user interfaces of early Windows.[3] However, its 16-bit architecture and segmentation model became outdated with the rise of 32-bit computing; it was largely supplanted by the Linear Executable (LE) format in OS/2 2.0 and Windows 3.1's protected-mode components, and fully replaced by the Portable Executable (PE) format starting with Windows NT 3.1 in 1993.[2][4] Key advantages of NE included built-in support for dynamic linking to shared libraries, reducing memory usage in multitasking scenarios, and a resource compiler integration that streamlined GUI development.[1] Despite its obsolescence, NE files persist in legacy software, particularly 16-bit games and utilities from the Windows 3.x era, with tools like disassemblers still available for analysis and preservation.[2]History
Development and Introduction
The New Executable (NE) format was created by Microsoft in 1984 as a successor to the DOS MZ executable format, specifically designed for use with MS-DOS and the early versions of Windows to enable advanced features such as dynamic linking of libraries and support for multitasking environments.[5] This development addressed limitations in the MZ format, which was constrained by the segmented memory model of 16-bit processors and lacked robust mechanisms for shared code and data across applications.[3] Key motivations for the NE format included leveraging the protected mode capabilities of the Intel 80286 processor to allow for better memory protection and larger address spaces, which were essential for implementing graphical user interface (GUI) elements in Windows applications.[3] By extending the MZ structure, NE incorporated support for segmented memory loading, resource tables for GUI components like icons and menus, and the ability to handle overlays and dynamic link libraries (DLLs), thereby facilitating more efficient multitasking and reducing memory overhead in resource-constrained systems.[3] These enhancements were critical for transitioning from simple command-line DOS programs to more sophisticated windowed applications. The NE format was formally introduced with the release of Windows 1.0 on November 20, 1985, marking the debut of Microsoft's first graphical operating environment, and it was also integrated into MS-DOS versions 3.2 and 3.3 to provide compatibility and execution support for Windows executables on the base DOS platform.[6] Its design drew influences from the concurrent collaboration between Microsoft and IBM on OS/2, initiated in June 1985, which emphasized protected-mode multitasking and shared executable standards that would later be adopted in OS/2 1.0.[7][8]Adoption and Evolution
The New Executable (NE) format saw primary adoption as the standard for 16-bit applications across several early Microsoft and IBM operating systems. Introduced with Windows 1.0 in 1985, it became the native executable format for Windows versions up to 3.x through 1992, enabling protected-mode execution and dynamic linking for graphical applications. Similarly, OS/2 1.x from 1987 to 1991 utilized NE as its core format for 16-bit executables, supporting multitasking and compatibility with Windows binaries via subsystems like Win-OS/2. Windows NT 3.1, released in 1993, retained NE support specifically for 16-bit Windows and OS/2 applications through its Windows on Windows (WOW) layer, ensuring backward compatibility for legacy software on the new 32-bit platform.[2][3][9] NE's evolution involved incremental refinements tied to linker versions and operating system needs, with early implementations providing basic segment-based loading in Windows 1.0. By 1986, multitasking MS-DOS 4.0 incorporated NE support alongside MZ executables, adding preemptive multitasking capabilities for NE files to enable concurrent execution in a DOS environment. In OS/2, the format incorporated enhanced resource handling and module management for more complex 16-bit applications. These updates focused on improving memory management and interoperability, with NE files featuring a version field in the header to indicate compatibility levels across platforms.[2][3][10] Later extensions to NE accommodated hybrid 16/32-bit environments, particularly in Windows 9x series (1995–2000), where it supported 16-bit components within a predominantly 32-bit architecture. Through segment tables and dynamic linking, NE allowed seamless integration of legacy 16-bit code with 32-bit Portable Executable (PE) modules, such as in VxD drivers and WOW execution for older Windows applications. This hybrid capability extended NE's utility in transitional systems like Windows 95 and 98, bridging DOS-era software with emerging 32-bit features.[2][11] NE's decline began with the widespread adoption of the PE format in Windows 95 (1995), which offered better 32-bit support and supplanted NE for new development, relegating it to legacy 16-bit compatibility. Despite this shift, Windows 2000 maintained NE support through WOW and OS/2 subsystems until version 5.0, allowing execution of older executables in a protected environment. By the early 2000s, NE phased out entirely in favor of PE, though its influence persisted in emulation tools and historical analysis.[2][3]File Format
Overall Structure
The New Executable (NE) format functions as a container for 16-bit executable files, extending the DOS MZ executable format to support advanced features in graphical and multitasking operating systems. It commences with a standard DOS MZ header, ensuring compatibility with DOS loaders, followed immediately by the NE-specific structures beginning with the "NE" signature. This design allows NE files to be executed under DOS while providing the necessary metadata for protected-mode environments.[1] The overall layout includes several key components that organize the file's contents and dependencies: the NE header, which contains essential file attributes and offsets to subsequent tables; the segment table, detailing the locations and properties of code and data segments; the resource table, holding embedded assets like bitmaps and dialog templates; the entry table, specifying resident entry points for procedures; the module reference table, listing external modules; the import names table, defining imported names and ordinals; and relocation data, used for runtime address adjustments. These elements collectively enable modular and relocatable code organization.[1][3] NE files are identified by common extensions including .exe for standalone executables, .dll for dynamic-link libraries, .fon for font resource files, and .drv for device drivers, reflecting their varied applications in 16-bit Windows systems.[12][5] At its core, the format leverages a segmented memory architecture, where code, data, and resources are divided into discrete segments designated as movable (dynamically allocatable) or preload (fixed at load time), optimizing memory usage and sharing in resource-constrained environments.[1][3] To detect an NE file, the loader examines the MZ header's e_lfanew field at offset 0x3C, which points to the offset of the "NE" signature, confirming the transition from the DOS-compatible prefix to the extended format.[1]NE Header
The New Executable (NE) header is a fixed 64-byte structure located immediately after the DOS stub, with its position indicated by the offset value at byte 0x3C in the MZ (DOS) header. This header encapsulates critical metadata about the executable, including versioning, memory allocation parameters, entry points, and pointers to subsequent tables within the file, enabling the loader to initialize and execute the program correctly.[3] The header commences with a two-byte signature "NE" (ASCII values 0x4E and 0x45) at offset 0x00, unequivocally identifying the file as adhering to the New Executable format. Immediately succeeding this are the one-byte major and minor linker version fields at offsets 0x02 and 0x03, respectively, which specify the version of the Microsoft linker tool employed during compilation; for instance, executables from Windows 1.0 typically feature a linker version of 0x01 (major 0, minor 1). These version indicators ensure compatibility assessments by the operating system loader.[3][13] Succeeding the versioning information, the header defines offsets and sizes for key internal structures, beginning with the two-byte entry table offset at 0x04 and its corresponding length in bytes at 0x06; the entry table enumerates the module's resident and movable entry points for dynamic linking. The segment count, a two-byte value at offset 0x1C, denotes the total number of logical segments in the executable, while the module reference count at offset 0x1E indicates the quantity of external modules (such as DLLs) the program depends on. Additionally, the two-byte resource table offset at 0x24 points to the location of the resource table relative to the start of the NE header, facilitating access to embedded resources like icons and menus.[3][13] A 32-bit checksum at offset 0x08 provides a cyclic redundancy check (CRC) over the entire file contents, aiding in file integrity validation during loading, though some tools like Borland's set this field to zero. The two-byte flag word at offset 0x0C encodes behavioral attributes via bit flags, including bit 0 for single data segment usage (indicating a unified code and data model), bit 1 for multiple data segments, bit 2 for no automatic data allocation, and bit 3 for protected mode API support, which signals the loader to utilize 80286 protected mode capabilities. The two-byte automatic data segment index at offset 0x0E references the default segment for runtime data allocation from the segment table (with index 0 denoting no automatic allocation if combined with specific flag settings). Initial heap and stack sizes, each two bytes at offsets 0x10 and 0x12, specify the byte allocations for the local heap and stack upon program startup, respectively, defaulting to zero if the stack segment differs from the data segment.[3][13] The 32-bit entry point at offset 0x14 stores the initial code segment index (from the segment table) and instruction pointer offset (CS:IP), marking the starting execution address. Correspondingly, the initial stack pointer at offset 0x18 provides the stack segment index and stack pointer offset (SS:SP), with special handling if the stack pointer is zero: the loader positions it at the top of the automatic data segment below the heap area. The two-byte field at offset 0x20 specifies the size in bytes of the non-resident names table.[3][14]Segment and Resource Tables
The segment table in a New Executable (NE) file consists of an array of fixed-length entries that define the layout and attributes of code and data segments within the file.[1][3] Each entry is 8 bytes long, with the table's location and number of entries specified in the NE header.[15] The first two bytes represent the file offset of the segment, shifted left by the file alignment shift count to obtain the actual byte offset.[1] The next two bytes indicate the segment's length in bytes, where a value of 0x0000 denotes 65,536 bytes.[3] Bytes 4-5 contain a flags word that specifies attributes such as the segment type (code or data), whether it is movable or fixed, preload status, and presence of relocation information; for example, bit 0 distinguishes code (0) from data (1), bit 2 indicates movability, bit 4 marks preload segments, and bit 6 flags segments with relocations.[15] The final two bytes specify the minimum allocation size for the segment in memory, again with 0x0000 meaning 65,536 bytes.[1] The resource table organizes non-executable data such as icons, menus, and dialogs in a hierarchical manner, allowing for grouped resources by type.[3] It begins with a 2-byte alignment shift count that determines how offsets and lengths are scaled.[15] The table then contains one or more resource type headers, each followed by resource entries; a header includes a 2-byte type ID (0x0000 to end the table, or predefined values like 1 for cursors, 2 for bitmaps, 3 for icons, 4 for menus, and 5 for dialogs), a 2-byte count of resources in the group, and reserved bytes.[1] Each resource entry is 12 bytes: the first two bytes give the file offset (shifted by the alignment count), followed by two bytes for length (also shifted), two bytes for flags (e.g., bit 4 for movable resources), and two bytes for the resource name or ID (high bit set indicates an ordinal, otherwise an offset to a string in the name table).[3] This structure enables the loader to map resources into memory separately from code and data segments.[15] The entry table specifies the program's entry points, distinguishing between fixed and movable segments to support dynamic loading.[1] It comprises bundles of entries, each starting with a 1-byte count of entries in the bundle (0x00 to end the table) and a 1-byte segment indicator (0xFF for movable segments).[3] For fixed segments, each entry is 3 bytes: a flag byte (e.g., bit 0 for exported entries) followed by a 2-byte offset within the segment.[15] Movable segment entries are 6 bytes: a flag byte, a 2-byte INT 3FH instruction for relocation patching (0xCD 0x3F), a 1-byte relative segment number, and a 2-byte offset.[1] These entries allow the loader to resolve the initial execution point and other function starts after segment relocation.[3] Relocation data corrects 16-bit addresses in segments to account for their loaded positions in memory, stored per-segment immediately after the segment data if the segment flags indicate relocations are present.[15] Each segment's relocation block begins with a 2-byte count of items, followed by 8-byte entries.[1] The first byte specifies the address type (1 for offset only, 2 for segment only, 3 for both), the second byte indicates the relocation type (0 for internal references, 1 for imported ordinals, 2 for imported names, with bit 7 possibly set for additive relocations).[3] Bytes 2-3 provide the offset within the segment, while bytes 4-7 vary by type: for internal, they include the target segment number and offset; for imports, a module index and either an ordinal or name table offset.[15] This mechanism supports both intra-module adjustments and inter-module references in the 16-bit segmented address space.[1] The module reference table and imported names table facilitate dynamic linking to external modules, such as DLLs.[3] The module table is an array of 2-byte entries, each an offset into the imported names table pointing to a module name.[15] The imported names table follows, consisting of variable-length Pascal-style strings: a 1-byte length followed by that many ASCII characters (not null-terminated), listing module names first, then procedure or type names used in import relocations.[1] These tables enable the loader to resolve references to external code during execution.[3]Compatibility
DOS Stub
The DOS stub in the New Executable (NE) format serves as a minimal MS-DOS executable embedded at the beginning of the file, ensuring that NE executables can be loaded by pure DOS systems while preventing unintended execution. If run under MS-DOS without a compatible loader such as Windows or OS/2, the stub executes a small program that displays an error message—typically "This program cannot be run in DOS mode."—and then terminates, informing the user that the file requires a graphical environment.[2][16] Structurally, the DOS stub forms a standard MZ executable header starting at the file's offset 0, with specific fields configured for NE compatibility: the e_lfarlc field at offset 0x18 is set to 0x40, indicating the location of the stub's relocation table, and the e_lfanew field at offset 0x3C points to the offset of the subsequent NE header. This setup allows DOS loaders to recognize and process the initial MZ portion without accessing the NE-specific data. The stub's code follows the 64-byte MZ header, consisting of assembly instructions to output the error message via DOS interrupts and exit gracefully.[16][2] In terms of size, the DOS stub is usually 64 bytes or more to accommodate the MZ header and basic code, though it can be minimized for compatibility while maintaining functionality; larger stubs may include additional features like custom messages but adhere to the same hybrid principles. This minimal design enables the NE file to masquerade as a valid MZ executable for DOS loaders, which load and run the stub instead of attempting to execute the protected-mode NE content, thereby providing backward compatibility during the transition to Windows environments.[2][16]Support in Later Systems
In 32-bit versions of Windows starting from Windows 95, Windows 98, and Windows NT 3.1 and later, New Executable (NE) files, which are 16-bit Windows applications, are executed through the Virtual DOS Machine (VDM) subsystem.[17] This mechanism provides a protected environment for running legacy 16-bit code alongside 32-bit applications, emulating the necessary 16-bit addressing and API calls without direct hardware access.[17] In Windows NT-based systems, this is specifically handled by NTVDM.exe, which isolates 16-bit processes to prevent system instability.[17] Native support for NE executables is absent in 64-bit versions of Windows, as the x64 architecture lacks the virtual 8086 mode required for 16-bit code execution in long mode.[18] Instead, running such files necessitates third-party emulation software, such as DOSBox for simpler DOS-stubbed NE programs or more specialized tools like OTVDM for full 16-bit Windows compatibility.[19] Resource extraction from NE files faces significant limitations in Windows Vista and subsequent versions, where the operating system ignores embedded resources like icons due to the inability to load 16-bit modules into 32-bit or 64-bit processes.[20] To access these resources, users must rely on dedicated extraction tools capable of parsing the NE format, such as OpenWatcom's Resource Editor or eXeScope.[21] OS/2 Warp and its successors provide partial support for NE executables through the Win-OS/2 compatibility subsystem, which allows execution of 16-bit Windows applications in a dedicated session.[22] This support leverages the shared NE format between early OS/2 and Windows but is handled via the LX loader for 32-bit contexts, and continues to be supported in modern OS/2 derivatives like ArcaOS.[23][24]Legacy and Successors
Relation to Portable Executable
The New Executable (NE) format served as the direct predecessor to the Portable Executable (PE) format, which Microsoft introduced with Windows NT 3.1 in 1993 to enable native 32-bit applications on the platform. This shift addressed limitations in the 16-bit NE design, particularly its reliance on segmented addressing suited to the Intel 80286 architecture, by adopting a more efficient structure for 32-bit protected-mode execution. Both formats share foundational concepts, including organized headers that describe file layout, relocation information, and support for dynamic-link libraries (DLLs) to facilitate code modularity and sharing across applications. NE divides code and data into segments with associated selectors for memory management, while PE maps these to sections in a flat 32-bit address space, eliminating the need for complex segment descriptors and enabling simpler relocation via relative virtual addresses (RVAs). DLL handling also evolved: NE uses per-segment fixups and entry tables for imports and exports, whereas PE consolidates this in dedicated sections like .idata and .edata for streamlined loading.[4] The transition from NE to PE occurred gradually, with Windows 95 (released in 1995) supporting both formats to maintain compatibility: NE for legacy 16-bit Windows 3.x applications running in a virtual DOS machine, and PE for new 32-bit Win32 programs.[2] Key differences further distinguished PE as a more robust successor; it builds on the Common Object File Format (COFF) for object modules, incorporates richer metadata such as debug directories and security attributes, and removes the mandatory DOS stub required in NE files—though PE often includes an optional MZ DOS stub for pre-Windows execution fallback.[4] In hybrid scenarios, some PE executables embed NE structures to accommodate 16-bit components, enabling transitional applications that mix 16-bit and 32-bit code during the era of format coexistence in Windows 9x systems.[2] This approach supported backward compatibility without fully migrating legacy elements, though PE's design ultimately phased out such necessities in favor of pure 32-bit (and later 64-bit) architectures.[4]Modern Usage and Tools
In contemporary computing as of 2025, the New Executable (NE) format persists primarily in retro computing and preservation efforts, where it enables the emulation and study of legacy Windows 3.x and OS/2 software. Enthusiast projects, such as the eXoWin3x archive, have preserved over 1,100 unique Windows 3.x games packaged in NE executables, prioritizing original media and playability to maintain historical accessibility on modern hardware. These initiatives rely on emulation to counteract the format's obsolescence, ensuring that software from the late 1980s and early 1990s remains runnable without native operating system support.[25][2] Several specialized tools facilitate the viewing, editing, and disassembly of NE files for analysis and modification. Tools such as Open Watcom Resource Editor allow extraction and viewing of resources within NE-formatted executables, including elements like icons and dialogs.[21] Disassembly is supported by tools like radare2, where commands such asrabin2 -s reveal exported functions and segment details in NE binaries, aiding reverse engineering tasks.[2]
Emulation environments are essential for executing NE applications on current hardware, bridging the gap left by the absence of native 16-bit support in 64-bit systems. DOSBox-X emulates DOS-based Windows 3.x environments, allowing NE executables to run with high fidelity, including mouse integration and video driver configurations for games and utilities. Similarly, PCem provides full hardware emulation of era-appropriate PCs, enabling the installation and operation of Windows 3.x and its NE software in simulated configurations like 386DX systems. Open-source loaders like Wine offer execution of 16-bit NE applications through its WoW64 mode; as of Wine 10.16 (October 2025), this includes explicit support for 16-bit apps in the new WoW64 mode, though full compatibility may require additional setup for legacy behaviors.[26][27][28]
NE files find niche applications in font handling and security research. Legacy .fon bitmap font files, which use the NE format, remain readable and installable in Windows 11, supporting applications that require fixed-pitch or low-resolution typography from older systems. In malware analysis, NE executables serve as samples for studying historical threats, where tools dissect their structures to understand evasion techniques in legacy code that may resurface in modern attacks. As of 2025, no new native OS support has emerged for NE files, confining their use to these specialized domains.[29][30][31]