Index: /trunk/Config.kmk
===================================================================
--- /trunk/Config.kmk	(revision 59403)
+++ /trunk/Config.kmk	(revision 59404)
@@ -1915,4 +1915,7 @@
 # VBoxDef2LazyLoad (lazy dynamic library loader assembly generator)
 VBOX_DEF_2_LAZY_LOAD ?= $(PATH_OBJ)/VBoxDef2LazyLoad/VBoxDef2LazyLoad$(HOSTSUFF_EXE)
+
+# VBoxCheckImports (checks what we imports from on windows)
+VBOX_CHECK_IMPORTS ?= $(PATH_OBJ)/VBoxCheckImports/VBoxCheckImports$(HOSTSUFF_EXE)
 
 # GNU tar if present.
Index: /trunk/include/iprt/initterm.h
===================================================================
--- /trunk/include/iprt/initterm.h	(revision 59403)
+++ /trunk/include/iprt/initterm.h	(revision 59404)
@@ -57,4 +57,7 @@
 /** The caller ensures that the argument bector is UTF-8. */
 #define RTR3INIT_FLAGS_UTF8_ARGV    RT_BIT(3)
+/** Indicates that this is a standalone application without any additional
+ * shared libraries in the application directory. Mainly windows loader mess. */
+#define RTR3INIT_FLAGS_STANDALONE_APP RT_BIT(4)
 /** @} */
 
Index: /trunk/src/VBox/Installer/win/Stub/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Installer/win/Stub/Makefile.kmk	(revision 59403)
+++ /trunk/src/VBox/Installer/win/Stub/Makefile.kmk	(revision 59404)
@@ -38,5 +38,9 @@
  VBoxStub_LIBS = \
  	$(VBOX_LIB_RUNTIME_STATIC) \
- 	$(PATH_SDK_$(VBOX_WINPSDK)_LIB)/Msi.lib
+       $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/delayimp.lib
+ VBoxStub_LDFLAGS = \
+ 	-DelayLoad:comctl32.dll
+ VBoxStub_POST_CMDS = $(VBOX_CHECK_IMPORTS) --image $(out) ntdll.dll kernel32.dll
+ VBoxStub_LNK_DEPS  = $(VBOX_CHECK_IMPORTS)
 
  VBoxStub.cpp_DEFS += VBOX_SVN_REV=$(VBOX_SVN_REV)
@@ -48,5 +52,4 @@
 
   VBoxStub_SOURCES  += VBoxStubCertUtil.cpp
-  VBoxStub_LIBS     += crypt32.lib
   VBoxStub.cpp_DEPS += $(VBoxStub_0_OUTDIR)/VBoxStubPublicCert.h
   VBoxStub.cpp_INCS += $(VBoxStub_0_OUTDIR)
@@ -76,4 +79,39 @@
 	$(APPEND) -t $@ 'APP_MANIFEST RT_MANIFEST "$(subst /,\\,$(VBOX_STUB_MANIFEST_FILE))"'
 
+ # Dynamic import no. 1: MSI.DLL
+ VBoxStub_SOURCES += $(VBoxStub_0_OUTDIR)/MsiLazyLoad.asm
+ $$(VBoxStub_0_OUTDIR)/MsiLazyLoad.asm: $(PATH_SUB_CURRENT)/msi.def $(VBOX_DEF_2_LAZY_LOAD) | $$(dir $$@)
+	$(call MSG_TOOL,VBoxDef2LazyLoad,VBoxStub,$(filter %.def, $^),$@)
+	$(QUIET)$(RM) -f -- "$@"
+	$(VBOX_DEF_2_LAZY_LOAD) --system --library MSI.DLL --output "$@" $(filter %.def, $^)
+
+ # Dynamic import no. 2: CRYPTO32.DLL
+ VBoxStub_SOURCES += $(VBoxStub_0_OUTDIR)/Crypt32LazyLoad.asm
+ $$(VBoxStub_0_OUTDIR)/Crypt32LazyLoad.asm: $(PATH_SUB_CURRENT)/crypt32.def $(VBOX_DEF_2_LAZY_LOAD) | $$(dir $$@)
+	$(call MSG_TOOL,VBoxDef2LazyLoad,VBoxStub,$(filter %.def, $^),$@)
+	$(QUIET)$(RM) -f -- "$@"
+	$(VBOX_DEF_2_LAZY_LOAD) --system --library CRYPT32.DLL --output "$@" $(filter %.def, $^)
+
+ # Dynamic import no. 3: WS2_32.DLL
+ VBoxStub_SOURCES += $(VBoxStub_0_OUTDIR)/Ws232LazyLoad.asm
+ $$(VBoxStub_0_OUTDIR)/Ws232LazyLoad.asm: $(PATH_SUB_CURRENT)/ws2_32.def $(VBOX_DEF_2_LAZY_LOAD) | $$(dir $$@)
+	$(call MSG_TOOL,VBoxDef2LazyLoad,VBoxStub,$(filter %.def, $^),$@)
+	$(QUIET)$(RM) -f -- "$@"
+	$(VBOX_DEF_2_LAZY_LOAD) --system --library WS2_32.DLL --output "$@" $(filter %.def, $^)
+
+ # Dynamic import no. 4: USER32.DLL
+ VBoxStub_SOURCES += $(VBoxStub_0_OUTDIR)/User32LazyLoad.asm
+ $$(VBoxStub_0_OUTDIR)/User32LazyLoad.asm: $(PATH_SUB_CURRENT)/user32.def $(VBOX_DEF_2_LAZY_LOAD) | $$(dir $$@)
+	$(call MSG_TOOL,VBoxDef2LazyLoad,VBoxStub,$(filter %.def, $^),$@)
+	$(QUIET)$(RM) -f -- "$@"
+	$(VBOX_DEF_2_LAZY_LOAD) --system --library USER32.DLL --output "$@" $(filter %.def, $^)
+
+ # Dynamic import no. 5: SHELL32.DLL
+ VBoxStub_SOURCES += $(VBoxStub_0_OUTDIR)/Shell32LazyLoad.asm
+ $$(VBoxStub_0_OUTDIR)/Shell32LazyLoad.asm: $(PATH_SUB_CURRENT)/shell32.def $(VBOX_DEF_2_LAZY_LOAD) | $$(dir $$@)
+	$(call MSG_TOOL,VBoxDef2LazyLoad,VBoxStub,$(filter %.def, $^),$@)
+	$(QUIET)$(RM) -f -- "$@"
+	$(VBOX_DEF_2_LAZY_LOAD) --system --library SHELL32.DLL --output "$@" $(filter %.def, $^)
+
 
 endif # x86 only
Index: /trunk/src/VBox/Installer/win/Stub/VBoxStub.cpp
===================================================================
--- /trunk/src/VBox/Installer/win/Stub/VBoxStub.cpp	(revision 59403)
+++ /trunk/src/VBox/Installer/win/Stub/VBoxStub.cpp	(revision 59404)
@@ -802,6 +802,17 @@
     int argc    = __argc;
 
-    /* Check if we're already running and jump out if so. */
-    /* Do not use a global namespace ("Global\\") for mutex name here, will blow up NT4 compatibility! */
+    /*
+     * Init IPRT. This is _always_ the very first thing we do.
+     */
+    int vrc = RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_STANDALONE_APP);
+    if (RT_FAILURE(vrc))
+        return RTMsgInitFailure(vrc);
+
+    /*
+     * Check if we're already running and jump out if so.
+     *
+     * Note! Do not use a global namespace ("Global\\") for mutex name here,
+     *       will blow up NT4 compatibility!
+     */
     HANDLE hMutexAppRunning = CreateMutex(NULL, FALSE, "VBoxStubInstaller");
     if (   hMutexAppRunning != NULL
@@ -812,14 +823,4 @@
         hMutexAppRunning = NULL;
         return RTEXITCODE_FAILURE;
-    }
-
-    /* Init IPRT. */
-    int vrc = RTR3InitExe(argc, &argv, 0);
-    if (RT_FAILURE(vrc))
-    {
-        /* Close the mutex for this application instance. */
-        CloseHandle(hMutexAppRunning);
-        hMutexAppRunning = NULL;
-        return RTMsgInitFailure(vrc);
     }
 
Index: /trunk/src/VBox/Installer/win/Stub/crypt32.def
===================================================================
--- /trunk/src/VBox/Installer/win/Stub/crypt32.def	(revision 59404)
+++ /trunk/src/VBox/Installer/win/Stub/crypt32.def	(revision 59404)
@@ -0,0 +1,25 @@
+; $Id$
+;; @file
+; Definitions for CRYPT32.DLL lazy import library.
+;
+
+; 
+; Copyright (C) 2009-2016 Oracle Corporation
+; 
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+; 
+
+LIBRARY CRYPT32.DLL
+EXPORTS
+    _CertCreateCertificateContext@12
+    _CertOpenStore@20
+    _CertFreeCertificateContext@4
+    _CertAddCertificateContextToStore@16
+    _CertCloseStore@8
+
Index: /trunk/src/VBox/Installer/win/Stub/msi.def
===================================================================
--- /trunk/src/VBox/Installer/win/Stub/msi.def	(revision 59404)
+++ /trunk/src/VBox/Installer/win/Stub/msi.def	(revision 59404)
@@ -0,0 +1,23 @@
+; $Id$
+;; @file
+; Definitions for MSI.DLL lazy import library.
+;
+
+; 
+; Copyright (C) 2009-2016 Oracle Corporation
+; 
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+; 
+
+LIBRARY MSI.DLL
+EXPORTS
+    _MsiInstallProductW@8
+    _MsiEnableLogW@12
+    _MsiSetInternalUI@8
+
Index: /trunk/src/VBox/Installer/win/Stub/shell32.def
===================================================================
--- /trunk/src/VBox/Installer/win/Stub/shell32.def	(revision 59404)
+++ /trunk/src/VBox/Installer/win/Stub/shell32.def	(revision 59404)
@@ -0,0 +1,22 @@
+; $Id$
+;; @file
+; Definitions for SHELL32.DLL lazy import library.
+;
+
+; 
+; Copyright (C) 2009-2016 Oracle Corporation
+; 
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+; 
+
+LIBRARY SHELL32.DLL
+EXPORTS
+    _CommandLineToArgvW@8
+    _SHFileOperationW@4
+
Index: /trunk/src/VBox/Installer/win/Stub/user32.def
===================================================================
--- /trunk/src/VBox/Installer/win/Stub/user32.def	(revision 59404)
+++ /trunk/src/VBox/Installer/win/Stub/user32.def	(revision 59404)
@@ -0,0 +1,23 @@
+; $Id$
+;; @file
+; Definitions for USER32.DLL lazy import library.
+;
+
+; 
+; Copyright (C) 2009-2016 Oracle Corporation
+; 
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+; 
+
+LIBRARY USER32.DLL
+EXPORTS
+    _MessageBoxW@16
+    _MessageBoxA@16
+    _GetDesktopWindow@0
+
Index: /trunk/src/VBox/Installer/win/Stub/ws2_32.def
===================================================================
--- /trunk/src/VBox/Installer/win/Stub/ws2_32.def	(revision 59404)
+++ /trunk/src/VBox/Installer/win/Stub/ws2_32.def	(revision 59404)
@@ -0,0 +1,22 @@
+; $Id$
+;; @file
+; Definitions for WS2_32.DLL lazy import library.
+;
+
+; 
+; Copyright (C) 2009-2016 Oracle Corporation
+; 
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+; 
+
+LIBRARY WS2_32.DLL
+EXPORTS
+    _WSASetLastError@4
+    _WSAGetLastError@0
+
Index: /trunk/src/VBox/Runtime/r3/init.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/init.cpp	(revision 59403)
+++ /trunk/src/VBox/Runtime/r3/init.cpp	(revision 59404)
@@ -148,5 +148,5 @@
 DECLHIDDEN(int)  rtR3InitNativeFirst(uint32_t fFlags) { return VINF_SUCCESS; }
 DECLHIDDEN(int)  rtR3InitNativeFinal(uint32_t fFlags) { return VINF_SUCCESS; }
-DECLHIDDEN(void) rtR3InitNativeObtrusive(void) { }
+DECLHIDDEN(void) rtR3InitNativeObtrusive(uint32_t fFlags) { }
 #endif
 
@@ -556,5 +556,6 @@
                         | RTR3INIT_FLAGS_SUPLIB
                         | RTR3INIT_FLAGS_UNOBTRUSIVE
-                        | RTR3INIT_FLAGS_UTF8_ARGV)));
+                        | RTR3INIT_FLAGS_UTF8_ARGV
+                        | RTR3INIT_FLAGS_STANDALONE_APP)));
     Assert(!(fFlags & RTR3INIT_FLAGS_DLL) || cArgs == 0);
 
@@ -577,4 +578,5 @@
         }
 #endif
+        g_fInitFlags |= fFlags & RTR3INIT_FLAGS_UTF8_ARGV;
 
         if (   !(fFlags      & RTR3INIT_FLAGS_UNOBTRUSIVE)
@@ -582,7 +584,10 @@
         {
             g_fInitFlags &= ~RTR3INIT_FLAGS_UNOBTRUSIVE;
-            rtR3InitNativeObtrusive();
+            g_fInitFlags |= fFlags & RTR3INIT_FLAGS_STANDALONE_APP;
+            rtR3InitNativeObtrusive(g_fInitFlags | fFlags);
             rtThreadReInitObtrusive();
         }
+        else
+            Assert(!(fFlags & RTR3INIT_FLAGS_STANDALONE_APP) || (g_fInitFlags & RTR3INIT_FLAGS_STANDALONE_APP));
 
         int rc = VINF_SUCCESS;
Index: /trunk/src/VBox/Runtime/r3/init.h
===================================================================
--- /trunk/src/VBox/Runtime/r3/init.h	(revision 59403)
+++ /trunk/src/VBox/Runtime/r3/init.h	(revision 59404)
@@ -33,5 +33,5 @@
 DECLHIDDEN(int)  rtR3InitNativeFirst(uint32_t fFlags);
 DECLHIDDEN(int)  rtR3InitNativeFinal(uint32_t fFlags);
-DECLHIDDEN(void) rtR3InitNativeObtrusive(void);
+DECLHIDDEN(void) rtR3InitNativeObtrusive(uint32_t fFlags);
 
 #endif
Index: /trunk/src/VBox/Runtime/r3/win/init-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/init-win.cpp	(revision 59403)
+++ /trunk/src/VBox/Runtime/r3/win/init-win.cpp	(revision 59404)
@@ -250,5 +250,5 @@
 
 
-static int rtR3InitNativeObtrusiveWorker(void)
+static int rtR3InitNativeObtrusiveWorker(uint32_t fFlags)
 {
     /*
@@ -264,5 +264,6 @@
      *    current directory.
      *  - The second trick is W7 w/ KB2533623 and W8+, it restrict the DLL
-     *    searching to the application directory and the System32 directory.
+     *    searching to the application directory (except when
+     *    RTR3INIT_FLAGS_STANDALONE_APP is given) and the System32 directory.
      */
     int rc = VINF_SUCCESS;
@@ -278,6 +279,10 @@
     }
 
-    /** @bugref{6861} Observed GUI issues on Vista (32-bit and 64-bit). */
-    if (g_enmWinVer > kRTWinOSType_VISTA)
+    /** @bugref{6861} Observed GUI issues on Vista (32-bit and 64-bit) when using
+     *                SetDefaultDllDirectories.
+     *  @bugref{8194} Try use SetDefaultDllDirectories on Vista for standalone apps
+     *                despite potential GUI issues. */
+    if (   g_enmWinVer > kRTWinOSType_VISTA
+        || (fFlags & RTR3INIT_FLAGS_STANDALONE_APP))
     {
         typedef BOOL(WINAPI *PFNSETDEFAULTDLLDIRECTORIES)(DWORD);
@@ -286,6 +291,9 @@
         if (pfnSetDefDllDirs)
         {
-            if (pfnSetDefDllDirs(LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32))
-                g_enmWinLdrProt = RTR3WINLDRPROT_SAFE;
+            DWORD fDllDirs = LOAD_LIBRARY_SEARCH_SYSTEM32;
+            if (!(fFlags & RTR3INIT_FLAGS_STANDALONE_APP))
+                fDllDirs |= LOAD_LIBRARY_SEARCH_APPLICATION_DIR;
+            if (pfnSetDefDllDirs(fDllDirs))
+                g_enmWinLdrProt = fDllDirs & LOAD_LIBRARY_SEARCH_APPLICATION_DIR ? RTR3WINLDRPROT_SAFE : RTR3WINLDRPROT_SAFER;
             else if (RT_SUCCESS(rc))
                 rc = VERR_INTERNAL_ERROR_4;
@@ -313,5 +321,5 @@
     int rc = VINF_SUCCESS;
     if (!(fFlags & RTR3INIT_FLAGS_UNOBTRUSIVE))
-        rc = rtR3InitNativeObtrusiveWorker();
+        rc = rtR3InitNativeObtrusiveWorker(fFlags);
 
     /*
@@ -327,7 +335,7 @@
 
 
-DECLHIDDEN(void) rtR3InitNativeObtrusive(void)
-{
-    rtR3InitNativeObtrusiveWorker();
+DECLHIDDEN(void) rtR3InitNativeObtrusive(uint32_t fFlags)
+{
+    rtR3InitNativeObtrusiveWorker(fFlags);
 }
 
Index: /trunk/src/VBox/Runtime/r3/win/internal-r3-win.h
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/internal-r3-win.h	(revision 59403)
+++ /trunk/src/VBox/Runtime/r3/win/internal-r3-win.h	(revision 59404)
@@ -85,5 +85,6 @@
     RTR3WINLDRPROT_NONE,
     RTR3WINLDRPROT_NO_CWD,
-    RTR3WINLDRPROT_SAFE
+    RTR3WINLDRPROT_SAFE,
+    RTR3WINLDRPROT_SAFER
 } RTR3WINLDRPROT;
 
Index: /trunk/src/VBox/Storage/testcase/vbox-img.cpp
===================================================================
--- /trunk/src/VBox/Storage/testcase/vbox-img.cpp	(revision 59403)
+++ /trunk/src/VBox/Storage/testcase/vbox-img.cpp	(revision 59404)
@@ -1778,5 +1778,5 @@
     int exitcode = 0;
 
-    int rc = RTR3InitExe(argc, &argv, 0);
+    int rc = RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_STANDALONE_APP);
     if (RT_FAILURE(rc))
         return RTMsgInitFailure(rc);
Index: /trunk/src/bldprogs/Makefile.kmk
===================================================================
--- /trunk/src/bldprogs/Makefile.kmk	(revision 59403)
+++ /trunk/src/bldprogs/Makefile.kmk	(revision 59404)
@@ -68,4 +68,8 @@
 VBoxPeSetVersion_SOURCES  = VBoxPeSetVersion.cpp
 
+BLDPROGS.win += VBoxCheckImports
+VBoxCheckImports_TEMPLATE = VBoxBldProg
+VBoxCheckImports_SOURCES  = VBoxCheckImports.cpp
+
 BLDPROGS += VBoxDef2LazyLoad
 VBoxDef2LazyLoad_TEMPLATE = VBoxBldProg
Index: /trunk/src/bldprogs/VBoxCheckImports.cpp
===================================================================
--- /trunk/src/bldprogs/VBoxCheckImports.cpp	(revision 59404)
+++ /trunk/src/bldprogs/VBoxCheckImports.cpp	(revision 59404)
@@ -0,0 +1,371 @@
+/* $Id$ */
+/** @file
+ * IPRT - Checks that a windows image only imports from a given set of DLLs.
+ */
+
+/*
+ * Copyright (C) 2012-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/formats/mz.h>
+#include <iprt/formats/pecoff.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+typedef struct
+{
+    const char *pszImage;
+    FILE       *pFile;
+    bool        f32Bit;
+    union
+    {
+        IMAGE_NT_HEADERS32 Nt32;
+        IMAGE_NT_HEADERS64 Nt64;
+    } Hdrs;
+
+    uint32_t                cSections;
+    PIMAGE_SECTION_HEADER   paSections;
+} MYIMAGE;
+
+
+static bool Failed(MYIMAGE *pThis, const char *pszFmt, ...)
+{
+    va_list va;
+    fprintf(stderr, "error '%s': ", pThis->pszImage);
+    va_start(va, pszFmt);
+    vfprintf(stderr, pszFmt, va);
+    va_end(va);
+    fprintf(stderr, "\n");
+    return false;
+}
+
+
+static bool ReadPeHeaders(MYIMAGE *pThis)
+{
+    /*
+     * MZ header.
+     */
+    IMAGE_DOS_HEADER MzHdr;
+    if (fread(&MzHdr, sizeof(MzHdr), 1, pThis->pFile) != 1)
+        return Failed(pThis, "Reading DOS header");
+
+    if (MzHdr.e_magic != IMAGE_DOS_SIGNATURE)
+        return Failed(pThis, "No MZ magic (found %#x)", MzHdr.e_magic);
+
+    if (fseek(pThis->pFile, MzHdr.e_lfanew, SEEK_SET) != 0)
+        return Failed(pThis, "Seeking to %#lx", (unsigned long)MzHdr.e_lfanew);
+
+    /*
+     * NT signature + file header.
+     */
+    if (fread(&pThis->Hdrs.Nt32, offsetof(IMAGE_NT_HEADERS32, OptionalHeader), 1, pThis->pFile) != 1)
+        return Failed(pThis, "Reading NT file header");
+
+    if (pThis->Hdrs.Nt32.Signature != IMAGE_NT_SIGNATURE)
+        return Failed(pThis, "No PE magic (found %#x)", pThis->Hdrs.Nt32.Signature);
+
+    if (pThis->Hdrs.Nt32.FileHeader.SizeOfOptionalHeader == sizeof(pThis->Hdrs.Nt32.OptionalHeader))
+        pThis->f32Bit = true;
+    else if (pThis->Hdrs.Nt32.FileHeader.SizeOfOptionalHeader == sizeof(pThis->Hdrs.Nt64.OptionalHeader))
+        pThis->f32Bit = false;
+    else
+        return Failed(pThis, "Unsupported SizeOfOptionalHeaders value: %#x",
+                      pThis->Hdrs.Nt32.FileHeader.SizeOfOptionalHeader);
+
+    /*
+     * NT optional header.
+     */
+    if (fread(&pThis->Hdrs.Nt32.OptionalHeader, pThis->Hdrs.Nt32.FileHeader.SizeOfOptionalHeader, 1, pThis->pFile) != 1)
+        return Failed(pThis, "Reading NT optional header");
+
+    if (   pThis->Hdrs.Nt32.OptionalHeader.Magic
+        != (pThis->f32Bit ? IMAGE_NT_OPTIONAL_HDR32_MAGIC : IMAGE_NT_OPTIONAL_HDR64_MAGIC) )
+        return Failed(pThis, "Bad optional header magic: %#x", pThis->Hdrs.Nt32.OptionalHeader.Magic);
+
+    uint32_t NumberOfRvaAndSizes = pThis->f32Bit
+                                 ? pThis->Hdrs.Nt32.OptionalHeader.NumberOfRvaAndSizes
+                                 : pThis->Hdrs.Nt64.OptionalHeader.NumberOfRvaAndSizes;
+    if (NumberOfRvaAndSizes != IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
+        return Failed(pThis, "Unsupported NumberOfRvaAndSizes value: %#x", NumberOfRvaAndSizes);
+
+    /*
+     * Read the section table.
+     */
+    pThis->cSections  = pThis->Hdrs.Nt32.FileHeader.NumberOfSections;
+    if (!pThis->cSections)
+        return Failed(pThis, "No sections in image!");
+    pThis->paSections = (PIMAGE_SECTION_HEADER)calloc(sizeof(pThis->paSections[0]), pThis->cSections);
+    if (!pThis->paSections)
+        return Failed(pThis, "Out of memory!");
+    if (fread(pThis->paSections, sizeof(pThis->paSections[0]), pThis->cSections, pThis->pFile) != pThis->cSections)
+        return Failed(pThis, "Reading NT section headers");
+
+
+    return true;
+}
+
+
+static bool ReadAtRva(MYIMAGE *pThis, uint32_t uRva, void *pvBuf, size_t cbToRead)
+{
+    unsigned const uRvaOrg     = uRva;
+    size_t   const cbToReadOrg = cbToRead;
+
+    /*
+     * Header section.
+     */
+    int      iSh        = -1;
+    uint32_t uSectRva   = 0;
+    uint32_t offSectRaw = 0;
+    uint32_t cbSectRaw  = pThis->f32Bit
+                        ? pThis->Hdrs.Nt32.OptionalHeader.SizeOfHeaders
+                        : pThis->Hdrs.Nt64.OptionalHeader.SizeOfHeaders;
+    uint32_t cbSectMax  = pThis->paSections[0].VirtualAddress;
+
+    for (;;)
+    {
+        /* Read if we've got a match. */
+        uint32_t off = uRva - uSectRva;
+        if (off < cbSectMax)
+        {
+            uint32_t cbThis = cbSectMax - off;
+            if (cbThis > cbToRead)
+                cbThis = (uint32_t)cbToRead;
+
+            memset(pvBuf, 0, cbThis);
+
+            if (off < cbSectRaw)
+            {
+                if (fseek(pThis->pFile, offSectRaw + off, SEEK_SET) != 0)
+                    return Failed(pThis, "Seeking to %#x", offSectRaw + off);
+                if (fread(pvBuf, RT_MIN(cbThis, cbSectRaw - off), 1, pThis->pFile) != 1)
+                    return Failed(pThis, "Reading %u bytes at %#x", RT_MIN(cbThis, cbSectRaw - off), offSectRaw + off);
+            }
+
+            cbToRead -= cbThis;
+            if (!cbToRead)
+                return true;
+            pvBuf = (uint8_t *)pvBuf + cbThis;
+        }
+
+        /* next section */
+        iSh++;
+        if ((unsigned)iSh >= pThis->cSections)
+            return Failed(pThis, "RVA %#x LB %u is outside the image", uRvaOrg, cbToReadOrg);
+        uSectRva   = pThis->paSections[iSh].VirtualAddress;
+        offSectRaw = pThis->paSections[iSh].PointerToRawData;
+        cbSectRaw  = pThis->paSections[iSh].SizeOfRawData;
+        if ((unsigned)iSh + 1 < pThis->cSections)
+            cbSectMax = pThis->paSections[iSh + 1].VirtualAddress - uSectRva;
+        else
+            cbSectMax = pThis->paSections[iSh].Misc.VirtualSize;
+    }
+}
+
+
+static bool ReadStringAtRva(MYIMAGE *pThis, uint32_t uRva, char *pszBuf, size_t cbMax)
+{
+    uint32_t const uRvaOrg = uRva;
+
+    /*
+     * Try read the whole string at once.
+     */
+    uint32_t cbImage = pThis->f32Bit
+                     ? pThis->Hdrs.Nt32.OptionalHeader.SizeOfImage
+                     : pThis->Hdrs.Nt64.OptionalHeader.SizeOfImage;
+    uint32_t cbThis = uRva < cbImage ? cbImage - uRva : 1;
+    if (cbThis > cbMax)
+        cbThis = (uint32_t)cbMax;
+    if (!ReadAtRva(pThis, uRva, pszBuf, cbThis))
+        return false;
+    if (memchr(pszBuf, 0, cbThis) != NULL)
+        return true;
+
+    /*
+     * Read more, byte-by-byte.
+     */
+    for (;;)
+    {
+        cbMax -= cbThis;
+        if (!cbMax)
+            return Failed(pThis, "String to long at %#x", uRvaOrg);
+        pszBuf += cbThis;
+        uRva   += cbThis;
+
+        cbThis = 1;
+        if (!ReadAtRva(pThis, uRva, pszBuf, cbThis))
+            return false;
+        if (!*pszBuf)
+            return true;
+    }
+}
+
+
+static void *ReadAtRvaAlloc(MYIMAGE *pThis, uint32_t uRva, size_t cbToRead)
+{
+    void *pvBuf = malloc(cbToRead);
+    if (pvBuf)
+    {
+        if (ReadAtRva(pThis, uRva, pvBuf, cbToRead))
+            return pvBuf;
+        free(pvBuf);
+    }
+    else
+        Failed(pThis, "Out of memory!");
+    return NULL;
+}
+
+
+static bool ParseAndCheckImports(MYIMAGE *pThis,  const char **papszAllowed, unsigned cAllowed)
+{
+    /*
+     * Do we have an import directory? If so, read it.
+     */
+    IMAGE_DATA_DIRECTORY ImpDir = pThis->f32Bit
+                                ? pThis->Hdrs.Nt32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
+                                : pThis->Hdrs.Nt64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
+    if (ImpDir.Size == 0)
+        return true;
+
+    uint32_t cImps = ImpDir.Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);
+    if (cImps * sizeof(IMAGE_IMPORT_DESCRIPTOR) != ImpDir.Size)
+        return Failed(pThis, "Import directory size is not a multiple of IMAGE_IMPORT_DESCRIPTOR: %#x", ImpDir.Size);
+
+    PIMAGE_IMPORT_DESCRIPTOR paImps = (PIMAGE_IMPORT_DESCRIPTOR)ReadAtRvaAlloc(pThis, ImpDir.VirtualAddress, ImpDir.Size);
+    if (!paImps)
+        return false;
+
+    /* There is usually an empty entry at the end. */
+    if (   paImps[cImps - 1].Name       == 0
+        || paImps[cImps - 1].FirstThunk == 0)
+           cImps--;
+
+    /*
+     * Do the processing.
+     */
+    bool fRc = true;
+    for (uint32_t i = 0; i < cImps; i++)
+    {
+        /* Read the import name string. */
+        char szName[128];
+        if (!ReadStringAtRva(pThis, paImps[i].Name, szName, sizeof(szName)))
+        {
+            fRc = false;
+            break;
+        }
+
+        /* Check it against the list of allowed DLLs. */
+        bool fFound = false;
+        unsigned j = cAllowed;
+        while (j-- > 0)
+            if (stricmp(papszAllowed[j], szName) == 0)
+            {
+                fFound = true;
+                break;
+            }
+        if (!fFound)
+            fRc = Failed(pThis, "Illegal import: '%s'", szName);
+    }
+
+    free(paImps);
+    return fRc;
+}
+
+
+static int usage(const char *argv0)
+{
+    printf("usage: %s --image <image> [allowed-dll [..]]\n");
+    return RTEXITCODE_SUCCESS;
+}
+
+
+int main(int argc, char **argv)
+{
+    /*
+     * Parse arguments.
+     */
+    const char  *pszImage     = NULL;
+    const char **papszAllowed = (const char **)calloc(argc, sizeof(const char *));
+    unsigned     cAllowed     = 0;
+
+    for (int i = 1; i < argc; i++)
+    {
+        const char *psz = argv[i];
+        if (*psz == '-')
+        {
+            if (!strcmp(psz, "--image") || !strcmp(psz, "-i"))
+            {
+                if (++i >= argc)
+                {
+                    fprintf(stderr, "syntax error: File name expected after '%s'.\n", psz);
+                    return RTEXITCODE_SYNTAX;
+                }
+                pszImage = argv[i];
+            }
+            else if (   !strcmp(psz, "--help")
+                     || !strcmp(psz, "-help")
+                     || !strcmp(psz, "-h")
+                     || !strcmp(psz, "-?") )
+                return usage(argv[0]);
+            else if (   !strcmp(psz, "--version")
+                     || !strcmp(psz, "-V"))
+            {
+                printf("$Revision$\n");
+                return RTEXITCODE_SUCCESS;
+            }
+            else
+            {
+                fprintf(stderr, "syntax error: Unknown option '%s'.\n", psz);
+                return RTEXITCODE_SYNTAX;
+            }
+        }
+        else
+            papszAllowed[cAllowed++] = argv[i];
+    }
+
+    if (!pszImage)
+    {
+        fprintf(stderr, "syntax error: No input file specified.\n");
+        return RTEXITCODE_SYNTAX;
+    }
+
+    /*
+     * Open the image and process headers.
+     */
+    RTEXITCODE  rcExit = RTEXITCODE_FAILURE;
+    MYIMAGE     MyImage;
+    memset(&MyImage, 0, sizeof(MyImage));
+    MyImage.pszImage = pszImage;
+    MyImage.pFile     = fopen(pszImage, "rb");
+    if (MyImage.pFile)
+    {
+        if (   ReadPeHeaders(&MyImage)
+            && ParseAndCheckImports(&MyImage, papszAllowed, cAllowed))
+               rcExit = RTEXITCODE_SUCCESS;
+
+        fclose(MyImage.pFile);
+        free(MyImage.paSections);
+    }
+    else
+        Failed(&MyImage, "Failed to open image for binary reading.");
+
+    return rcExit;
+}
+
+
Index: /trunk/src/bldprogs/VBoxDef2LazyLoad.cpp
===================================================================
--- /trunk/src/bldprogs/VBoxDef2LazyLoad.cpp	(revision 59403)
+++ /trunk/src/bldprogs/VBoxDef2LazyLoad.cpp	(revision 59404)
@@ -35,6 +35,10 @@
 {
     struct MYEXPORT    *pNext;
+    /** Pointer to unmangled name for stdcall (after szName), NULL if not. */
+    char               *pszUnstdcallName;
+    /** Pointer to the exported name. */
+    char const         *pszExportedNm;
+    unsigned            uOrdinal;
     bool                fNoName;
-    unsigned            uOrdinal;
     char                szName[1];
 } MYEXPORT;
@@ -54,4 +58,5 @@
 static bool         g_fIgnoreData = true;
 static bool         g_fWithExplictLoadFunction = false;
+static bool         g_fSystemLibrary = false;
 /** @} */
 
@@ -176,5 +181,5 @@
             }
 
-            bool     fNoName  = true;
+            bool     fNoName  = false;
             unsigned uOrdinal = ~0U;
             if (*psz == '@')
@@ -196,11 +201,6 @@
                 if (WORD_CMP(psz, cch, "NONAME"))
                 {
-#if 0
                     fNoName = true;
                     psz = leftStrip(psz + cch);
-#else
-                    fprintf(stderr, "%s:%u: error: NONAME export not implemented.\n", pszInput, iLine);
-                    return RTEXITCODE_FAILURE;
-#endif
                 }
             }
@@ -228,7 +228,23 @@
 
             /*
+             * Check for stdcall mangling.
+             */
+            size_t   cbExp = sizeof(MYEXPORT) + cchName;
+            unsigned cchStdcall = 0;
+            if (cchName > 3 && *pchName == '_' && isdigit(pchName[cchName - 1]))
+            {
+                if (cchName > 3 && pchName[cchName - 2] == '@')
+                    cchStdcall = 2;
+                else if (cchName > 4 && pchName[cchName - 3] == '@' && isdigit(pchName[cchName - 2]))
+                    cchStdcall = 3;
+                if (cchStdcall)
+                    cbExp += cchName - 1 - cchStdcall;
+            }
+
+            /*
              * Add the export.
              */
-            PMYEXPORT pExp = (PMYEXPORT)malloc(sizeof(*pExp) + cchName);
+
+            PMYEXPORT pExp = (PMYEXPORT)malloc(cbExp);
             if (!pExp)
             {
@@ -238,9 +254,21 @@
             memcpy(pExp->szName, pchName, cchName);
             pExp->szName[cchName] = '\0';
-            pExp->uOrdinal = uOrdinal;
-            pExp->fNoName  = fNoName;
-            pExp->pNext    = NULL;
-            *g_ppExpNext   = pExp;
-            g_ppExpNext    = &pExp->pNext;
+            if (!cchStdcall)
+            {
+                pExp->pszUnstdcallName = NULL;
+                pExp->pszExportedNm = pExp->szName;
+            }
+            else
+            {
+                pExp->pszUnstdcallName = &pExp->szName[cchName + 1];
+                memcpy(pExp->pszUnstdcallName, pchName + 1, cchName - 1 - cchStdcall);
+                pExp->pszUnstdcallName[cchName - 1 - cchStdcall] = '\0';
+                pExp->pszExportedNm = pExp->pszUnstdcallName;
+            }
+            pExp->uOrdinal   = uOrdinal;
+            pExp->fNoName    = fNoName;
+            pExp->pNext      = NULL;
+            *g_ppExpNext     = pExp;
+            g_ppExpNext      = &pExp->pNext;
         }
     }
@@ -322,11 +350,24 @@
             "BEGINCODE\n");
     for (PMYEXPORT pExp = g_pExpHead; pExp; pExp = pExp->pNext)
-        fprintf(pOutput,
-                "BEGINPROC %s\n"
-                "    jmp RTCCPTR_PRE [g_pfn%s xWrtRIP]\n"
-                "ENDPROC   %s\n",
-                pExp->szName,
-                pExp->szName,
-                pExp->szName);
+        if (!pExp->pszUnstdcallName)
+            fprintf(pOutput,
+                    "BEGINPROC %s\n"
+                    "    jmp   RTCCPTR_PRE [g_pfn%s xWrtRIP]\n"
+                    "ENDPROC   %s\n",
+                    pExp->szName, pExp->szName, pExp->szName);
+        else
+            fprintf(pOutput,
+                    "%%ifdef RT_ARCH_X86\n"
+                    "global    %s\n"
+                    "%s:\n"
+                    "    jmp   RTCCPTR_PRE [g_pfn%s xWrtRIP]\n"
+                    "%%else\n"
+                    "BEGINPROC %s\n"
+                    "    jmp   RTCCPTR_PRE [g_pfn%s xWrtRIP]\n"
+                    "ENDPROC   %s\n"
+                    "%%endif\n",
+                    pExp->szName, pExp->szName, pExp->pszUnstdcallName,
+                    pExp->pszUnstdcallName, pExp->pszUnstdcallName, pExp->pszUnstdcallName);
+
     fprintf(pOutput,
             "\n"
@@ -348,9 +389,10 @@
                 "__imp_%s:\n"
                 "%%endif\n"
-                "g_pfn%s RTCCPTR_DEF ___LazyLoad___%s\n",
+                "g_pfn%s RTCCPTR_DEF ___LazyLoad___%s\n"
+                "\n",
                 pExp->szName,
                 pExp->szName,
-                pExp->szName,
-                pExp->szName);
+                pExp->pszExportedNm,
+                pExp->pszExportedNm);
     fprintf(pOutput,
             "RTCCPTR_DEF 0 ; Terminator entry for traversal.\n"
@@ -369,11 +411,18 @@
             ";\n"
             "BEGINCODE\n"
-            "g_szLibrary db '%s',0\n"
+            "g_szLibrary:        db '%s',0\n"
+            "\n"
             "g_szzNames:\n",
             g_pszLibrary);
     for (PMYEXPORT pExp = g_pExpHead; pExp; pExp = pExp->pNext)
-        fprintf(pOutput, "g_sz%s: db '%s',0\n", pExp->szName, pExp->szName);
+        if (!pExp->fNoName)
+            fprintf(pOutput, "  g_sz%s:\n    db '%s',0\n", pExp->pszExportedNm, pExp->pszExportedNm);
+        else
+            fprintf(pOutput, "  g_sz%s:\n    db '#%u',0\n", pExp->pszExportedNm, pExp->uOrdinal);
     fprintf(pOutput,
             "g_EndOfNames: db 0\n"
+            "\n"
+            "g_szFailLoadFmt:    db 'Lazy loader failed to load \"%%s\": %%Rrc', 10, 0\n"
+            "g_szFailResolveFmt: db 'Lazy loader failed to resolve symbol \"%%s\" in \"%%s\": %%Rrc', 10, 0\n"
             "\n"
             "\n");
@@ -388,29 +437,62 @@
             "BEGINCODE\n");
     for (PMYEXPORT pExp = g_pExpHead; pExp; pExp = pExp->pNext)
-        fprintf(pOutput,
-                "___LazyLoad___%s:\n"
-                /* "int3\n" */
-                "%%ifdef RT_ARCH_AMD64\n"
-                "    lea     rax, [g_sz%s wrt rip]\n"
-                "    lea     r10, [g_pfn%s wrt rip]\n"
-                "%%elifdef RT_ARCH_X86\n"
-                "    push    g_sz%s\n"
-                "    push    g_pfn%s\n"
-                "%%else\n"
-                " %%error \"Unsupported architecture\"\n"
-                "%%endif\n"
-                "    call    LazyLoadResolver\n"
-                "%%ifdef RT_ARCH_X86\n"
-                "    add     esp, 8h\n"
-                "%%endif\n"
-                "    jmp     NAME(%s)\n"
-                "\n"
-                ,
-                pExp->szName,
-                pExp->szName,
-                pExp->szName,
-                pExp->szName,
-                pExp->szName,
-                pExp->szName);
+    {
+        if (!pExp->fNoName)
+            fprintf(pOutput,
+                    "___LazyLoad___%s:\n"
+                    /* "int3\n" */
+                    "%%ifdef RT_ARCH_AMD64\n"
+                    "    lea     rax, [g_sz%s wrt rip]\n"
+                    "    lea     r10, [g_pfn%s wrt rip]\n"
+                    "    call    LazyLoadResolver\n"
+                    "%%elifdef RT_ARCH_X86\n"
+                    "    push    g_sz%s\n"
+                    "    push    g_pfn%s\n"
+                    "    call    LazyLoadResolver\n"
+                    "    add     esp, 8h\n"
+                    "%%else\n"
+                    " %%error \"Unsupported architecture\"\n"
+                    "%%endif\n"
+                    ,
+                    pExp->pszExportedNm,
+                    pExp->pszExportedNm,
+                    pExp->pszExportedNm,
+                    pExp->pszExportedNm,
+                    pExp->pszExportedNm);
+        else
+            fprintf(pOutput,
+                    "___LazyLoad___%s:\n"
+                    /* "int3\n" */
+                    "%%ifdef RT_ARCH_AMD64\n"
+                    "    mov     eax, %u\n"
+                    "    lea     r10, [g_pfn%s wrt rip]\n"
+                    "    call    LazyLoadResolver\n"
+                    "%%elifdef RT_ARCH_X86\n"
+                    "    push    %u\n"
+                    "    push    g_pfn%s\n"
+                    "    call    LazyLoadResolver\n"
+                    "    add     esp, 8h\n"
+                    "%%else\n"
+                    " %%error \"Unsupported architecture\"\n"
+                    "%%endif\n"
+                    ,
+                    pExp->pszExportedNm,
+                    pExp->uOrdinal,
+                    pExp->pszExportedNm,
+                    pExp->uOrdinal,
+                    pExp->pszExportedNm);
+        if (!pExp->pszUnstdcallName)
+            fprintf(pOutput, "    jmp     NAME(%s)\n", pExp->szName);
+        else
+            fprintf(pOutput,
+                    "%%ifdef RT_ARCH_X86\n"
+                    "    jmp     %s\n"
+                    "%%else\n"
+                    "    jmp     NAME(%s)\n"
+                    "%%endif\n"
+                    ,
+                    pExp->szName, pExp->szName);
+        fprintf(pOutput, "\n");
+    }
     fprintf(pOutput,
             "\n"
@@ -437,55 +519,139 @@
      * saved all necessary registers.
      */
-    fprintf(pOutput,
-            ";\n"
-            ";SUPR3DECL(int) SUPR3HardenedLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod,\n"
-            ";                                           uint32_t fFlags, PRTERRINFO pErrInfo);\n"
-            ";\n"
-            "EXTERN_IMP2 SUPR3HardenedLdrLoadAppPriv\n"
-            "BEGINCODE\n"
-            "\n"
-            "LazyLoading:\n"
-            "    mov     xCX, [g_hMod xWrtRIP]\n"
-            "    or      xCX, xCX\n"
-            "    jnz     .return\n"
-            "\n"
-            "%%ifdef ASM_CALL64_GCC\n"
-            "    xor     rcx, rcx               ; pErrInfo\n"
-            "    xor     rdx, rdx               ; fFlags (local load)\n"
-            "    lea     rsi, [g_hMod wrt rip]  ; phLdrMod\n"
-            "    lea     rdi, [g_szLibrary wrt rip] ; pszFilename\n"
-            "    sub     rsp, 08h\n"
-            "    call    IMP2(SUPR3HardenedLdrLoadAppPriv)\n"
-            "    add     rsp, 08h\n"
-            "\n"
-            "%%elifdef ASM_CALL64_MSC\n"
-            "    xor     r9, r9                 ; pErrInfo\n"
-            "    xor     r8, r8                 ; fFlags (local load)\n"
-            "    lea     rdx, [g_hMod wrt rip]  ; phLdrMod\n"
-            "    lea     rcx, [g_szLibrary wrt rip] ; pszFilename\n"
-            "    sub     rsp, 28h\n"
-            "    call    IMP2(SUPR3HardenedLdrLoadAppPriv)\n"
-            "    add     rsp, 28h\n"
-            "\n"
-            "%%elifdef RT_ARCH_X86\n"
-            "    sub     xSP, 0ch\n"
-            "    push    0              ; pErrInfo\n"
-            "    push    0              ; fFlags (local load)\n"
-            "    push    g_hMod         ; phLdrMod\n"
-            "    push    g_szLibrary    ; pszFilename\n"
-            "    call    IMP2(SUPR3HardenedLdrLoadAppPriv)\n"
-            "    add     esp, 1ch\n"
-            "%%else\n"
-            " %%error \"Unsupported architecture\"\n"
-            "%%endif\n"
+    if (!g_fSystemLibrary)
+        fprintf(pOutput,
+                ";\n"
+                ";SUPR3DECL(int) SUPR3HardenedLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod,\n"
+                ";                                           uint32_t fFlags, PRTERRINFO pErrInfo);\n"
+                ";\n"
+                "EXTERN_IMP2 SUPR3HardenedLdrLoadAppPriv\n"
+                "%%ifdef IN_RT_R3\n"
+                "extern NAME(RTAssertMsg2Weak)\n"
+                "%%else\n"
+                "EXTERN_IMP2 RTAssertMsg2Weak\n"
+                "%%endif\n"
+                "BEGINCODE\n"
+                "\n"
+                "LazyLoading:\n"
+                "    mov     xCX, [g_hMod xWrtRIP]\n"
+                "    or      xCX, xCX\n"
+                "    jnz     .return\n"
+                "\n"
+                "%%ifdef ASM_CALL64_GCC\n"
+                "    xor     rcx, rcx               ; pErrInfo\n"
+                "    xor     rdx, rdx               ; fFlags (local load)\n"
+                "    lea     rsi, [g_hMod wrt rip]  ; phLdrMod\n"
+                "    lea     rdi, [g_szLibrary wrt rip] ; pszFilename\n"
+                "    sub     rsp, 08h\n"
+                "    call    IMP2(SUPR3HardenedLdrLoadAppPriv)\n"
+                "    add     rsp, 08h\n"
+                "\n"
+                "%%elifdef ASM_CALL64_MSC\n"
+                "    xor     r9, r9                 ; pErrInfo\n"
+                "    xor     r8, r8                 ; fFlags (local load)\n"
+                "    lea     rdx, [g_hMod wrt rip]  ; phLdrMod\n"
+                "    lea     rcx, [g_szLibrary wrt rip] ; pszFilename\n"
+                "    sub     rsp, 28h\n"
+                "    call    IMP2(SUPR3HardenedLdrLoadAppPriv)\n"
+                "    add     rsp, 28h\n"
+                "\n"
+                "%%elifdef RT_ARCH_X86\n"
+                "    sub     xSP, 0ch\n"
+                "    push    0              ; pErrInfo\n"
+                "    push    0              ; fFlags (local load)\n"
+                "    push    g_hMod         ; phLdrMod\n"
+                "    push    g_szLibrary    ; pszFilename\n"
+                "    call    IMP2(SUPR3HardenedLdrLoadAppPriv)\n"
+                "    add     esp, 1ch\n"
+                "%%else\n"
+                " %%error \"Unsupported architecture\"\n"
+                "%%endif\n");
+    else
+        fprintf(pOutput,
+                ";\n"
+                "; RTDECL(int) RTLdrLoadSystem(const char *pszFilename, bool fNoUnload, PRTLDRMOD phLdrMod);\n"
+                ";\n"
+                "%%ifdef IN_RT_R3\n"
+                "extern NAME(RTLdrLoadSystem)\n"
+                "extern NAME(RTAssertMsg2Weak)\n"
+                "%%else\n"
+                "EXTERN_IMP2 RTLdrLoadSystem\n"
+                "EXTERN_IMP2 RTAssertMsg2Weak\n"
+                "%%endif\n"
+                "BEGINCODE\n"
+                "\n"
+                "LazyLoading:\n"
+                "    mov     xCX, [g_hMod xWrtRIP]\n"
+                "    or      xCX, xCX\n"
+                "    jnz     .return\n"
+                "\n"
+                "%%ifdef ASM_CALL64_GCC\n"
+                "    lea     rdx, [g_hMod wrt rip]  ; phLdrMod\n"
+                "    mov     esi, 1                 ; fNoUnload=true\n"
+                "    lea     rdi, [g_szLibrary wrt rip] ; pszFilename\n"
+                "    sub     rsp, 08h\n"
+                " %%ifdef IN_RT_R3\n"
+                "    call    NAME(RTLdrLoadSystem)\n"
+                " %%else\n"
+                "    call    IMP2(RTLdrLoadSystem)\n"
+                " %%endif\n"
+                "    add     rsp, 08h\n"
+                "\n"
+                "%%elifdef ASM_CALL64_MSC\n"
+                "    lea     r8, [g_hMod wrt rip]   ; phLdrMod\n"
+                "    mov     edx, 1                 ; fNoUnload=true\n"
+                "    lea     rcx, [g_szLibrary wrt rip] ; pszFilename\n"
+                "    sub     rsp, 28h\n"
+                " %%ifdef IN_RT_R3\n"
+                "    call    NAME(RTLdrLoadSystem)\n"
+                " %%else\n"
+                "    call    IMP2(RTLdrLoadSystem)\n"
+                " %%endif\n"
+                "    add     rsp, 28h\n"
+                "\n"
+                "%%elifdef RT_ARCH_X86\n"
+                "    push    g_hMod         ; phLdrMod\n"
+                "    push    1              ; fNoUnload=true\n"
+                "    push    g_szLibrary    ; pszFilename\n"
+                " %%ifdef IN_RT_R3\n"
+                "    call    NAME(RTLdrLoadSystem)\n"
+                " %%else\n"
+                "    call    IMP2(RTLdrLoadSystem)\n"
+                " %%endif\n"
+                "    add     esp, 0ch\n"
+                "%%else\n"
+                " %%error \"Unsupported architecture\"\n"
+                "%%endif\n");
+    fprintf(pOutput,
             "    or      eax, eax\n"
-            "    jz      .loadok\n"
-            ".badload:\n"
-            "    int3\n"
-            "    jmp     .badload\n"
-            ".loadok:\n"
+            "    jnz    .badload\n"
             "    mov     xCX, [g_hMod xWrtRIP]\n"
             ".return:\n"
             "    ret\n"
+            "\n"
+            ".badload:\n"
+            "%%ifdef ASM_CALL64_GCC\n"
+            "    mov     edx, eax\n"
+            "    lea     rsi, [g_szLibrary wrt rip]\n"
+            "    lea     rdi, [g_szFailLoadFmt wrt rip]\n"
+            "    sub     rsp, 08h\n"
+            "%%elifdef ASM_CALL64_MSC\n"
+            "    mov     r8d, eax\n"
+            "    lea     rdx, [g_szLibrary wrt rip]\n"
+            "    lea     rcx, [g_szFailLoadFmt wrt rip]\n"
+            "    sub     rsp, 28h\n"
+            "%%elifdef RT_ARCH_X86\n"
+            "    push    eax\n"
+            "    push    g_szLibrary\n"
+            "    push    g_szFailLoadFmt\n"
+            "%%endif\n"
+            "%%ifdef IN_RT_R3\n"
+            "    call    NAME(RTAssertMsg2Weak)\n"
+            "%%else\n"
+            "    call    IMP2(RTAssertMsg2Weak)\n"
+            "%%endif\n"
+            ".badloadloop:\n"
+            "    int3\n"
+            "    jmp     .badloadloop\n"
             "LazyLoading_End:\n"
             "\n"
@@ -497,5 +663,9 @@
             ";RTDECL(int) RTLdrGetSymbol(RTLDRMOD hLdrMod, const char *pszSymbol, void **ppvValue);\n"
             ";\n"
+            "%%ifdef IN_RT_R3\n"
+            "extern NAME(RTLdrGetSymbol)\n"
+            "%%else\n"
             "EXTERN_IMP2 RTLdrGetSymbol\n"
+            "%%endif\n"
             "BEGINCODE\n"
             "LazyLoadResolver:\n"
@@ -531,11 +701,11 @@
             "    mov     r8, r14        ; ppvValue\n"
             " %%endif\n"
+            " %%ifdef IN_RT_R3\n"
+            "    call    NAME(RTLdrGetSymbol)\n"
+            " %%else\n"
             "    call    IMP2(RTLdrGetSymbol)\n"
+            " %%endif\n"
             "    or      eax, eax\n"
-            "    jz      .symok\n"
-            ".badsym:\n"
-            "    int3\n"
-            "    jmp     .badsym\n"
-            ".symok:\n"
+            "    jnz     .badsym\n"
             "\n"
             "    mov     rsp, r12\n"
@@ -562,17 +732,15 @@
             "\n"
             ".loaded:\n"
-            "    mov     eax, [ebp + 4] ; value addr\n"
-            "    push    eax\n"
-            "    mov     edx, [ebp + 8] ; symbol name\n"
-            "    push    edx\n"
-            "    call    LazyLoading    ; returns handle in ecx\n"
-            "    mov     ecx, [g_hMod]\n"
+            "    call    LazyLoading      ; returns handle in ecx\n"
+            "    push    dword [ebp + 8]  ; value addr\n"
+            "    push    dword [ebp + 12] ; symbol name\n"
+            "    push    ecx\n"
+            " %%ifdef IN_RT_R3\n"
+            "    call    NAME(RTLdrGetSymbol)\n"
+            " %%else\n"
             "    call    IMP2(RTLdrGetSymbol)\n"
+            " %%endif\n"
             "    or      eax, eax\n"
-            "    jz      .symok\n"
-            ".badsym:\n"
-            "    int3\n"
-            "    jmp     .badsym\n"
-            ".symok:\n"
+            "    jnz     .badsym\n"
             "    lea     esp, [ebp - 0ch]\n"
             "    pop     edx\n"
@@ -584,4 +752,33 @@
             "%%endif\n"
             "    ret\n"
+            "\n"
+            ".badsym:\n"
+            "%%ifdef ASM_CALL64_GCC\n"
+            "    mov     ecx, eax\n"
+            "    lea     rdx, [g_szLibrary wrt rip]\n"
+            "    mov     rsi, r15\n"
+            "    lea     rdi, [g_szFailResolveFmt wrt rip]\n"
+            "    sub     rsp, 08h\n"
+            "%%elifdef ASM_CALL64_MSC\n"
+            "    mov     r9d, eax\n"
+            "    mov     r8, r15\n"
+            "    lea     rdx, [g_szLibrary wrt rip]\n"
+            "    lea     rcx, [g_szFailResolveFmt wrt rip]\n"
+            "    sub     rsp, 28h\n"
+            "%%elifdef RT_ARCH_X86\n"
+            "    push    eax\n"
+            "    push    dword [ebp + 12]\n"
+            "    push    g_szLibrary\n"
+            "    push    g_szFailResolveFmt\n"
+            "%%endif\n"
+            "%%ifdef IN_RT_R3\n"
+            "    call    NAME(RTAssertMsg2Weak)\n"
+            "%%else\n"
+            "    call    IMP2(RTAssertMsg2Weak)\n"
+            "%%endif\n"
+            ".badsymloop:\n"
+            "    int3\n"
+            "    jmp     .badsymloop\n"
+            "\n"
             "LazyLoadResolver_End:\n"
             "\n"
@@ -597,4 +794,10 @@
     if (g_fWithExplictLoadFunction)
     {
+        if (g_fSystemLibrary) /* Lazy bird. */
+        {
+            fprintf(stderr, "error: cannot use --system with --explicit-load-function, sorry\n");
+            return RTEXITCODE_FAILURE;
+        }
+
         int cchLibBaseName = (int)(strchr(g_pszLibrary, '.') ? strchr(g_pszLibrary, '.') - g_pszLibrary : strlen(g_pszLibrary));
         fprintf(pOutput,
@@ -835,4 +1038,6 @@
             else if (!strcmp(psz, "--no-explicit-load-function"))
                 g_fWithExplictLoadFunction = false;
+            else if (!strcmp(psz, "--system"))
+                g_fSystemLibrary = true;
             /** @todo Support different load methods so this can be used on system libs and
              *        such if we like. */
