Valid HTML 4.01 Transitional Valid CSS Valid SVG 1.0

Me, myself & IT

Bugs in module loader of Windows® 10 and LINK.EXE version 14.1*

Introduction
Manifestation
Demonstration
Security Impact
MSRC Case 56011
Demonstration (continued)
Demonstration (completed)

Introduction

Windows 10 1607 alias Anniversary Update, codenamed Redstone 1, introduced the feature to change and restrict the search path for the Win32 function LoadLibrary() through the /DEPENDENTLOADFLAG § linker option:
/DEPENDENTLOADFLAG[:load_flags]
[…]
On supported operating systems, this option has the effect of changing calls to LoadLibrary("dependent.dll") to the equivalent of LoadLibraryEx("dependent.dll", 0, load_flags).
[…]
This flag can be used to make DLL planting attacks more difficult.
[…]
An option of /DEPENDENTLOADFLAG:0x800 is even more restrictive, limiting search to the %windows%\system32 directory.
Note: the text cited above shows the original and wrong documentation, present until January 24, 2020.

§ This option is supported by LINK.EXE since version 14.10, shipped with Visual Studio 2017 and newer versions; to use the feature with prior versions of LINK.EXE, provide an initialised (constant) IMAGE_LOAD_CONFIG_DIRECTORY structure with public name _load_config_used and its DependentLoadFlags (former Reserved1) member set to the desired value.

The MSDN article Dynamic-Link Library Search Order documents the standard search path.

The values for /DEPENDENTLOADFLAG are documented with the LoadLibraryEx() function:

[…]
LOAD_LIBRARY_SEARCH_APPLICATION_DIR
0x00000200
If this value is used, the application's installation directory is searched for the DLL and its dependencies. Directories in the standard search path are not searched. […]
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
0x00001000
This value is a combination of LOAD_LIBRARY_SEARCH_APPLICATION_DIR, LOAD_LIBRARY_SEARCH_SYSTEM32, and LOAD_LIBRARY_SEARCH_USER_DIRS. Directories in the standard search path are not searched. […]
[…]
LOAD_LIBRARY_SEARCH_SYSTEM32
0x00000800
If this value is used, %windows%\system32 is searched for the DLL and its dependencies. Directories in the standard search path are not searched. […]
LOAD_LIBRARY_SEARCH_USER_DIRS
0x00000400
If this value is used, directories added using the AddDllDirectory or the SetDllDirectory function are searched for the DLL and its dependencies. If more than one directory has been added, the order in which the directories are searched is unspecified. Directories in the standard search path are not searched. […]
[…]

If more than one LOAD_LIBRARY_SEARCH flag is specified, the directories are searched in the following order:

Especially notice the highlighted statement common to all flag descriptions there: directories in the standard search path are not searched.

Manifestation

This feature but does not work as advertised, the bugs render it void: /DEPENDENTLOADFLAG:… is ignored completely and no restriction is applied to the search path for the Win32 function LoadLibrary()!

Demonstration

Perform the following 5 simple steps to demonstrate the bugs.
  1. Create the text file SNAFU.C with the following content in an arbitrary, preferable empty directory:

    // Copyright © 2016-2020, Stefan Kanthak <‍stefan‍.‍kanthak‍@‍nexgo‍.‍de‍>
    
    #define STRICT
    #define WIN32_LEAN_AND_MEAN
    
    #include <windows.h>
    
    #ifdef DLL
    #pragma comment(linker, "/DEFAULTLIB:KERNEL32.LIB")
    #pragma comment(linker, "/DLL")
    #pragma comment(linker, "/ENTRY:_DllMainCRTStartup")
    #pragma comment(linker, "/EXPORT:_SNAFU,DATA")
    #pragma comment(linker, "/SUBSYSTEM:CONSOLE")
    
    __declspec(dllexport)
    const	CHAR	SNAFU[] = "Situation normal, all\b\b\bjust \"/DEPENDENTLOADFLAG\" fucked up!\n";
    
    const	LPCSTR	szReason[] = {"DLL_PROCESS_DETACH\n",
    		              "DLL_PROCESS_ATTACH\n",
    		              "DLL_THREAD_ATTACH\n",
    		              "DLL_THREAD_DETACH\n"};
    
    BOOL	WINAPI	_DllMainCRTStartup(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
    {
    #ifdef VERBOSE
    	DWORD	dwConsole;
    
    	WriteConsoleA(GetStdHandle(STD_ERROR_HANDLE), szReason[dwReason], lstrlenA(szReason[dwReason]), &dwConsole, NULL);
    #else
    	OutputDebugStringA(szReason[dwReason]);
    #endif
    	return FALSE;
    }
    #else
    #pragma comment(linker, "/DEFAULTLIB:KERNEL32.LIB")
    #pragma comment(linker, "/ENTRY:mainCRTStartup")
    #pragma comment(linker, "/SUBSYSTEM:CONSOLE")
    
    #ifdef LOADTIME
    #pragma comment(linker, "/DEFAULTLIB:SNAFU.LIB")
    
    __declspec(dllimport)
    extern	const	CHAR	SNAFU[];
    
    __declspec(noreturn)
    VOID	WINAPI	mainCRTStartup(VOID)
    {
    #ifdef VERBOSE
    	DWORD	dwConsole;
    
    	WriteConsoleA(GetStdHandle(STD_ERROR_HANDLE), SNAFU, lstrlenA(SNAFU), &dwConsole, NULL);
    #else
    	OutputDebugStringA(SNAFU);
    #endif
    	ExitProcess(0);
    }
    #else
    __declspec(noreturn)
    VOID	WINAPI	mainCRTStartup(VOID)
    {
    	HMODULE	hModule = LoadLibraryA("SNAFU.DLL");
    
    	if (hModule == NULL)
    		ExitProcess(GetLastError());
    
    	if (!FreeLibrary(hModule))
    		ExitProcess(GetLastError());
    
    	ExitProcess(0);
    }
    #endif // LOADTIME
    #endif // DLL
    
    #ifdef LCU
    #ifndef _WIN64
    const	struct	_LOAD_CONFIG_USED_32
    {
    	DWORD	Size;
    	DWORD	TimeDateStamp;
    	WORD	MajorVersion;
    	WORD	MinorVersion;
    	DWORD	GlobalFlagsClear;
    	DWORD	GlobalFlagsSet;
    	DWORD	CriticalSectionDefaultTimeout;
    	DWORD	DeCommitFreeBlockThreshold;
    	DWORD	DeCommitTotalFreeThreshold;
    	DWORD	LockPrefixTable;
    	DWORD	MaximumAllocationSize;
    	DWORD	VirtualMemoryThreshold;
    	DWORD	ProcessHeapFlags;
    	DWORD	ProcessAffinityMask;
    	WORD	CSDVersion;
    	WORD	DependentLoadFlags;
    	DWORD	EditList;
    	DWORD	SecurityCookie;
    	DWORD	SEHandlerTable;
    	DWORD	SEHandlerCount;
    #ifdef SPOILER
    	DWORD	GuardCFCheckFunctionPointer;
    	DWORD	GuardCFDispatchFunctionPointer;
    	DWORD	GuardCFFunctionTable;
    	DWORD	GuardCFFunctionCount;
    	DWORD	GuardFlags;
    #endif
    } _load_config_used = {sizeof(_load_config_used)};
    #else
    const	struct	_LOAD_CONFIG_USED_64
    {
    	DWORD	Size;
    	DWORD	TimeDateStamp;
    	WORD	MajorVersion;
    	WORD	MinorVersion;
    	DWORD	GlobalFlagsClear;
    	DWORD	GlobalFlagsSet;
    	DWORD	CriticalSectionDefaultTimeout;
    	DWORD64	DeCommitFreeBlockThreshold;
    	DWORD64	DeCommitTotalFreeThreshold;
    	DWORD64	LockPrefixTable;
    	DWORD64	MaximumAllocationSize;
    	DWORD64	VirtualMemoryThreshold;
    	DWORD64	ProcessAffinityMask;
    	DWORD	ProcessHeapFlags;
    	WORD	CSDVersion;
    	WORD	DependentLoadFlags;
    	DWORD64	EditList;
    	DWORD64	SecurityCookie;
    	DWORD64	SEHandlerTable;
    	DWORD64	SEHandlerCount;
    #ifdef SPOILER
    	DWORD64	GuardCFCheckFunctionPointer;
    	DWORD64	GuardCFDispatchFunctionPointer;
    	DWORD64	GuardCFFunctionTable;
    	DWORD64	GuardCFFunctionCount;
    	DWORD	GuardFlags;
    #endif
    } _load_config_used = {sizeof(_load_config_used)};
    #endif // _WIN64
    #endif // LCU
    Note: the entry-point function _DllMainCRTStartup() intentionally returns FALSE to force an error on DLL load!
  2. Build the DLL SNAFU.DLL and the application SNAFU.EXE from the source file SNAFU.C created in step 1.:

    SET CL=/GF /Gy /W4 /Zl
    SET LINK=/DEPENDENTLOADFLAG:0x800 /DYNAMICBASE /NXCOMPAT /OPT:REF /OSVERSION:10.01 /RELEASE
    CL.EXE /DDLL /LD SNAFU.C
    CL.EXE SNAFU.C
    Note: if necessary, see the MSDN article Use the Microsoft C++ toolset from the command line for an introduction.

    Note: both portable executables build without the MSVCRT libraries.

    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 19.16.27027.1 for x86
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    SNAFU.C
    SNAFU.C(23) : warning C4100: 'lpReserved' : unreferenced formal parameter
    SNAFU.C(23) : warning C4100: 'dwReason' : unreferenced formal parameter
    SNAFU.C(23) : warning C4100: 'hModule' : unreferenced formal parameter
    
    Microsoft (R) Incremental Linker Version 14.16.27027.1
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    /DEPENDENTLOADFLAG:0x800 /DYNAMICBASE /NXCOMPAT /OPT:REF /OSVERSION:10.01 /RELEASE
    /out:SNAFU.dll
    /dll
    /implib:SNAFU.lib
    SNAFU.obj
       Creating library SNAFU.lib and object SNAFU.exp
    
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 19.16.27027.1 for x86
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    SNAFU.C
    
    Microsoft (R) Incremental Linker Version 14.16.27027.1
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    /DEPENDENTLOADFLAG:0x800 /DYNAMICBASE /NXCOMPAT /OPT:REF /OSVERSION:10.01 /RELEASE
    /out:SNAFU.exe
    SNAFU.obj
  3. Check whether at least the application SNAFU.EXE built in step 2. has /DEPENDENTLOADFLAG set:

    LINK.EXE /DUMP /HEADERS /LOADCONFIG SNAFU.EXE
    Microsoft (R) COFF/PE Dumper Version 14.16.27027.1
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    
    Dump of file SNAFU.EXE
    
    PE signature found
    
    File Type: EXECUTABLE IMAGE
    
    FILE HEADER VALUES
                 14C machine (x86)
                   3 number of sections
            5E224C34 time date stamp Sat Jan 18 01:07:16 2020
                   0 file pointer to symbol table
                   0 number of symbols
                  E0 size of optional header
                 102 characteristics
                       Executable
                       32 bit word machine
    
    OPTIONAL HEADER VALUES
                 10B magic # (PE32)
               14.16 linker version
                 200 size of code
                 400 size of initialized data
                   0 size of uninitialized data
                1000 entry point (00401000)
                1000 base of code
                2000 base of data
              400000 image base (00400000 to 00403FFF)
                1000 section alignment
                 200 file alignment
               10.01 operating system version
                1.00 image version
                6.00 subsystem version
                   0 Win32 version
                4000 size of image
                 400 size of headers
                F6A9 checksum
                   3 subsystem (Windows CUI)
                8540 DLL characteristics
                       Dynamic base
                       NX compatible
                       No structured exception handler
                       Terminal Server Aware
              100000 size of stack reserve
                1000 size of stack commit
              100000 size of heap reserve
                1000 size of heap commit
                   0 loader flags
                  10 number of directories
                   0 [       0] RVA [size] of Export Directory
                20F0 [      28] RVA [size] of Import Directory
                   0 [       0] RVA [size] of Resource Directory
                   0 [       0] RVA [size] of Exception Directory
                   0 [       0] RVA [size] of Certificates Directory
                3000 [      18] RVA [size] of Base Relocation Directory
                2030 [      1C] RVA [size] of Debug Directory
                   0 [       0] RVA [size] of Architecture Directory
                   0 [       0] RVA [size] of Global Pointer Directory
                   0 [       0] RVA [size] of Thread Storage Directory
                   0 [       0] RVA [size] of Load Configuration Directory
                   0 [       0] RVA [size] of Bound Import Directory
                2000 [      20] RVA [size] of Import Address Table Directory
                   0 [       0] RVA [size] of Delay Import Directory
                   0 [       0] RVA [size] of COM Descriptor Directory
                   0 [       0] RVA [size] of Reserved Directory
    …
    Oops!
    LINK.EXE fails to generate and include the IMAGE_LOAD_CONFIG_DIRECTORY structure which holds the /DEPENDENTLOADFLAG in its DependentLoadFlags member!
    Contrary to the observed behaviour, the specification of the PE format but states:
    The load configuration structure (IMAGE_LOAD_CONFIG_DIRECTORY) was formerly used in very limited cases in the Windows NT operating system itself to describe various features too difficult or too large to describe in the file header or optional header of the image. Current versions of the Microsoft linker and Windows XP and later versions of Windows use a new version of this structure for 32-bit x86-based systems that include reserved SEH technology.
    […]
    The Microsoft linker automatically provides a default load configuration structure to include the reserved SEH data. If the user code already provides a load configuration structure, it must include the new reserved SEH fields. Otherwise, the linker cannot include the reserved SEH data and the image is not marked as containing reserved SEH.
    Ouch!
    LINK.EXE also fails to report this omission with an appropriate error message!
  4. Build the application SNAFU.EXE again from the source file SNAFU.C created in step 1., now with the macro LCU (and in consequence a load configuration structure named _load_config_used) defined, and verify that /DEPENDENTLOADFLAG is properly set:

    CL.EXE /DLCU SNAFU.C
    LINK.EXE /DUMP /HEADERS /LOADCONFIG SNAFU.EXE
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 19.16.27027.1 for x86
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    SNAFU.C
    
    Microsoft (R) Incremental Linker Version 14.16.27027.1
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    /DEPENDENTLOADFLAG:0x800 /DYNAMICBASE /NXCOMPAT /OPT:REF /OSVERSION:10.01 /RELEASE
    /out:SNAFU.exe
    SNAFU.obj
    
    Microsoft (R) Incremental Linker Version 14.16.27027.1
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    
    Dump of file SNAFU.EXE
    
    PE signature found
    
    File Type: EXECUTABLE IMAGE
    
    FILE HEADER VALUES
                 14C machine (x86)
                   3 number of sections
            5E224C9D time date stamp Sat Jan 18 01:09:01 2020
                   0 file pointer to symbol table
                   0 number of symbols
                  E0 size of optional header
                 102 characteristics
                       Executable
                       32 bit word machine
    
    OPTIONAL HEADER VALUES
                 10B magic # (PE32)
               14.16 linker version
                 200 size of code
                 400 size of initialized data
                   0 size of uninitialized data
                1000 entry point (00401000)
                1000 base of code
                2000 base of data
              400000 image base (00400000 to 00403FFF)
                1000 section alignment
                 200 file alignment
               10.01 operating system version
                1.00 image version
                6.00 subsystem version
                   0 Win32 version
                4000 size of image
                 400 size of headers
                62D1 checksum
                   3 subsystem (Windows CUI)
                8540 DLL characteristics
                       Dynamic base
                       NX compatible
                       No structured exception handler
                       Terminal Server Aware
              100000 size of stack reserve
                1000 size of stack commit
              100000 size of heap reserve
                1000 size of heap commit
                   0 loader flags
                  10 number of directories
                   0 [       0] RVA [size] of Export Directory
                2190 [      28] RVA [size] of Import Directory
                   0 [       0] RVA [size] of Resource Directory
                   0 [       0] RVA [size] of Exception Directory
                   0 [       0] RVA [size] of Certificates Directory
                3000 [      18] RVA [size] of Base Relocation Directory
                20D0 [      1C] RVA [size] of Debug Directory
                   0 [       0] RVA [size] of Architecture Directory
                   0 [       0] RVA [size] of Global Pointer Directory
                   0 [       0] RVA [size] of Thread Storage Directory
                2020 [      40] RVA [size] of Load Configuration Directory
                   0 [       0] RVA [size] of Bound Import Directory
                2000 [      20] RVA [size] of Import Address Table Directory
                   0 [       0] RVA [size] of Delay Import Directory
                   0 [       0] RVA [size] of COM Descriptor Directory
                   0 [       0] RVA [size] of Reserved Directory
    …
      Section contains the following load config:
    
                00000048 size
                       0 time date stamp
                    0.00 Version
                       0 GlobalFlags Clear
                       0 GlobalFlags Set
                       0 Critical Section Default Timeout
                       0 Decommit Free Block Threshold
                       0 Decommit Total Free Threshold
                00000000 Lock Prefix Table
                       0 Maximum Allocation Size
                       0 Virtual Memory Threshold
                       0 Process Heap Flags
                       0 Process Affinity Mask
                       0 CSD Version
                    0800 Dependent Load Flag
                00000000 Edit list
                00000000 Security Cookie
                00000000 Safe Exception Handler Table
                       0 Safe Exception Handler Count
    …
    Notice the wrong size (0x40 instead of 0x48) for the IMAGE_LOAD_CONFIG_DIRECTORY structure in the 11th entry of the IMAGE_DATA_DIRECTORY array in the IMAGE_OPTIONAL_HEADER structure!
  5. Execute the application SNAFU.EXE built in step 4. to demonstrate the bug in Windows’ module loader:

    .\SNAFU.EXE
    ECHO %ERRORLEVEL%
    NET.EXE HELPMSG %ERRORLEVEL%
    1114
    
    A dynamic link library (DLL) initialization routine failed.
    Oops!
    Instead of the expected Win32 error code 126 alias ERROR_MOD_NOT_FOUND the application SNAFU.EXE returns the Win32 error code 1114 alias ERROR_DLL_INIT_FAILED, indicating that the Win32 function LoadLibrary() loaded the DLL SNAFU.DLL from the application directory, i.e. the search path was not limited to the system directory %SystemRoot%\System32\, and /DEPENDENTLOADFLAG:0x800 does not work as documented!
Note: the makefile SNAFU.MAK performs all necessary steps shown above (and below).

Security Impact

When working as advertised, /DEPENDENTLOADFLAG is were an easy to implement defense against well-known weaknesses like CWE-426: Untrusted Search Path, CWE-427: Uncontrolled Search Path Element and CWE-428: Unquoted Search Path or Element documented in the CWE, which allow well-known attacks like CAPEC-471: Search Order Hijacking documented in the CAPEC, also known as DLL spoofing, DLL preloading, directory poisoning, binary planting, DLL hijacking and DLL side-loading.

The posts MS09-014: Addressing the Safari Carpet Bomb vulnerability, More information about the DLL Preloading remote attack vector, An update on the DLL-preloading remote attack vector and Triaging a DLL planting vulnerability on Microsoft’s Security Research and Defense Blog give additional information on this ubiquituous vulnerabilty.

MSRC Case 56011

Due to their security impact I reported these bugs to the MSRC, where case number 56011 was assigned.

They replied with the following statements:

The team has finished their investigation and determined the way they will address this report is via a documentation update of https://docs.microsoft.com/en-us/cpp/build/reference/dependentloadflag?view=vs-2019.

It wasn't supposed to say that LoadLibrary will act as LoadLibraryEx, specifically this statement:

On supported operating systems, this option has the effect of changing calls to LoadLibrary("dependent.dll") to the equivalent of LoadLibraryEx("dependent.dll", 0, load_flags). Calls to LoadLibraryEx are unaffected. This option doesn't apply recursively to DLLs loaded by your app.

Notice that there’s no statement regarding the bugs in LINK.EXE!

According to the documentation changed in response to my report on January 24, 2020, /DEPENDENTLOADFLAG is now supposed to affect (static) load-time linking instead of (dynamic) runtime linking:

Sets the default load flags used when the operating system resolves the statically linked imports of a module.

/DEPENDENTLOADFLAG[:load_flags]

load_flags
An optional integer value that specifies the load flags to apply when resolving statically linked import dependencies of the module. The default value is 0. For a list of supported flag values, see the LOAD_LIBRARY_SEARCH_* entries in LoadLibraryEx.
[…]
[…] if you specify the link option /DEPENDENTLOADFLAG:0x800 (the value of the flag LOAD_LIBRARY_SEARCH_SYSTEM32), then the module search path is limited to the %windows%\system32 directory.

Note: the documentation still lacks (necessary) information similar to that given for the /SAFESEH linker option:
If you link with /NODEFAULTLIB and you want a table of safe exception handlers, you need to supply a load config struct (such as can be found in loadcfg.c CRT source file) that contains all the entries defined for Visual C++. For example: […]
Note: this also applies when the /Zl compiler option is used!

Demonstration (continued)

Perform the following additional 2 simple steps to prove the changed documentation wrong too.
  1. Build the application SNAFU.COM from the source file SNAFU.C created in step 1., now with the macros LCU and LOADTIME defined:

    CL.EXE /DLCU /DLOADTIME /FeSNAFU.COM SNAFU.C
    Note: if necessary, see the MSDN article Use the Microsoft C++ toolset from the command line for an introduction.

    Note: the portable executable SNAFU.COM builds without the MSVCRT libraries.

    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 19.16.27027.1 for x86
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    SNAFU.C
    
    Microsoft (R) Incremental Linker Version 14.16.27027.1
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    /DEPENDENTLOADFLAG:0x800 /DYNAMICBASE /NXCOMPAT /OPT:REF /OSVERSION:10.01 /RELEASE
    /out:SNAFU.COM
    SNAFU.obj
  2. Execute the application SNAFU.COM built in step 6. to demonstrate the bug in Windows’ module loader:

    .\SNAFU.COM
    ECHO %ERRORLEVEL%
    CERTUTIL.EXE /ERROR %ERRORLEVEL%
    [Screenshot of error message for NTSTATUS 0xC0000142 alias STATUS_DLL_INIT_FAILED]
    -1073741502
    0xc0000142 (-1073741502) -- 3221225794 (-1073741502)
    Error message text: {DLL Initialization Failed}
    Initialization of the dynamic link library %hs failed. The process is terminating abnormally.
    CertUtil: -error command completed successfully.
    Oops!
    -1073741502 is the decimal representation of 0xC0000142 alias STATUS_DLL_INIT_FAILED, indicating that SNAFU.DLL is loaded from the application directory, i.e. the search path was not limited to the system directory %SystemRoot%\System32\, and /DEPENDENTLOADFLAG:0x800 does not work as documented!

    Note: the expected error message and exit code is but 0xC0000135 alias STATUS_DLL_NOT_FOUND.

Demonstration (completed)

Perform the following final 2 simple steps to show the missing piece of the changed documentation, respectively the braindead implementation (detail) of this security feature in Windows’ module loader.
  1. Build the application SNAFU.COM from the source file SNAFU.C created in step 1. again, now with the macros LCU, LOADTIME and SPOILER defined:

    CL.EXE /DLCU /DLOADTIME /DSPOILER /FeSNAFU.COM SNAFU.C
    Note: if necessary, see the MSDN article Use the Microsoft C++ toolset from the command line for an introduction.

    Note: the portable executable SNAFU.COM builds without the MSVCRT libraries.

    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 19.16.27027.1 for x86
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    SNAFU.C
    
    Microsoft (R) Incremental Linker Version 14.16.27027.1
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    /DEPENDENTLOADFLAG:0x800 /DYNAMICBASE /NXCOMPAT /OPT:REF /OSVERSION:10.01 /RELEASE
    /out:SNAFU.COM
    SNAFU.obj
  2. Execute the application SNAFU.COM built in step 8. to demonstrate the bug fix:

    .\SNAFU.COM
    ECHO %ERRORLEVEL%
    CERTUTIL.EXE /ERROR %ERRORLEVEL%
    [Screenshot of error message for NTSTATUS 0xC0000135 alias STATUS_DLL_NOT_FOUND]
    -1073741515
    0xc0000135 (-1073741515) -- 3221225781 (-1073741515)
    Error message text: {Unable To Locate Component}
    This application has failed to start because %hs was not found. Reinstalling the application might fix this problem.
    CertUtil: -error command completed successfully.
    -1073741515 is the decimal representation of 0xC0000135 alias STATUS_DLL_NOT_FOUND.

    Conclusion: in order to honor the /DEPENDENTLOADFLAG linker option, Windows’ module loader expects an IMAGE_LOAD_CONFIG_DIRECTORY which includes the GuardFlags member at least!

    Note: the members GuardCFCheckFunctionPointer to GuardFlags were added with Windows 8.1 to the IMAGE_LOAD_CONFIG_DIRECTORY structure; the member DependentLoadFlags alias Reserved1 is but present there since Windows NT 3.1!

Contact

If you miss anything here, have additions, comments, corrections, criticism or questions, want to give feedback, hints or tipps, report broken links, bugs, deficiencies, errors, inaccuracies, misrepresentations, omissions, shortcomings, vulnerabilities or weaknesses, …: don’t hesitate to contact me and feel free to ask, comment, criticise, flame, notify or report!

Use the X.509 certificate to send S/MIME encrypted mail.

Note: email in weird format and without a proper sender name is likely to be discarded!

I dislike HTML (and even weirder formats too) in email, I prefer to receive plain text.
I also expect to see your full (real) name as sender, not your nickname.
I abhor top posts and expect inline quotes in replies.

Terms and Conditions

By using this site, you signify your agreement to these terms and conditions. If you do not agree to these terms and conditions, do not use this site!

Data Protection Declaration

This web page records no (personal) data and stores no cookies in the web browser.

The web service is operated and provided by

Telekom Deutschland GmbH
Business Center
D-64306 Darmstadt
Germany
<‍hosting‍@‍telekom‍.‍de‍>
+49 800 5252033

The web service provider stores a session cookie in the web browser and records every visit of this web site with the following data in an access log on their server(s):


Copyright © 1995–2020 • Stefan Kanthak • <‍stefan‍.‍kanthak‍@‍nexgo‍.‍de‍>