en:docs:tk:formats:newexe

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
en:docs:tk:formats:newexe [2024/09/24 04:47] prokusheven:docs:tk:formats:newexe [2024/09/26 12:59] (current) prokushev
Line 1: Line 1:
 +====== New Executable file format ======
 +
 +New Executable (NE) file format used by set of operating system including OS/2, Windows, Multitasking MS-DOS 4 and set of DOS Extenders. It is designed to be store on disk and in-memory usage. In-disk format is same for all OSes, but In-memory usage is mostly specific for Windows systems.
 +
 ^ Offset ^ Size ^ Name ^ Description ^ ^ Offset ^ Size ^ Name ^ Description ^
 | 00h | WORD | ne_magic | Signature word NEMAGIC | | 00h | WORD | ne_magic | Signature word NEMAGIC |
- union { +| On-disk |||| 
- struct { +| 02h | BYTE ne_ver Version number of the linker | 
- BYTE   ne_ver; /Version number of the linker */ +| 03h | BYTEne_rev Revision number of the linker | 
- BYTE   ne_rev; /Revision number of the linker */ +| In-memory |||| 
- }; +| 02h | WORD count Usage count (ne_ver/ne_rev on disk) | 
- WORD  count; /Usage count (ne_ver/ne_rev on disk) */ +| 04h | WORD ne_enttab Entry Table file offset, relative to the beginning of the segmented EXE header | 
- }; +| On-disk |||| 
-    WORD  ne_enttab; /Entry Table file offset, relative to the beginning of +| 06h | WORD ne_cbenttab Number of bytes in the entry table | 
-    the segmented EXE header */ +| In-memory |||| 
- union { +| 06h | WORD next Selector to next module | 
- WORD  ne_cbenttab; /Number of bytes in the entry table */ +| On-disk |||| 
- WORD  next; /Selector to next module */ +| 08h | DWORD ne_crc 32-bit CRC of entire contents of file. These words are taken as 00 during the calculation | 
- }; +| In-memory ||||     
- union { +| 08h | WORD dgroup_entry Near ptr to segment entry for DGROUP | 
- DWORD            ne_crc; /* 32-bit CRC of entire contents of file. +| 0Ah | WORD fileinfo Near ptr to file info (OFSTRUCT) | 
-    These words are taken as 00 during the calculation */ +| 0Ch | WORD ne_flags Flag word | 
- struct { +| 0Eh | WORD ne_autodata Segment number of automatic data segment. This value is set to zero if SINGLEDATA and MULTIPLEDATA flag bits are clear, NOAUTODATA is indicated in the flags word. A Segment number is an index into the module's segment table. The first entry in the segment table is segment number 1 | 
- WORD dgroup_entry; /* Near ptr to segment entry for DGROUP */ +| 10h | WORD ne_heap Initial size, in bytes, of dynamic heap added to the data segment. This value is zero if no initial local heap is allocated | 
- WORD fileinfo; /* Near ptr to file info (OFSTRUCT)*/ +| 12h | WORD ne_stack Initial size, in bytes, of stack added to the data segment. This value is zero to indicate no initial stack allocation, or when SS is not equal to DS | 
- }; +| 14h | DWORD ne_csip Segment number:offset of CS:IP | 
- }; +| 18h | DWORD ne_sssp Segment number:offset of SS:SP \\ If SS equals the automatic data segment and SP equals zero, the stack pointer is set to the top of the automatic data segment just below the additional heap area. \\ +--------------------------+\\ ! additional dynamic heap  !\\ +--------------------------+ <- SP\\ !    additional stack      !\\ +--------------------------+\\ ! loaded auto data segment !%\\ +--------------------------+ <- DS, SS | 
-    WORD  ne_flags; /Flag word */ +| 1Ch | WORD ne_cseg Number of entries in the Segment Table | 
-    WORD  ne_autodata; /Segment number of automatic data segment. +| 1Eh | WORD ne_cmod Number of entries in the Module Reference Table | 
-    This value is set to zero if SINGLEDATA and +| 20h | WORD ne_cbnrestab Number of bytes in the Non-Resident Name Table | 
-    MULTIPLEDATA flag bits are clear, NOAUTODATA is +| 22h | WORD ne_segtab Segment Table file offset, relative to the beginning of the segmented EXE header | 
-    indicated in the flags word. +| 24h | WORD ne_rsrctab Resource Table file offset, relative to the beginning of the segmented EXE header | 
- +| 26h | WORD ne_restab Resident Name Table file offset, relative to the beginning of the segmented EXE header | 
-    A Segment number is an index into the module's segment +| 28h | WORD ne_modtab Module Reference Table file offset, relative to the beginning of the segmented EXE header | 
-    table. The first entry in the segment table is segment +| 2Ah | WORD ne_imptab Imported Names Table file offset, relative to the beginning of the segmented EXE header | 
-    number 1 */ +| 2Ch | DWORD ne_nrestab Non-Resident Name Table offset, relative to the beginning of the file | 
-    WORD  ne_heap; /Initial size, in bytes, of dynamic heap added to the +| 30h | WORD ne_cmovent Number of movable entries in the Entry Table | 
-    data segment. This value is zero if no initial local +| 32h | WORD ne_align Logical sector alignment shift count, log(base 2) of the segment sector size (default 9) | 
-    heap is allocated */ +| 34h | WORD ne_cres Number of resource entries | 
-    WORD  ne_stack; /Initial size, in bytes, of stack added to the data +| 36h | BYTE ne_exetyp Executable type, used by loader. 02h = WINDOWS | 
-    segment. This value is zero to indicate no initial +| 37h | BYTE ne_flagsothers Operating system flags | 
-    stack allocation, or when SS is not equal to DS */ +| 38h | WORD | ??? | offset to return thunks or start of gangload area | 
-    DWORD            ne_csip; /* Segment number:offset of CS:IP */ +| 3Ah | WORD | ??? | offset to segment reference thunks or length of gangload area | 
- DWORD            ne_sssp; /* Segment number:offset of SS:SP+| 3Ch | WORD | ??? | minimum code swap area size | 
-    If SS equals the automatic data segment and SP equals +| 3Eh | 2 BYTEs | ??? | expected Windows version (minor version first) |
-    zero, the stack pointer is set to the top of the +
-    automatic data segment just below the additional heap +
-    area. +
- +
-    +--------------------------+ +
-    additional dynamic heap  +
-    +--------------------------+ <- SP +
-       additional stack      +
-    +--------------------------+ +
-    loaded auto data segment +
-    +--------------------------+ <- DS, SS */ +
-    WORD  ne_cseg; /Number of entries in the Segment Table */ +
-    WORD  ne_cmod; /Number of entries in the Module Reference Table */ +
-    WORD  ne_cbnrestab; /Number of bytes in the Non-Resident Name Table */ +
-    WORD  ne_segtab; /Segment Table file offset, relative to the beginning +
-    of the segmented EXE header */ +
-    WORD  ne_rsrctab; /Resource Table file offset, relative to the beginning +
-    of the segmented EXE header */ +
- WORD  ne_restab; /Resident Name Table file offset, relative to the +
-    beginning of the segmented EXE header */ +
-    WORD  ne_modtab; /Module Reference Table file offset, relative to the +
-    beginning of the segmented EXE header */ +
-    WORD  ne_imptab; /Imported Names Table file offset, relative to the +
-    beginning of the segmented EXE header */ +
-    DWORD ne_nrestab; /Non-Resident Name Table offset, relative to the +
-    beginning of the file */ +
-    WORD ne_cmovent; /Number of movable entries in the Entry Table */ +
-    WORD ne_align; /Logical sector alignment shift count, log(base 2) of +
-    the segment sector size (default 9) */ +
-    WORD ne_cres; /Number of resource entries */ +
-    BYTE ne_exetyp; /Executable type, used by loader. +
-    02h = WINDOWS */ +
-    BYTE ne_flagsothers; /Operating system flags */ +
-    char ne_res[NERESBYTES]; /* Reserved */  +
-};+
  
 On-disk segment entry On-disk segment entry
Line 107: Line 76:
 }; };
  
-struct new_rlcinfo { +Relocation table header
-    WORD  nr_nreloc; +
-};+
  
-struct new_rlc { +^ Offset ^ Size ^ Name ^ Description ^ 
-    char            nr_stype; +| 00h | WORD | nr_nreloc | ??? |
-    char            nr_flags; +
-    WORD  nr_soff; +
-    union { +
-        struct { +
-            char            nr_segno; +
-            char            nr_res; +
-            WORD  nr_entry; +
-          } nr_intref; +
-        struct { +
-            WORD  nr_mod; +
-            WORD  nr_proc; +
-          } nr_import; +
-        struct { +
-            WORD  nr_ostype; +
-            WORD  nr_osres; +
-          } nr_osfix; +
-      } nr_union; +
-};+
  
-#define NR_STYPE(x)     (x).nr_stype +Relocation table entry
-#define NR_FLAGS(x)     (x).nr_flags +
-#define NR_SOFF(x)      (x).nr_soff +
-#define NR_SEGNO(x)     (x).nr_union.nr_intref.nr_segno +
-#define NR_RES(x)       (x).nr_union.nr_intref.nr_res +
-#define NR_ENTRY(x)     (x).nr_union.nr_intref.nr_entry +
-#define NR_MOD(x)       (x).nr_union.nr_import.nr_mod +
-#define NR_PROC(x)      (x).nr_union.nr_import.nr_proc +
-#define NR_OSTYPE(x)    (x).nr_union.nr_osfix.nr_ostype +
-#define NR_OSRES(x)     (x).nr_union.nr_osfix.nr_osres+
  
-#define NRSTYP      0x0f +^ Offset ^ Size ^ Name ^ Description ^ 
-#define NRSBYT      0x00 +| 00h | char | nr_stype | ??? | 
-#define NRSSEG      0x02 +| 01h | char | nr_flags | ??? | 
-#define NRSPTR      0x03 +| 02h | WORD | nr_soff | ??? | 
-#define NRSOFF      0x05 +| Internal fixup |||| 
-#define NRPTR48     0x06 +| 04h | char | nr_segno | ??? | 
-#define NROFF32     0x07 +| 05h | char | nr_res | ??? | 
-#define NRSOFF32    0x08+| 06h | WORD | nr_entry | ??? | 
 +| ??? |||| 
 +| 04h | WORD | nr_mod | ??? | 
 +| 06h | WORD | nr_proc | ??? | 
 +| OS Fixup |||| 
 +| 04h | WORD | nr_ostype | ??? | 
 +| 06h | WORD | nr_osres | ??? |
  
-#define NRADD       0x04 
-#define NRRTYP      0x03 
-#define NRRINT      0x00 
-#define NRRORD      0x01 
-#define NRRNAM      0x02 
-#define NRROSF      0x03 
-#define NRICHAIN    0x08 
  
-#if (EXE386 == 0)+^ Offset ^ Size ^ Name ^ Description ^ 
 +| 00h | char | rs_len | ??? | 
 +| 01h | char | rs_string[1] | ??? |
  
-#define RS_LEN(x)       (x).rs_len +^ Offset ^ Size ^ Name ^ Description ^ 
-#define RS_STRING(x)    (x).rs_string +| 00h | WORD | rt_id | ??? | 
-#define RS_ALIGN(x)     (x).rs_align+| 02h | WORD | rt_nres | ??? | 
 +| 04h | DWORD | rt_proc | ??? |
  
-#define RT_ID(x)        (x).rt_id +^ Offset ^ Size ^ Name ^ Description ^ 
-#define RT_NRES(x)      (x).rt_nres +| 00h | WORD | rn_offset | ??? | 
-#define RT_PROC(x)      (x).rt_proc+| 02h | WORD | rn_length | ??? | 
 +| 04h | WORD | rn_flags | ??? | 
 +| 06h | WORD | rn_id | ??? | 
 +| 08h | WORD | rn_handle | ??? | 
 +| 0Ah | WORD | rn_usage | ??? |
  
-#define RN_OFFSET(x)    (x).rn_offset +^ Offset ^ Size ^ Name ^ Description ^ 
-#define RN_LENGTH(x)    (x).rn_length +| 00h | WORD | rs_align | ??? | 
-#define RN_FLAGS(x)     (x).rn_flags +| 02h | struct rsrc_typeinfo | rs_typeinfo | ??? |
-#define RN_ID(x)        (x).rn_id +
-#define RN_HANDLE(x)    (x).rn_handle +
-#define RN_USAGE(x)     (x).rn_usage+
  
-#define RSORDID     0x8000 
- 
-#define RNMOVE      0x0010 
-#define RNPURE      0x0020 
-#define RNPRELOAD   0x0040 
-#define RNDISCARD   0xF000 
- 
-#define NE_FFLAGS_LIBMODULE 0x8000 
- 
-struct rsrc_string { 
-    char    rs_len; 
-    char    rs_string[1]; 
-}; 
- 
-struct rsrc_typeinfo { 
-    WORD  rt_id; 
-    WORD  rt_nres; 
-    DWORD            rt_proc; 
-}; 
- 
-struct rsrc_nameinfo { 
-    WORD  rn_offset; 
-    WORD  rn_length; 
-    WORD  rn_flags; 
-    WORD  rn_id; 
-    WORD  rn_handle; 
-    WORD  rn_usage; 
-}; 
- 
-struct new_rsrc { 
-    WORD          rs_align; 
-    struct rsrc_typeinfo    rs_typeinfo; 
-};