[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