[PATCH v2 1/4] krnl386.exe16: NE files which have an OS type of 0x00 (unknown) or linker
Martin Payne
development at martinpayne.me.uk
Sat Dec 16 15:04:44 CST 2017
major version 4 must have their imported modules checked to determine
whether they are Windows or OS/2 or Multitasking DOS 4 executables.
Tested on Fedora 26 x86
---
dlls/krnl386.exe16/ne_module.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/dlls/krnl386.exe16/ne_module.c b/dlls/krnl386.exe16/ne_module.c
index 14f8075166..e9009677d0 100644
--- a/dlls/krnl386.exe16/ne_module.c
+++ b/dlls/krnl386.exe16/ne_module.c
@@ -697,6 +697,46 @@ static HMODULE16 build_module( const void *mapping, SIZE_T mapping_size, LPCSTR
ne_header->ne_enttab - ne_header->ne_imptab )) goto failed;
pData += ne_header->ne_enttab - ne_header->ne_imptab;
+ /* If the linker version is 4.x or the executable type is unknown, it is necessary to check the import table for
+ known Windows and OS/2 libraries to determine whether it's a Windows executable. Executables with no module table
+ or which don't import known Windows or OS/2 libraries are also assumed to be Windows. */
+ if (((ne_header->ne_ver == 0x04) || (ne_header->ne_exetyp == 0x00)) && pModule->ne_modtab)
+ {
+ /* Array of offsets into the imported names table where module names are located */
+ WORD* module_table;
+
+ /* Series of Pascal strings containing the module names */
+ LPCSTR imported_names;
+
+ int i;
+ BOOL importsDosCalls = FALSE;
+ BOOL importsKernel = FALSE;
+
+ /* Get address of module table and imported names table from their offsets */
+ module_table = (WORD*)(((BYTE*)pModule) + pModule->ne_modtab);
+ imported_names = (LPCSTR)(((BYTE*)pModule) + pModule->ne_imptab);
+
+ /* Look for imports from DOSCALLS and KERNEL */
+ for (i = 0; i < pModule->ne_cmod; i++)
+ {
+ /* Module name is a Pascal string with byte length prefix */
+ LPCSTR module_name = imported_names + module_table[i];
+
+ if (!importsDosCalls && !strncmp("DOSCALLS", &module_name[1], module_name[0]))
+ importsDosCalls = TRUE;
+
+ else if (!importsKernel && !strncmp("KERNEL", &module_name[1], module_name[0]))
+ importsKernel = TRUE;
+
+ if (importsDosCalls && importsKernel)
+ break;
+ }
+
+ /* If the module has imports from DOSCALLS but not KERNEL, assume it's for OS/2 or Multitasking DOS 4. */
+ if (importsDosCalls && !importsKernel)
+ goto failed;
+ }
+
/* Load entry table, convert it to the optimized version used by Windows */
pModule->ne_enttab = pData - (BYTE *)pModule;
--
2.15.1.windows.2
More information about the wine-devel
mailing list