LINK.EXE
Version 14.1*LoadLibrary()
through the
/DEPENDENTLOADFLAG
§ linker option:
/DEPENDENTLOADFLAG[:load_flags]Note: the text cited above shows the original and wrong documentation, present until January 24, 2020.
[…]
On supported operating systems, this option has the effect of changing calls toLoadLibrary("dependent.dll")
to the equivalent ofLoadLibraryEx("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.
§ This option is supported by
LINK.EXE
since version 14.10, shipped with Visual Studio 2017
and newer versions; to use the security 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.
Caveat: older versions of
LINK.EXE
set
a wrong size for the
IMAGE_LOAD_CONFIG_DIRECTORY
structure in the
IMAGE_DATA_DIRECTORY
array; Windows’ module loader but
discards the
/DEPENDENTLOADFLAG
in portable executables
for the AMD64 alias
x64 processor architecture when this size doesn’t
match the size of the
_load_config_used
structure stored in its first member!
The values for
/DEPENDENTLOADFLAG
are documented with the
LoadLibraryEx()
function:
[…]Especially notice the highlighted statement common to all flag descriptions there: directories in the standard search path are not searched.
- 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:
- The directory that contains the DLL (LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR). This directory is searched only for dependencies of the DLL to be loaded.
- The application directory (LOAD_LIBRARY_SEARCH_APPLICATION_DIR).
- Paths explicitly added to the application search path with the AddDllDirectory function (LOAD_LIBRARY_SEARCH_USER_DIRS) or the SetDllDirectory function. If more than one path has been added, the order in which the paths are searched is unspecified.
- The System32 directory (LOAD_LIBRARY_SEARCH_SYSTEM32).
Note: the MSDN article Dynamic-Link Library Search Order documents the standard search path.
/DEPENDENTLOADFLAG:…
is ignored
completely and no restriction is applied to the
search path for the Win32 function
LoadLibrary()
!
Create the text file
SNAFU.C
with the following content in an arbitrary, preferable empty
directory:
// Copyright © 2016-2024, Stefan Kanthak <stefan.kanthak@nexgo.de>
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#ifdef _DLL
const LPCSTR szReason[4] = {"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;
}
__declspec(dllexport)
const CHAR SNAFU[] = "Situation normal, all\b\b\bbut \"/DEPENDENTLOADFLAG\" fucked up!\n";
#else
#ifdef LOADTIME
__declspec(dllimport)
extern const CHAR SNAFU[];
__declspec(noreturn)
VOID CDECL 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 CDECL mainCRTStartup(VOID)
{
DWORD dwError = ERROR_SUCCESS;
HMODULE hModule = LoadLibraryA("SNAFU.DLL");
if (hModule == NULL)
dwError = GetLastError();
else
if (!FreeLibrary(hModule))
dwError = GetLastError();
ExitProcess(dwError);
}
#endif // LOADTIME
#endif // _DLL
#ifdef LCU
#ifndef _WIN64
const struct _IMAGE_LOAD_CONFIG_DIRECTORY_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;
#if LCU > 2 // Redstone 1 (1607)
WORD DependentLoadFlags;
#else
WORD Reserved1;
#endif
DWORD EditList;
DWORD SecurityCookie;
DWORD SEHandlerTable;
DWORD SEHandlerCount;
#if LCU > 0 // Threshold 1 (1507)
DWORD GuardCFCheckFunctionPointer;
DWORD GuardCFDispatchFunctionPointer;
DWORD GuardCFFunctionTable;
DWORD GuardCFFunctionCount;
DWORD GuardFlags;
#if LCU > 1 // Threshold 2 (1511)
struct // _IMAGE_LOAD_CONFIG_CODE_INTEGRITY
{
WORD Flags;
WORD Catalog;
DWORD CatalogOffset;
DWORD Reserved;
} CodeIntegrity;
#if LCU > 2 // Redstone 1 (1607)
DWORD GuardAddressTakenIatEntryTable;
DWORD GuardAddressTakenIatEntryCount;
DWORD GuardLongJumpTargetTable;
DWORD GuardLongJumpTargetCount;
DWORD DynamicValueRelocTable;
DWORD CHPEMetadataPointer;
#if LCU > 3 // Redstone 2 (1703)
DWORD GuardRFFailureRoutine;
DWORD GuardRFFailureRoutineFunctionPointer;
DWORD DynamicValueRelocTableOffset;
WORD DynamicValueRelocTableSection;
WORD Reserved2;
DWORD GuardRFVerifyStackPointerFunctionPointer;
DWORD HotPatchTableOffset;
#if LCU > 4 // Redstone 3 (1709)
DWORD Reserved3;
DWORD EnclaveConfigurationPointer;
#if LCU > 5 // Redstone 4 (1803)
DWORD VolatileMetadataPointer;
#if LCU > 6 // Redstone 5 (1809)
DWORD GuardEHContinuationTable;
DWORD GuardEHContinuationCount;
#if LCU > 7 // Vibranium 3 (21H1)
DWORD GuardXFGCheckFunctionPointer;
DWORD GuardXFGDispatchFunctionPointer;
DWORD GuardXFGTableDispatchFunctionPointer;
#if LCU > 8 // Vibranium 4 (21H2)
DWORD CastGuardOsDeterminedFailureMode;
#if LCU > 9 // Vibranium 5 (22H2)
DWORD GuardMemcpyFunctionPointer;
#endif
#endif
#endif
#endif
#endif
#endif
#endif
#endif
#endif
#endif
} _load_config_used = {sizeof(_load_config_used), 'OUCH', _MSC_VER / 100, _MSC_VER % 100};
#else
const struct _IMAGE_LOAD_CONFIG_DIRECTORY_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;
#if LCU > 2 // Redstone 1 (1607)
WORD DependentLoadFlags;
#else
WORD Reserved1;
#endif
DWORD64 EditList;
DWORD64 SecurityCookie;
DWORD64 SEHandlerTable;
DWORD64 SEHandlerCount;
#if LCU > 0 // Threshold 1 (1507)
DWORD64 GuardCFCheckFunctionPointer;
DWORD64 GuardCFDispatchFunctionPointer;
DWORD64 GuardCFFunctionTable;
DWORD64 GuardCFFunctionCount;
DWORD GuardFlags;
#if LCU > 1 // Threshold 2 (1511)
struct // _IMAGE_LOAD_CONFIG_CODE_INTEGRITY
{
WORD Flags;
WORD Catalog;
DWORD CatalogOffset;
DWORD Reserved;
} CodeIntegrity;
#if LCU > 2 // Redstone 1 (1607)
DWORD64 GuardAddressTakenIatEntryTable;
DWORD64 GuardAddressTakenIatEntryCount;
DWORD64 GuardLongJumpTargetTable;
DWORD64 GuardLongJumpTargetCount;
DWORD64 DynamicValueRelocTable;
DWORD64 CHPEMetadataPointer;
#if LCU > 3 // Redstone 2 (1703)
DWORD64 GuardRFFailureRoutine;
DWORD64 GuardRFFailureRoutineFunctionPointer;
DWORD DynamicValueRelocTableOffset;
WORD DynamicValueRelocTableSection;
WORD Reserved2;
DWORD64 GuardRFVerifyStackPointerFunctionPointer;
DWORD HotPatchTableOffset;
#if LCU > 4 // Redstone 3 (1709)
DWORD Reserved3;
DWORD64 EnclaveConfigurationPointer;
#if LCU > 5 // Redstone 4 (1803)
DWORD64 VolatileMetadataPointer;
#if LCU > 6 // Redstone 5 (1809)
DWORD64 GuardEHContinuationTable;
DWORD64 GuardEHContinuationCount;
#if LCU > 7 // Vibranium 3 (21H1)
DWORD64 GuardXFGCheckFunctionPointer;
DWORD64 GuardXFGDispatchFunctionPointer;
DWORD64 GuardXFGTableDispatchFunctionPointer;
#if LCU > 8 // Vibranium 4 (21H2)
DWORD64 CastGuardOsDeterminedFailureMode;
#if LCU > 9 // Vibranium 5 (22H2)
DWORD64 GuardMemcpyFunctionPointer;
#endif
#endif
#endif
#endif
#endif
#endif
#endif
#endif
#endif
#endif
} _load_config_used = {sizeof(_load_config_used), 'OUCH', _MSC_VER / 100, _MSC_VER % 100};
#endif // _WIN64
#endif // LCU
Note: the
entry-point function
_DllMainCRTStartup()
intentionally returns
FALSE
to force an error on
DLL
load!
Build the DLL
SNAFU.DLL
and the console application
SNAFU.EXE
from the source file
SNAFU.C
created in step 1. for the i386 alias
x86 processor architecture:
SET CL=/GA /GF /Gw /Gy /W4 /wd4100 /Zl SET LINK=/DEPENDENTLOADFLAG:0x800 /DYNAMICBASE /LARGEADDRESSAWARE /MACHINE:I386 /NOCOFFGRPINFO /NODEFAULTLIB /OPT:REF /OSVERSION:10.01 /RELEASE /SUBSYSTEM:CONSOLE /VERSION:0.815 CL.EXE /LD /MD SNAFU.C KERNEL32.LIB CL.EXE SNAFU.C KERNEL32.LIBFor details and reference see the MSDN articles Compiler Options and Linker Options.
Note: if necessary, see the MSDN article Use the Microsoft C++ toolset from the command line for an introduction.
Note: both 32-bit portable executables
build
without the
MSVCRT
libraries.
Note: the command lines can be copied and pasted as block into a Command Processor window.
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 /LARGEADDRESSAWARE /MACHINE:I386 /NOCOFFGRPINFO /NODEFAULTLIB /OPT:REF /OSVERSION:10.01 /RELEASE /SUBSYSTEM:CONSOLE /VERSION:0.815 /out:SNAFU.dll /dll /implib:SNAFU.lib SNAFU.obj KERNEL32.LIB 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 /LARGEADDRESSAWARE /MACHINE:I386 /NOCOFFGRPINFO /NODEFAULTLIB /OPT:REF /OSVERSION:10.01 /RELEASE /SUBSYSTEM:CONSOLE /VERSION:0.815 /out:SNAFU.exe SNAFU.obj KERNEL32.LIB
Check whether at least the console 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 5DF38EE4 time date stamp Fri Dec 13 14:15:16 2019 0 file pointer to symbol table 0 number of symbols E0 size of optional header 122 characteristics Executable Application can handle large (>2GB) addresses 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 0.815 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 20D0 [ 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 0 [ 0] 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.Ouch: even worse,
[…]
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.
LINK.EXE
also fails to report this omission with an appropriate error
message!
The specification of the PE format continues with the following, completely wrong information:
Load Configuration LayoutOuch: according toThe load configuration structure has the following layout for 32-bit and 64-bit PE files:
Offset Size Field Description 0 4 Characteristics Flags that indicate attributes of the file, currently unused. […] 54/78 2 Reserved Must be zero.
IMAGE_LOAD_CONFIG_DIRECTORY
,
the field at offset 0 gives the size of the structure, and the field
at offset 54 (for 32-bit images) or 78 (for 64-bit images) holds the
/DEPENDENTLOADFLAG
!
Build the console application
SNAFU.EXE
again from the source file
SNAFU.C
created in step 1., now with the preprocessor macro
LCU
(and in consequence a load configuration structure
named _load_config_used
) defined as 0, then verify that
/DEPENDENTLOADFLAG
is properly set:
CL.EXE /DLCU=0 SNAFU.C KERNEL32.LIB 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 /LARGEADDRESSAWARE /MACHINE:I386 /NOCOFFGRPINFO /NODEFAULTLIB /OPT:REF /OSVERSION:10.01 /RELEASE /SUBSYSTEM:CONSOLE /VERSION:0.815 /out:SNAFU.exe SNAFU.obj KERNEL32.LIB 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 5DF38EE4 time date stamp Fri Dec 13 14:15:16 2019 0 file pointer to symbol table 0 number of symbols E0 size of optional header 122 characteristics Executable Application can handle large (>2GB) addresses 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 0.815 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 2170 [ 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 0 [ 0] 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 4F554348 time date stamp Mon Mar 5 2012 23:50:48 19.16 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 …Oops: 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 from the
IMAGE_OPTIONAL_HEADER
structure!
Execute the console 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.Ouch: the console application
SNAFU.EXE
returns the Win32 error code 1114 alias
ERROR_DLL_INIT_FAILED
instead of the expected Win32 error code 126 alias
ERROR_MOD_NOT_FOUND
,
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).
/DEPENDENTLOADFLAG
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 vulnerability.
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.Note: there’s no statement regarding the multiple bugs inIt 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.
LINK.EXE
!
/DEPENDENTLOADFLAG
is now supposed to affect (static)
load-time linking
instead of (dynamic)
run-time linking:
Sets the default load flags used when the operating system resolves the statically linked imports of a module.Note: the documentation still lacks (necessary) information similar to that given for the/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 theLOAD_LIBRARY_SEARCH_*
entries in LoadLibraryEx.
[…]
[…] if you specify the link option/DEPENDENTLOADFLAG:0x800
(the value of the flagLOAD_LIBRARY_SEARCH_SYSTEM32
), then the module search path is limited to the %windows%\system32 directory.
/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!
Build the console application
SNAFU.COM
from the source file
SNAFU.C
created in step 1., now with the preprocessor macros
LCU
and LOADTIME
defined:
CL.EXE /DLCU=0 /DLOADTIME /FeSNAFU.COM SNAFU.C SNAFU.LIB KERNEL32.LIBFor details and reference see the MSDN articles Compiler Options and Linker Options.
Note: if necessary, see the MSDN article Use the Microsoft C++ toolset from the command line for an introduction.
Note: the 32-bit 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 /LARGEADDRESSAWARE /MACHINE:I386 /NOCOFFGRPINFO /NODEFAULTLIB /OPT:REF /OSVERSION:10.01 /RELEASE /SUBSYSTEM:CONSOLE /VERSION:0.815 /out:SNAFU.COM SNAFU.obj SNAFU.LIB KERNEL32.LIB
Execute the console application
SNAFU.COM
built in step 6. to demonstrate the bug in
Windows’ module loader:
.\SNAFU.COM ECHO %ERRORLEVEL% CERTUTIL.EXE /ERROR %ERRORLEVEL%
-1073741502 0xc0000142 (NT: 0xc0000142 STATUS_DLL_INIT_FAILED) -- 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.Ouch: -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; the expected error message and exit code is but
0xC0000135
alias STATUS_DLL_NOT_FOUND
.
Build the console application SNAFU.COM
from the source
file
SNAFU.C
created in step 1. again, now with the preprocessor macro
LCU
defined as 1 or greater, and LOADTIME
defined too:
CL.EXE /DLCU=1 /DLOADTIME /FeSNAFU.COM SNAFU.C SNAFU.LIB KERNEL32.LIBFor details and reference see the MSDN articles Compiler Options and Linker Options.
Note: if necessary, see the MSDN article Use the Microsoft C++ toolset from the command line for an introduction.
Note: the 32-bit 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 /LARGEADDRESSAWARE /MACHINE:I386 /NOCOFFGRPINFO /NODEFAULTLIB /OPT:REF /OSVERSION:10.01 /RELEASE /SUBSYSTEM:CONSOLE /VERSION:0.815 /out:SNAFU.COM SNAFU.obj SNAFU.LIB KERNEL32.LIB
Execute the console application SNAFU.COM
built in
step 8. to demonstrate the bug fix:
.\SNAFU.COM ECHO %ERRORLEVEL% CERTUTIL.EXE /ERROR %ERRORLEVEL%
-1073741515 0xc0000135 (NT: 0xc0000135 STATUS_DLL_NOT_FOUND) -- 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 the expected error message and exit code 0xC0000135 alias
STATUS_DLL_NOT_FOUND
, indicating that the
application directorywas removed from the search path.
/DEPENDENTLOADFLAG
linker option in the i386 alias x86
execution environment, 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!
Note: a repetition of the preceding 2 steps with
the preprocessor macro LCU
defined as 2, 3, 4, 5, 6, 7,
8, 9 and 10 is left as an exercise to the reader.
Build the DLL
SNAFU.DLL
and the console application
SNAFU.COM
from the source file
SNAFU.C
created in step 1. for the AMD64 alias
x64 processor architecture:
SET CL=/GA /GF /Gw /Gy /W4 /wd4100 /Zl SET LINK=/DEPENDENTLOADFLAG:0x800 /DYNAMICBASE /HIGHENTROPYVA /MACHINE:AMD64 /NOCOFFGRPINFO /NODEFAULTLIB /OPT:REF /OSVERSION:10.01 /RELEASE /SUBSYSTEM:CONSOLE /VERSION:0.815 CL.EXE /LD /MD SNAFU.C KERNEL32.LIB CL.EXE /DLCU=0 /DLOADTIME /FeSNAFU.COM SNAFU.C SNAFU.LIB KERNEL32.LIBFor details and reference see the MSDN articles Compiler Options and Linker Options.
Note: if necessary, see the MSDN article Use the Microsoft C++ toolset from the command line for an introduction.
Note: both 64-bit portable executables
build
without the
MSVCRT
libraries.
Note: the command lines can be copied and pasted as block into a Command Processor window.
Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27027.1 for x64 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 /HIGHENTROPYVA /MACHINE:AMD64 /NOCOFFGRPINFO /NODEFAULTLIB /OPT:REF /OSVERSION:10.01 /RELEASE /SUBSYSTEM:CONSOLE /VERSION:0.815 /out:SNAFU.dll /dll /implib:SNAFU.lib SNAFU.obj KERNEL32.LIB Creating library SNAFU.lib and object SNAFU.exp Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27027.1 for x64 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 /HIGHENTROPYVA /MACHINE:AMD64 /NOCOFFGRPINFO /NODEFAULTLIB /OPT:REF /OSVERSION:10.01 /RELEASE /SUBSYSTEM:CONSOLE /VERSION:0.815 /out:SNAFU.COM SNAFU.obj SNAFU.LIB KERNEL32.LIB
Execute the console application
SNAFU.COM
built in step 10. to demonstrate the bug in
Windows’ module loader:
.\SNAFU.COM ECHO %ERRORLEVEL% CERTUTIL.EXE /ERROR %ERRORLEVEL%
-1073741502 0xc0000142 (NT: 0xc0000142 STATUS_DLL_INIT_FAILED) -- 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.Ouch: -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; the expected error message and exit code is but
0xC0000135
alias STATUS_DLL_NOT_FOUND
.
Build the console application SNAFU.COM
from the source
file
SNAFU.C
created in step 1. a last time, now with the preprocessor macro
LCU
defined as 1 or greater, and LOADTIME
defined too:
CL.EXE /DLCU=1 /DLOADTIME /FeSNAFU.COM SNAFU.C SNAFU.LIB KERNEL32.LIB
Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27027.1 for x64 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 /HIGHENTROPYVA /MACHINE:AMD64 /NOCOFFGRPINFO /NODEFAULTLIB /OPT:REF /OSVERSION:10.01 /RELEASE /SUBSYSTEM:CONSOLE /VERSION:0.815 /out:SNAFU.COM SNAFU.obj SNAFU.LIB KERNEL32.LIB
Execute the console application
SNAFU.COM
built in step 12. to demonstrate the bug fix:
.\SNAFU.COM ECHO %ERRORLEVEL% CERTUTIL.EXE /ERROR %ERRORLEVEL%
-1073741515 0xc0000135 (NT: 0xc0000135 STATUS_DLL_NOT_FOUND) -- 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 the expected error message and exit code 0xC0000135 alias
STATUS_DLL_NOT_FOUND
, indicating that the
application directorywas removed from the search path.
/DEPENDENTLOADFLAG
linker option in the AMD64 alias x64
execution environment, 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!
Note: a repetition of the preceding 2 steps with
the preprocessor macro LCU
defined as 2, 3, 4, 5, 6, 7,
8, 9 and 10 is left as an exercise to the reader.
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.
as iswithout any warranty, neither express nor implied.
cookiesin the web browser.
The web service is operated and provided by
Telekom Deutschland GmbH 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):