From: Pali Rohár pali@kernel.org
Field ne_ver contains the NE linker major version. This value represents the layout of the NE binary, which means which fields are available in the IMAGE_OS2_HEADER structure. And hence it specifies the version of NE binary.
NE binaries with version less than 4 have last field at offset 2c. NE binaries with version less than 5 have last field at offset 32. And all non-Windows NE binaries have the maximal possible field at offset 3a.
After the last field of the NE header of particular version is the NE segment table. This was verified against more NE ver4 binaries. Sometimes there is a padding between end of NE header and NE segment table but in more cases there is not. And so the IMAGE_OS2_HEADER's ne_cres field for NE ver4 binaries points to the segment table.
Signed-off-by: Pali Rohár pali@kernel.org --- include/winnt.h | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/include/winnt.h b/include/winnt.h index bd3cd6dbb1f..960d644eb11 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -2624,8 +2624,14 @@ typedef struct WORD ne_modtab; /* 28 Offset to module reference table */ WORD ne_imptab; /* 2a Offset to imported name table */ DWORD ne_nrestab; /* 2c Offset to nonresident-name table */ + + /* end of the ne_ver < 4 structure */ + WORD ne_cmovent; /* 30 # of movable entry points */ WORD ne_align; /* 32 Logical sector alignment shift count */ + + /* end of the ne_ver < 5 structure */ + WORD ne_cres; /* 34 # of resource segments */ BYTE ne_exetyp; /* 36 Flags indicating target OS */ BYTE ne_flagsothers; /* 37 Additional information flags */ @@ -2645,6 +2651,9 @@ typedef struct WORD ne_psegrefbytes; WORD ne_ganglength; /* 3a Length of gangload area */ }; + + /* end of the ne_ver >= 5 structure for non-Windows modules */ + WORD ne_swaparea; /* 3c Minimum code swap area size */ WORD ne_expver; /* 3e Expected Windows version number */ } IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER;