DLL_PROCESS_VERIFIER
as reason in its
DllMain()
DllMain()
_DllMainCRTStartup()
routine and then returns the address of an initialised
RTL_VERIFIER_PROVIDER_DESCRIPTOR
structure to
Windows’ module loader, specifying the names of
DLLs and the names
of entry points exported from these
DLLs which
Windows’ module loader shall redirect to
alternative addresses.
Caveat: the call of the
_DllMainCRTStartup()
routine with DLL_PROCESS_VERIFIER
as reason happens
before the call(s) with DLL_PROCESS_ATTACH
as reason!
Caveat: Application Verifier Providers
are loaded and initialised before the
DLLs which
implement the Win32
API; only
the native
API
implemented by NTDLL.dll
is
available for them!
See A Debugging Approach to IFEO and A Debugging Approach to Application Verifier for more details.
VRFKNTHK.DLL
is designed to discover some well-known and well-documented, but
nevertheless (way too) common VRFKNTHK.DLL
helps software developers, integrators,
packagers and testers to detect and fix these bugs in their own
Win32 applications and all
DLLs they use.
Note: VRFKNTHK.DLL
works independent
from Microsoft’s
Application Verifier!
industry standard, typically result in easy to exploit weaknesses and vulnerabilities.
VRFKNTHK.DLL
hooks the Win32 functions
(in alphabetical order)
AddDllDirectory()
,
ChangeServiceConfigA()
and
ChangeServiceConfigW()
,
CreateProcessA()
and
CreateProcessW()
,
CreateProcessAsUserA()
and
CreateProcessAsUserW()
,
CreateProcessInternalA()
and
CreateProcessInternalW()
,
CreateProcessWithLogonW()
,
CreateProcessWithTokenW()
,
CreateServiceA()
and
CreateServiceW()
,
LoadLibraryA()
and
LoadLibraryW()
,
LoadLibraryExA()
and
LoadLibraryExW()
,
LoadModule()
,
LoadPackagedLibrary()
,
RealShellExecuteA()
and
RealShellExecuteW()
,
RealShellExecuteExA()
and
RealShellExecuteExW()
,
SearchPathA()
and
SearchPathW()
,
SetDefaultDllDirectories()
,
SetDllDirectoryA()
and
SetDllDirectoryW()
,
SetSearchPathMode()
,
SHCreateProcessAsUserW()
,
ShellExecuteA()
and
ShellExecuteW()
,
ShellExecuteExA()
and
ShellExecuteExW()
,
WinExec()
plus
WOWShellExecute()
,
exported
from the DLLs
AdvAPI32.dll
,
Kernel32.dll
,
KernelBase.dll
,
SecHost.dll
and Shell32.dll
, to
log all calls of these Win32 functions with the values
of their arguments, to check the values of (some of) the arguments
and to call the native function
RtlApplicationVerifierStop()
to yield a
verifier stop
if one of the checks fails.
Caveat: due to a deficiency of Windows’ module loader, forwarded exports are not hooked!
Note: the checks performed for calls
of the Win32 functions CreateProcess*()
and LoadLibrary*()
don’t evaluate the
Registry entry
SafeProcessSearchMode.
Note: no checks are performed when the
Win32 function
LoadLibraryEx()
is called with the flag LOAD_LIBRARY_AS_DATAFILE
since
the DLL’s
_DllMainCRTStarup()
routine is not called then.
Note: the checks performed for calls of the
Win32 functions LoadLibrary*()
don’t evaluate the
known DLLs
since these vary with Windows NT versions.
Note: the checks performed for calls
of the Win32 functions LoadLibrary*()
don’t evaluate the Registry entry
SafeDllSearchMode.
Note: the checks performed for calls
of the Win32 functions LoadLibrary*()
don’t evaluate the Registry entry
CWDIllegalInDllSearch
since it does not exist per default and the optional update
2264107
which introduced it may not be installed on every system for which
it is available.
Note: the checks performed for calls of the
Win32 functions LoadLibrary*()
don’t evaluate the flags set by the Win32
function
SetDefaultDllDirectories()
since this Win32 function is not available on all
versions of Windows NT.
Note: the checks performed for calls of the
Win32 function
LoadLibraryEx()
don’t evaluate the flags to alter or restrict the search path
since the optional update
2533623
as well as the security update
MS12-081
alias
2758857
which introduced these flags are not available for all supported
versions of Windows NT and may not be installed on
every system for which they are available.
Note: the checks performed for calls of the
Win32 function
SearchPath()
don’t evaluate the flags set by the Win32
function
SetSearchPathMode()
since the security update
MS09-015
alias
959426
which introduced the latter Win32 function may not be
installed on every system for which it is available.
For every Win32 application
‹filename›.‹extension›
you
want to test, create the following
Registry
entries:
REGEDIT4
; Copyright © 2011-2025, Stefan Kanthak <stefan.kanthak@nexgo.de>
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\‹filename›.‹extension›]
"GlobalFlag"=dword:00000100
"VerifierDebug"=dword:00000000
"VerifierDlls"="VrfKnthk.dll"
"VerifierFlags"=dword:80000000
When
‹filename›.‹extension›
is
run under a debugger, each verifier stop prints a
debug message and yields a breakpoint; if run without debugger,
each verifier stop prints a debug message and
continues.
=========================================================== VERIFIER STOP 0000FFFF: pid 0x89DC: The application or a component it uses called LoadLibrary*() without providing an absolute local pathname for the module to load. 7C801B21 : LoadLibraryA 768817D8 : RichEd20.dll 76881DD8 : CRYPTUI.DLL+0x00001DD8 76881D80 : CRYPTUI.DLL+0x00001D80 =========================================================== This verifier stop is continuable. After debugging it use `go' to continue. ===========================================================is a typical debug message printed from a verifier stop of
VRFKNTHK.DLL
.
Profilefunction of Dependency Walker to watch the debug messages without a debugger.
bogusDLLs placed in the
application directory
%USERPROFILE%\Downloads\
of the example programs to
demonstrate their vulnerabilities act as transparent proxies to the
DLLs in
Windows’ system directory
%SystemRoot%\System32\
: they export all symbols and
ordinals of the corresponding originalDLL
‹filename›.DLL
, forward them to the
same symbols and ordinals of
System32\‹filename›.DLL
, and return
TRUE
from their _DllMainCRTStartup()
routine.
// Copyright © 2009-2025, Stefan Kanthak <stefan.kanthak@nexgo.de>
#pragma comment(linker, "/DEFAULTLIB:KERNEL32.LIB")
#pragma comment(linker, "/DLL")
#pragma comment(linker, "/ENTRY:_DllMainCRTStartup")
#pragma comment(linker, "/EXPORT:‹symbol›=System32\\‹filename›.‹symbol›,@‹ordinal›,PRIVATE")
…
#pragma comment(linker, "/EXPORT:‹ordinal›=System32\\‹filename›.#‹ordinal›,@‹ordinal›,NONAME,PRIVATE")
…
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
extern const IMAGE_DOS_HEADER __ImageBase;
// see <https://msdn.microsoft.com/en-us/library/ms682583.aspx>
// and <https://msdn.microsoft.com/en-us/library/ms682596.aspx>
BOOL WINAPI _DllMainCRTStartup(HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved)
{
// see <https://msdn.microsoft.com/en-us/library/ms680336.aspx>
// and <https://msdn.microsoft.com/en-us/library/ms680339.aspx>
// plus <https://msdn.microsoft.com/en-us/library/ms680305.aspx>
IMAGE_NT_HEADERS *ntHeader = (IMAGE_NT_HEADERS *) ((BYTE *) &__ImageBase + __ImageBase.e_lfanew);
DWORD dwRVA = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
LPCSTR szModule = "<unknown>";
if (dwRVA != 0)
{
dwRVA = ((IMAGE_EXPORT_DIRECTORY *) ((BYTE *) &__ImageBase + dwRVA))->Name;
if (dwRVA != 0)
szModule = (LPCSTR) ((BYTE *) &__ImageBase + dwRVA);
}
// see <https://msdn.microsoft.com/en-us/library/aa363362.aspx>
OutputDebugStringA(szModule);
return fdwReason == DLL_PROCESS_ATTACH;
}
7z1602.exe
and
7z1602-x64.exe
,
save them in the directory %USERPROFILE%\Downloads\
and execute them just until they display their first dialog box
which prompts for the target directory.
EXAMPLE0.TXT
shows the output from Windows’ command line
debugger
NTSD.exe
during execution of 7z1602.exe
on
Windows XP, where a bogus
UXTheme.dll
is loaded
from the program’s application directory
C:\Documents and Settings\Stefan\Downloads\
instead
Windows’ system directory
C:\Windows\System32\
.
EXAMPLE0.LOG
shows the output from Windows’ command line
debugger NTSD.exe
during execution of 7z1602-x64.exe
on 64-bit
Windows 7, where a bogus
UXTheme.dll
is loaded
from the program’s application directory
C:\Users\Stefan\Downloads\
instead
Windows’ system directory
C:\Windows\SysWOW64\
.
Note: on
Windows Vista® and newer versions of
Windows NT,
7z1602.exe
and 7z1602-x64.exe
request
administrative privileges via their embedded
application manifest
, resulting in an
EoP in addition
to the
LCE!
EXAMPLE1.TXT
shows the output from Windows’ command line
debugger
NTSD.exe
during execution of the program
// Copyright © 2009-2025, Stefan Kanthak <stefan.kanthak@nexgo.de>
#pragma comment(linker, "/DEFAULTLIB:KERNEL32.LIB")
#pragma comment(linker, "/ENTRY:WinMainCRTStartup")
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
#include <windows.h>
__declspec(noreturn)
VOID CDECL WinMainCRTStartup(VOID)
{
HMODULE hModule = LoadLibrary("C:\\Windows\\System32\\CryptUI.dll");
if (hModule == NULL)
ExitProcess(GetLastError());
if (!FreeLibrary(hModule))
ExitProcess(GetLastError());
ExitProcess(ERROR_SUCCESS);
}
on Windows XP, where a bogus
RichEd20.dll
is
loaded as
run-time dependency
of
CryptUI.dll
from the program’s application directory
C:\Documents and Settings\Stefan\Downloads\
instead Windows’ system directory
C:\Windows\System32\
.
Caveat: no fix available!
Use Software Restriction Policies alias SAFER to disable execution in untrusted directories!
EXAMPLE2.TXT
shows the output from Windows’ command line
debugger NTSD.exe
during execution of the program
// Copyright © 2009-2025, Stefan Kanthak <stefan.kanthak@nexgo.de>
#pragma comment(linker, "/DEFAULTLIB:KERNEL32.LIB")
#pragma comment(linker, "/ENTRY:WinMainCRTStartup")
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
#include <windows.h>
__declspec(noreturn)
VOID CDECL WinMainCRTStartup(VOID)
{
HMODULE hModule = LoadLibrary("C:\\Program Files\\Common Files\\System\\WAB32.dll");
if (hModule == NULL)
ExitProcess(GetLastError());
if (!FreeLibrary(hModule))
ExitProcess(GetLastError());
ExitProcess(ERROR_SUCCESS);
}
on Windows XP, where a bogus
MSOERT2.dll
is
loaded as
load-time dependency
of
WAB32.dll
from the program’s application directory
C:\Documents and Settings\Stefan\Downloads\
instead Windows’ system directory
C:\Windows\System32\
.
Note: to fix this weakness, call
LoadLibraryEx("C:\\Program Files\\Common Files\\System\\WAB32.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
to load WAB32.dll
!
EXAMPLE3.TXT
shows the output during execution of the 32-bit program from
example 2 on 64-bit Windows 7, where bogus
CryptDlg.dll
,
CryptUI.dll
,
MSOERT2.dll
,
UXTheme.dll
,
MSImg32.dll
,
Secur32.dll
,
Version.dll
and MSFTEdit.dll
are loaded from the program’s application directory
C:\Users\Stefan\Downloads\
instead
Windows’ system directory
C:\Windows\SysWoW64\
.
EXAMPLE3.LOG
shows the output during execution of the 64-bit program from
example 2 on 64-bit Windows 7, where bogus
CryptDlg.dll
,
CryptUI.dll
,
MSOERT2.dll
,
UXTheme.dll
,
MSImg32.dll
,
Secur32.dll
,
SSPICli.dll
,
Version.dll
and MSFTEdit.dll
are loaded from the program’s application directory
C:\Users\Stefan\Downloads\
instead
Windows’ system directory
C:\Windows\System32\
.
EXAMPLE4.TXT
shows the output from Windows’ command line
debugger NTSD.exe
during execution of the fixed32-bit program
// Copyright © 2009-2025, Stefan Kanthak <stefan.kanthak@nexgo.de>
#pragma comment(linker, "/DEFAULTLIB:KERNEL32.LIB")
#pragma comment(linker, "/ENTRY:WinMainCRTStartup")
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
#include <windows.h>
__declspec(noreturn)
VOID CDECL WinMainCRTStartup(VOID)
{
#ifdef _WIN64
HMODULE hModule = LoadLibraryEx("C:\\Program Files\\Common Files\\System\\WAB32.dll",
#else
HMODULE hModule = LoadLibraryEx("C:\\Program Files (x86)\\Common Files\\System\\WAB32.dll",
#endif
NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (hModule == NULL)
ExitProcess(GetLastError());
if (!FreeLibrary(hModule))
ExitProcess(GetLastError());
ExitProcess(ERROR_SUCCESS);
}
from example 2 on 64-bit Windows 7, where a bogus
Version.dll
is loaded as (indirect) load-time dependency and a bogus
MSFTEdit.dll
is
loaded as runtime dependency of
WAB32.dll
from the
program’s application directory
C:\Users\Stefan\Downloads\
instead
Windows’ system directory
C:\Windows\System32\
.
EXAMPLE4.LOG
shows the output during execution of the fixed
64-bit
program from example 2 on 64-bit Windows 7, where
bogus
SSPICli.dll
and
Version.dll
are loaded as (indirect) load-time dependencies and a bogus
MSFTEdit.dll
is
loaded as runtime dependency of
WAB32.dll
from the
program’s application directory
C:\Users\Stefan\Downloads\
instead
Windows’ system directory
C:\Windows\System32\
.
Note: to fix the first weakness, embed the Application Manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<file name="SSPICli.dll"
loadFrom="%SystemRoot%\System32\SSPICli.dll" />
<file name="Version.dll"
loadFrom="%SystemRoot%\System32\Version.dll" />
</assembly>
in the program!
loadFrom
attribute of the
file
element is not documented by
Microsoft!
Note: to fix the second weakness, call
SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32);
before any other Win32 function in your programs!
_DllMainCRTStartup()
routines of load-time dependencies are called from
Windows’ module loader before your
program’s startup routine!
SetDefaultDllDirectories()
available!
SetDefaultDllDirectories()
!
EXAMPLE5.TXT
shows the output from Windows’ command line
debugger NTSD.exe
during execution of the program
// Copyright © 2009-2025, Stefan Kanthak <stefan.kanthak@nexgo.de>
#pragma comment(linker, "/DEFAULTLIB:KERNEL32.LIB")
#pragma comment(linker, "/DEFAULTLIB:OLE32.LIB")
#pragma comment(linker, "/DEFAULTLIB:SHELL32.LIB")
#pragma comment(linker, "/ENTRY:WinMainCRTStartup")
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
#define _WIN32_WINNT 0x0500
#include <windows.h>
__declspec(noreturn)
VOID CDECL WinMainCRTStartup(VOID)
{
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (hr == S_OK)
hr = ShellExecute(NULL, NULL, "..", NULL, NULL, SW_SHOWNORMAL);
CoUninitialize();
ExitProcess(hr);
}
on Windows XP, where bogus
ClbCatQ.dll
,
COMRes.dll
,
RichEd20.dll
and
SetupAPI.dll
are loaded as
runtime dependencies of
OLE32.dll
and
CryptUI.dll
, and a
bogus Shell32.dll
is
loaded as load-time dependency of
ClbCatQ.dll
from the
program’s application directory
C:\Documents and Settings\Stefan\Downloads\
instead Windows’ system directory
C:\Windows\System32\
.
Caveat: no fix available!
Use Software Restriction Policies alias SAFER to disable execution in untrusted directories!
EXAMPLE6.TXT
shows the output during execution of the 32-bit program from
example 5 on 64-bit Windows 7, where bogus
PropSys.dll
,
AppHelp.dll
,
NTMARTA.dll
,
CryptSP.dll
,
RPCRTRemote.dll
and
SxS.dll
are loaded as runtime dependencies of
Shell32.dll
,
AdvAPI32.dll
,
OLE32.dll
,
RPCRT4.dll
and
OLEAut32.dll
, and a bogus
Version.dll
is loaded as load-time dependency of
IEFrame.dll
from the
program’s application directory
C:\Users\Stefan\Downloads\
instead
Windows’ system directory
C:\Windows\SysWoW64\
.
EXAMPLE6.LOG
shows the output during execution of the 64-bit program from
example 5 on 64-bit Windows 7, where bogus
CryptBase.dll
,
PropSys.dll
,
AppHelp.dll
,
NTMARTA.dll
,
CryptSP.dll
,
RPCRTRemote.dll
and
SxS.dll
are loaded as runtime dependencies of
RPCRT4.dll
,
Shell32.dll
,
AdvAPI32.dll
,
OLE32.dll
and
OLEAut32.dll
, and a bogus
Version.dll
is loaded as load-time dependency of
IEFrame.dll
from the
program’s application directory
C:\Users\Stefan\Downloads\
instead
Windows’ system directory
C:\Windows\System32\
.
Note: to fix the first weakness, call
SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32);
before any other Win32 function in your programs!
_DllMainCRTStartup()
routines of load-time dependencies are called from
Windows’ module loader before your
program’s startup routine!
SetDefaultDllDirectories()
available!
SetDefaultDllDirectories()
!
Note: to fix the second weakness, embed the Application Manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<file name="Version.dll"
loadFrom="%SystemRoot%\System32\Version.dll" />
</assembly>
in the program!
loadFrom
attribute of the
file
element is not documented by
Microsoft!
CreateProcess*()
according to the
MSDN article
Using Application Verifier Within Your Software Development Lifecycle:
Calls to the CreateProcess API function are subject to attack if parameters are not specified correctly. AppVerifier generates an error if CreateProcess (or other related API functions) are called with a NULL lpApplicationName parameter and an lpCommandLine parameter that contains spaces. For example, it does not allow the following as the command line parameter:Unfortunately the MSDN article but tells a blatant lie: Application Verifier does not perform the check described there!c:\program files\sample.exe -t -g c:\program files\sample\testUsing this command line, an application can inadvertently execute unwanted code if a malicious user installs his program to C:\Program.
Follow the instructions given in the
MSDN articles
Dynamic-Link Library Security
and
Dynamic-Link Library Search Order,
the Security Advisory
2269637,
plus the
MSKB
articles
2389418
and
2533623:
always use absolute (fully qualified) pathnames in
all calls of the Win32 functions
LoadLibrary()
,
LoadLibraryEx()
and
LoadPackagedLibrary()
,
CreateProcess()
,
CreateProcessAsUser()
,
CreateProcessWithLogonW()
and
CreateProcessWithTokenW()
,
SHCreateProcessAsUserW()
,
ShellExecute()
and
ShellExecuteEx()
,
as well as
LoadModule()
and
WinExec()
!
Use lpApplicationName
in all calls of
the Win32 functions
CreateProcess()
,
CreateProcessAsUser()
,
CreateProcessWithLogonW()
and
CreateProcessWithTokenW()
.
Replace all calls of the Win32
function
LoadLibrary()
which use an absolute (fully qualified) pathname with calls of the
Win32 function
LoadLibraryEx()
and use the flag LOAD_WITH_ALTERED_SEARCH_PATH
:
this replaces during these calls the application directory
with the directory of the just loading executable module in the
search order.
Caveat: this fails with some (indirect) load-time dependencies!
Replace all calls of the Win32
function
LoadLibrary()
which load DLLs
from Windows’
system directory
%SystemRoot%\System32\
with calls of the
Win32 function
LoadLibraryEx()
and specify the flag LOAD_LIBRARY_SEARCH_SYSTEM32
.
Caveat: this fails with some (indirect) load-time
dependencies!
Caveat: on Windows Vista,
Windows Server 2008, Windows 7 and
Windows Server 2008 R2, your users have to install the
optional update
2533623
(available per Windows Update) security
update
MS12-081
alias
2758857
(or any newer update that supersedes it) to make the
backported flag LOAD_LIBRARY_SEARCH_SYSTEM32
available!
Use the flag LOAD_LIBRARY_SEARCH_SYSTEM32
in
all calls of the Win32 function
LoadLibraryEx()
when loading DLLs
from Windows’ system directory
or when
loading DLLs which
are linked to DLLs
from Windows’ system directory
only.
Caveat: this fails with some (indirect) load-time
dependencies!
Caveat: on Windows Vista,
Windows Server 2008, Windows 7 and
Windows Server 2008 R2, your users have to install the
optional update
2533623
(available per Windows Update) security
update
MS12-081
alias
2758857
(or any newer update that supersedes it) to make the
backported flag LOAD_LIBRARY_SEARCH_SYSTEM32
available!
Use the /DEPENDENTLOADFLAG:‹…›
option of
LINK.EXE
and specify only the absolutely necessary combination of flags
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
,
LOAD_LIBRARY_SEARCH_APPLICATION_DIR
,
LOAD_LIBRARY_SEARCH_USER_DIRS
and
LOAD_LIBRARY_SEARCH_SYSTEM32
to restrict the search
order for dependent
DLLs as much as
possible.
Caveat: this setting is supported on
Windows 10 1607 alias Anniversary Update
(codenamed Redstone 1) and newer versions of
Windows NT, and applies only to
run-time dependencies
and calls of the Win32 function
load-time dependencies!
LoadLibrary()
Create a load-time dependency to the Win32 function
SetDefaultDllDirectories()
in all your executable modules and call it with
the argument LOAD_LIBRARY_SEARCH_SYSTEM32
to remove the
application directory
and the
CWD alias .
from the DLL search
path.
Caveat: this fails with some (indirect) load-time
dependencies!
Caveat: this fixes the beginner’s error only
for
run-time dependencies!
Caveat: on Windows Vista,
Windows Server 2008, Windows 7 and
Windows Server 2008 R2, your users have to install the
optional update
2533623
(available per Windows Update) security
update
MS12-081
alias
2758857
(or any newer update that supersedes it) to make this
backported Win32 function available!
Note: the load-time dependency to the
Win32 function SetDefaultDllDirectories()
is safe, it is imported from
Kernel32.dll
,
which is one of the
known DLLs
.
Create a load-time dependency to the Win32 function
SetDllDirectory()
in all your executable modules and call it with an
empty string to remove the
CWD alias .
from the DLL search
path.
Note: the load-time dependency to the
Win32 function SetDllDirectory()
is safe,
it is imported from
Kernel32.dll
,
which is one of the known DLLs
.
If you can’t remove the
CWD alias .
from the DLL search
path using one of the functions named above, create a load-time
dependency to the Win32 function
SetSearchPathMode()
in all your executable modules and call it with the
argument
BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT
to enforce the safe search path mode
.
Note: on Windows XP,
Windows Server 2003, Windows Vista
and Windows Server 2008, this function was added with
the security update
MS09-015
alias
959426.
Note: the load-time dependency to the
Win32 function SetSearchPathMode()
is
safe, it is imported from
Kernel32.dll
,
which is one of the
known DLLs
.
Embed an application manifest
in all your
executable modules to disable
DLL redirection
via
application manifest
‹filename›.‹extension›.Manifest
,
‹filename›.‹extension›.Local
,
‹filename›.‹extension›.Local
,
‹filename›.‹extension›.Local
,
‹filename›.‹extension›.Local
.
Verify that an external application manifest
doesn’t
override an embedded application manifest
via the following
Registry
entry:
REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide]
"PreferExternalManifest"=dword:00000000
Note: in Windows XP and
Windows Server 2003 this Registry
entry defaulted to 1; as documented in the
MSKB
article
912949
the default was changed with Windows Server 2003 SP1.
Specify all dependents with their absolute (fully
qualified) pathname in the embedded application manifest
of
all your executable modules and
DLLs:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
…
<file name="‹filename›.‹extension›"
loadFrom="%SystemRoot%\System32\‹filename›.‹extension›" />
…
</assembly>
Caveat: the loadFrom
attribute of the
file
element is not documented by
Microsoft!
VRFKNTHK.DLL
is a pure native
DLL, written in
ANSI C,
built with the VRFKNTHK.DLL
is available for the I386
alias x86, AMD64
alias x64 and IA64 processor
architectures of Windows NT.
VRFKNTHK.DLL
and the cabinet file
VRFKNTHK.CAB
are
digitally signed
using an
X.509
certificate
issued by
WEB.DE TrustCenter E-Mail Certification Authority.
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA6ipnm9vAs63w+TM+9UcG1yQ8CRIxMz/tTXry9MCbeHpkiM/qdPaRWlwVTW2j
PhC81xwIPZXgE1FE4DgE1eImb33DG2YfEBY/ARpMaGUnme+85WmExWWc/YMUAaHOMYQ3TQDX
0V/7yuhfa9Uc29ljtQ2AB0MjhXTJvGguvZZTI5A3rcN4+AKwmETdYH+8OQKMU2s+2H9CVfaD
waX0aj9CeibGNooLTgDchzCBIC5J47qHned/3ZqnMDjYCv3Yc1HNgcbM+ZKzPoD8jShb/ptI
wWPo9s00KEs9ti68RsmejqKovAmdLSzFLGARbue2uiqs4piJkxI0LS5+NTTPyZjsSwIDAQAB
-----END RSA PUBLIC KEY-----
Download and install the
CA
and
root
X.509 certificates of
WEB.DE
to validate and verify the digital signature.
Note: unfortunately WEB.DE abandoned their trust center in 2018 and removed all pages and download links in 2019; fortunately the Wayback Machine archived the TrustCenter page, the CA and the root certificate.
Note: due to its counter signature alias timestamp the digital signature remains valid past the X.509 certificates expiration date!
AMD64\VRFKNTHK.DLL
,
I386\VRFKNTHK.DLL
,
IA64\VRFKNTHK.DLL
and the
setup script
VRFKNTHK.INF
are packaged in the (compressed and
digitally signed)
cabinet
file
VRFKNTHK.CAB
.
Microsoft Windows XP [Version 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. X:\>EXTRACT.EXE /D VRFKNTHK.CAB Microsoft (R) Cabinet Extraction Tool - Version 5.1.2600.5512 Copyright (c) Microsoft Corporation. All rights reserved.. Cabinet VRFKNTHK.CAB 08-03-2018 10:40:06p A--- 11,098 VRFKNTHK.INF 08-03-2018 10:41:42p A--- 65,152 AMD64\VRFKNTHK.DLL 08-03-2018 10:41:34p A--- 55,936 I386\VRFKNTHK.DLL 08-03-2018 10:41:48p A--- 110,720 IA64\VRFKNTHK.DLL 4 Files 242,906 bytes X:\>DIR VRFKNTHK.CAB Volume in drive X has no label. Volume Serial Number is 1957-0427 Directory of X:\ 08/03/2018 10:42 PM 61,132 VRFKNTHK.CAB 1 File(s) 61,132 bytes 0 Dir(s) 9,876,543,210 bytes free X:\>SIGNTOOL.EXE Verify /V VRFKNTHK.CAB Verifying: VRFKNTHK.CAB SHA1 hash of file: (not calculated) Signing Certificate Chain: Issued to: WEB.DE TrustCenter Issued by: WEB.DE TrustCenter Expires: 30.08.2024 09:49:34 SHA1 hash: C8301016951187E6320569B3ED54F34845B51638 Issued to: WEB.DE TrustCenter E-Mail Certification Authority Issued by: WEB.DE TrustCenter Expires: 30.08.2024 09:50:51 SHA1 hash: 8946380C6E370988FB587257A9F9A5CD323045F0 Issued to: Stefan Kanthak Issued by: WEB.DE TrustCenter E-Mail Certification Authority Expires: 15.12.2018 02:16:19 SHA1 hash: 8C5B7521404177AC54131302066BB069102E830E The signature is timestamped: 03.08.2018 22:42:21 Timestamp Verified by: Issued to: Thawte Timestamping CA Issued by: Thawte Timestamping CA Expires: 01.01.2021 01:59:59 SHA1 hash: BE36A4562FB2EE05DBB3D32323ADF445084ED656 Issued to: Symantec Time Stamping Services CA - G2 Issued by: Thawte Timestamping CA Expires: 31.12.2020 01:59:59 SHA1 hash: 6C07453FFDDA08B83707C09B82FB3D15F35336B1 Issued to: Symantec Time Stamping Services Signer - G4 Issued by: Symantec Time Stamping Services CA - G2 Expires: 30.12.2020 01:59:59 SHA1 hash: 65439929B67973EB192D6FF243E6767ADF0834E4 Successfully verified: VRFKNTHK.CAB Number of files successfully Verified: 1 Number of warnings: 0 Number of errors: 0 X:\>On Windows Vista and newer versions of Windows NT, run the following command line to extract all files into the specified directory, preserving their paths:
"%SystemRoot%\System32\Expand.exe" VRFKNTHK.CAB /F:* "‹target directory›"Note:
Expand.exe
from prior
versions of Windows NT ignores the paths and junks
them; use Extract.exe
from the Support Tools on Windows XP and
Windows Server 2003 instead!
Note: if you open VRFKNTHK.CAB
with
Windows Explorer, switch to
Details
view and turn on the Path
column!
Note: on systems with AMD64 alias
x64 processor architecture, the installation
must be run in the native (64-bit) execution
environment to install VRFKNTHK.DLL
for both processor
architectures!
I386\VRFKNTHK.DLL
to
%SystemRoot%\System32\VRFKNTHK.DLL
.
AMD64\VRFKNTHK.DLL
to
%SystemRoot%\System32\VRFKNTHK.DLL
and
I386\VRFKNTHK.DLL
to
%SystemRoot%\SysWoW64\VRFKNTHK.DLL
.
IA64\VRFKNTHK.DLL
to
%SystemRoot%\System32\VRFKNTHK.DLL
.
Note: on systems with AMD64 alias x64 processor architecture, Internet Explorer (x64) must be used!
VRFKNTHK.CAB
and verify its digital signature, then open it in
Windows Explorer, extract its
contents preserving the directory structure, right-click the
extracted setup script
VRFKNTHK.INF
to display its context menu and click Installto run the installation.
Note: on Windows Vista and newer
versions of Windows NT,
InfDefaultInstall.exe
,
the application registered for the Install
verb of
*.inf
files, requests administrative privileges.
On Windows XP and Windows Server 2003,
open the Add/Remove Programs applet of the
Control Panel,
tick the checkbox Updates
, select the entry
Application Verifier Provider
underneath
Systemkonfiguration
and click the
button.
On Windows Vista and newer versions of
Windows NT, open the Control Panel and
click the entry View installed updates underneath the
Programs and Features or Programs
category.
In Installed Updates select the entry
Application Verifier Provider
underneath
Systemkonfiguration
and click the Uninstall
menu entry.
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):