Geoff Chappell, Software Analyst
This function opens the registry key for reading a given executable’s Image File Execution Options.
NTSTATUS LdrOpenImageFileOptionsKey ( UNICODE_STRING *lpImageFile, BOOLEAN bWow64, HANDLE *phKey);
The lpImageFile argument names the executable image for which the key is sought.
The bWow64 argument is non-zero to get the key from the Wow6432Node branch. This argument is ignored in version 6.1 and higher.
The phKey argument is the address of a variable that is to receive a handle to the opened key.
The function returns STATUS_SUCCESS if successful, else a negative error code.
The LdrOpenImageFileOptionsKey function is exported by name from NTDLL.DLL in version 5.2 starting from Windows Server 2003 SP1, and higher.
The LdrOpenImageFileOptionsKey function is not documented. Neither is it declared in any C-language header that Microsoft is known to have published in any software development kit. While Microsoft’s names for the function’s arguments are not known, this article uses inventions.
From all the way back at version 3.10, NTDLL has provided that executables are subject to Image File Execution Options in the registry. The options for different executables are in different subkeys of an Image File Execution Options key, which versions 5.2 and 6.0 allow in either of two places. Historically, options apply to all executables that have the same filename. In version 6.1 and higher, subkeys can reach one level deeper to define different options for different executables that have the same filename. The LdrOpenImageFileOptionsKey function opens the appropriate subkey for the named executable without the caller having to know the tree’s implementation.
Not until Windows Server 2003 SP1 does NTDLL export separate functions for opening the key and for querying its (potentially numerous) values. This LdrOpenImageFileOptionsKey function opens the key. The LdrQueryImageFileKeyOption function queries the values. The caller is expected to close the key when done. The ancient LdrQueryImageFileExecutionOptions and the relatively new LdrQueryImageFileExecutionOptionsEx are compounds which open the key, query one value and close the key.
The parent key for all Image File Execution Options can be either:
Only the first is recognised in version 6.1 and higher. The second, in the Wow6432Node branch, is selected in versions 5.2 and 6.0 if the bWow64 argument is non-zero.
Each base key is opened on the first call with matching bWow64 argument. If the base key is not already open and the function cannot open it (for KEY_QUERY_VALUE and KEY_ENUMERATE_SUB_KEYS access), then the function fails.
The general scheme provides for subkeys in which to specify options for different executables. The subkey for an executable is the executable’s filename. If the given lpImageFile contains a backslash, then the filename for the subkey is whatever follows the last backslash. If this is too long for representation in a UNICODE_STRING, the function fails, returning STATUS_BUFFER_TOO_SMALL. If the function cannot open the subkey (relative to the open parent, again for KEY_QUERY_VALUE and KEY_ENUMERATE_SUB_KEYS access), it fails.
In general, and as the only successful outcome in early versions, the subkey as opened for the executable from just its filename is what the function returns at the address given by the phKey argument.
The general scheme has the problem, of course, that the same options apply to all executables that have the same filename. Version 6.1 extends the scheme to differentiate according to the whole name that is supplied for the executable. If the subkey just for the filename contains a suitable value (to show that the extension applies) and a suitable subkey (to match the executable’s whole name), then the function returns the deeper subkey instead.
Extension to a subkey for the whole name of the executable is optional. It applies only if the subkey for the filename contains a REG_DWORD value named UseFilter whose dword of data is non-zero:
|Key:||HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\filename|
If the UseFilter value is absent from the subkey for an executable’s filename, or if it is present but has the wrong type or size or is zero, then all executables with this filename have the same Image File Execution Options. The subkey for the filename is what the function sticks with. Note, however, that if querying for the UseFilter value fails with any error other than STATUS_OBJECT_NAME_NOT_FOUND, STATUS_BUFFER_TOO_SMALL or STATUS_BUFFER_OVERFLOW, then this error is failure for the function.
Given that UseFilter is configured for the filename, then the subkey for just the filename may have any number of subkeys that are each for a different pathname. The names of the subkeys are immaterial. The pathname is expected as a REG_SZ value named FilterFullPath whose data matches the executable’s whole name:
|Key:||HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\filename\subkey|
|Data:||executable’s case-insensitive name from lpImageFile, less any \??\ prefix|
Subkeys are ignored if they contain a FilterFullPath value that has the wrong type or has data that is too large for representation in a UNICODE_STRING or which does not match the executable. Any other error while enumerating or opening subkeys or querying FilterFullPath (once sufficient memory is obtained), including that a subkey has no FilterFullPath, is failure for the function. If every subkey has a FilterFullPath but none matches the executable’s whole name, then the function sticks with the subkey for just the filename.
Version 5.2 opens the base key for KEY_ENUMERATE_SUB_KEYS access and the subkey for GENERIC_READ access.
When the function fails while seeking a subkey for the executable’s whole name, the handle to the subkey for the executable’s filename is not closed.