NE-Executable | Segmented EXE Format New executable
The NE (fully “New executable”) is a 16-bit executable file format was designed by Microsoft for 16-bit Windows 1.x - Windows 3.x, Windows 9x, OS/2 1.x, multitasking MS-DOS 4.0 and the OS/2 sunset of Windows NT up to version 5.0 (Windows 2000).
This Segmented EXE format provides support for:
- Segmented memory model;
- Protected Mode (I286+) operation;
- Dynamic linking;
- Resource management;
- Shared code between programs.
Overview
NE segmented program or library always starts like MZ-Executable.
Means image has MZ
header structure. Last field in structure - e_lfanew
is a pointer to next NE
header structure.
The NE header is an important detail which describes the entire subsequent structure of the image. An NE segmented executable typically contains about 7 tables (or unsafe structures) and segments which contain program’s code.
| DOS stub |
+---------------------+
relative offset | ... |
[1,24,6...]<------+ Module references |
+-----+ Importing names | relative offset
relative offset | Entry Table +------------> [#1{...}][#2{...}...]
[...]<--------+ | Resident names +-------+
| Not resident names +----+ | relative offset
+-----------+ Segments Table | | +-----> [...]
| | Per-segment fixups | | absolute offset
| | Resources table | +--------> [...]
| ... |
+------+--------------------+ |
| #1 .CODE 0xBABE no_relocs | |
| #2 .CODE 0xFEED +------>[#2 fixups table]
| ... | |
+-------------+-------------+ |
|| | |
|| | |
|+--->+---------------------+
| | #1 .CODE bytes |
+---->+---------------------+
| #2 .CODE bytes |
| ... |
+---------------------+
| Resource #1 |
| Resource #2 |
| Resource #3 |
| ...
EOF
NE Header
The NE header is a packed structure. Starts with ASCII fixed string
[E, N]
(little endian reinterpretation) or [N, E]
(big endian reinterpretation). This is a main sign which indicates that the following values describe 16-bit Windows or OS/2 program.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Pod, Zeroable)]
#[repr(C)]
pub struct NeHeader {
pub e_magic: [u8; 2],
pub e_ver: u8, // LINK.EXE major version
pub e_rev: u8, // LINK.EXE minor version
pub e_enttab: u16,
pub e_cbent: u16, // Count of entry bundles
pub e_crc: u32,
pub e_flags: u16, // [program_flags][app_flags]
pub e_autodata: u16, // automatic DS (data segment) index
pub e_heap: u16, // Initial heap size
pub e_stack: u16, // Initial stack size
pub e_cs_ip: u32, // CS:IP
pub e_ss_sp: u32, // SS:SP
pub e_cbseg: u16, // Count of segments
pub e_cbmod: u16, // Count of module references
pub e_cbnres: u16, // Size of Nonresident names table
pub e_segtab: u16,
pub e_cbres: u16,
pub e_resntab: u16, // Resident names table
pub e_modtab: u16, // Module references table
pub e_imptab: u16, // Importing module names
pub e_nrestab: u32, // Non-Resident names table (raw offset)
pub e_cbentmov: u16, // Count of moveable entries
pub e_align: u16, // Sector shift. (0 means 512)
pub e_restab: u16, // Resources table
pub e_os: u8, // Target OS
// **OS/2 part** of header. (checks by IBM OS/2 Win-OS/2 module)
pub e_flagothers: u8, // OS/2 flags for loader (e.g. HPFS/FAT naming)
pub e_pretthunk: u16, // Return Thunk offset
pub e_thunk: u16, // Segment reference thunk offset
pub e_swap: u16, // minimum code swap
pub e_expver: [u8; 2],// Expected Windows version!
// (little endian reinterpretation!)
}
NE Header has fields-masks which tells more about exploring binary image.
NE Header | LINK.EXE
Depending on the version of Microsoft Link, the processed file may have minor changes in NE segmentation format. That’s why images linked by LINK.EXE 4.x
are have wrong reinterpretation of EntryTable LINK.EXE 5.10
instead
NE Header | e_flags
The e_flags
field has 2 categories. Program and Application flags.
Program flags are a common module description which stores CPU, module type, flags.
//
// In 16-bit DOS/Windows terminology, DGROUP is a segment class that referring
// to segments that are used for data.
//
// Win16 used segmentation to permit a DLL or program to have multiple
// instances along with an instance handle and manage multiple data
// segments. This allowed one NOTEPAD.EXE code segment to execute
// multiple instances of the notepad application.
//
enum FlagWord {
// how is data handled?
NOAUTODATA = 0x0000,
SINGLEDATA = 0x0001, // shared among instances of the same program
MULTIPLEDATA = 0x0002, // separate for each instance of the same program
// additional flags:
LINKERROR = 0x2000, // Linker error, module can't be loaded
LIBMODULE = 0x8000, // if this flag is set, this is a DLL;
// see the "Dynamic Libraries" section below
};
#define GLOBINIT 1 << 2 // global initialization
#define PMODEONLY 1 << 3 // Protected mode only
#define I8086 1 << 4 // 8086 instructions
#define I286 1 << 5 // 80286 instructions
#define I386 1 << 6 // 80386 instructions
#define I8087 1 << 7 // 80x87 (FPU) instructions
Application flags tells a program’s window behavoiur. Windows 3.x and Win-OS/2 uses this flags for running module
// Application flags
//
// I suggest, Win-OS/2 or Windows 3.x uses this
// information, so application flags tells how to work Windows
// OR OS/2 Presentation Manager. (shorten P.M.)
//
enum apptype {
none,
fullscreeen, // fullscreen (not aware of Windows/P.M. API)
winpmcompat, // compatible with Windows/P.M. API
winpmuses // uses Windows/P.M. API
};
More information has Oracle VirtualBox driver for various operating systems. Oracle holds a C/++ sources of NE Header declaration
NE Header | e_os
Value that e_os
holds is optional, because not all binaries
was compiled for the IBM OS/2 environment.
In old Windows 1.x executables e_os
flag is zeroed what means 2 things:
- Target OS is unknown;
- Any OS supported (don’t think about unix).
Fonts compiled as NE executables have zeroed target os flag too.
enum targetos {
Unknown = 0x00, // Any OS or unknown
OS2 = 0x01, // IBM OS/2
Win16 = 0x02, // Windows/286
Dos4 = 0x03, // European DOS 4.x
Win32s = 0x04, // Windows/386
Boss = 0x05 // Borland OS service
}
Other structures?
Other structures will be in next pages, for each structure will be placed per one page. In future this region may contain links to other pages