KnownDlls is a nifty little trick used by Windows to speed up the loading of “default” system shared libraries, using a
(Copy on Write) mechanism for fast mapping in memory.
One question though, is it possible to list all the dll under
The Windows dll search order is fairly complicated and slow since it must scan the following folders (in the default search) :
* The directory from which the application loaded. * The system directory. Use the GetSystemDirectory function to get the path of this directory. * The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched. * The Windows directory. Use the GetWindowsDirectory function to get the path of this directory. * The current directory. * The directories that are listed in the PATH environment variable. ( Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.)
KnownDlls mechanism has been introduced in 2006 by
KB 164501 in order to speed up dll loading. It leverage the fact that most
Win32 applications load the same set of system libraries (
kernel32.dll, etc.) : instead of scanning folders on disk, those particular dlls can be mapped in memory and copied into newly created processes, thus greatly improving process creation times.
KnownDlls can easily spotted by looking at several processes loaded module lists : they are always mapped at the same virtual base address accross processes (which has security implications …).
In order to list all the dll considered
KnownDlls, I had to read some documentation. As always, there is a pertinent blog post on the msdn network : https://blogs.msdn.microsoft.com/larryosterman/2004/07/19/what-are-known-dlls-anyway.
According to the author, if some dlls are “statically” listed as
KnownDlls in the registry key
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SessionManager\KnownDLLs, it does not return the entire list of librairies since all the dlls loaded by a
KnownDll is also a
KnownDll. In order to “dynamically” list all the
KnownDlls, we need to list all the sections under
\KnownDlls (for 64-bit dlls) and/or
\KnownDlls32 (for wow64-bit dlls).
Listing files from a directory handle
\KnownDlls is a “special” directory since it’s not really present on disk’s FS.
The first implication is
FindNextFile won’t work, since it rely on
\KnownDlls being a traditionnal folder.
Nevertheless we can get a directory handle on
CreateFile (via the
FILE_FLAG_BACKUP_SEMANTICS flag). However the available API to manipulate directory handles are quite poor :
* BackupRead * BackupSeek * BackupWrite * GetFileInformationByHandle * GetFileSize * GetFileTime * GetFileType * ReadDirectoryChangesW * SetFileTime
Backup* apis are useless in our case, as well as
ReadDirectoryChangesW seem remotely useful. Unfortunately,
GetFileInformationByHandle does not return useful infos to us and
ReadDirectoryChangesW only notify changes inside the directory, not the current state of it.
However there is another way to list elements living under a directory handle, using
NtQueryDirectoryObject is a meh documented native api that
retrieves information about the specified directory object which does not say much about what it does. Fortunately, some people on the Internet hinted this NT API was used by
Winobj to read the content of global objects such as
NtQueryDirectoryObject API is a bit clunky to use (just read
rewolf’s post about it) since you need to provide a buffer that will be written by increments of
OBJECT_DIRECTORY_INFORMATION data structures. If the buffer size is too small, you need to keep track of a
Context parameter that store which entries already has been returned. It looks like to me like a old-style generator or the way Linux’s char devices handle
Anyway, I’ve found two implementations which enumerate objects under a DirectoryObjects:
processhacker2\ProcessHacker2\phlib\native.c. It’s used by ProcessHacker2’s
ExtraPlugins\ObjectManagerPluginwhich is a
Here my quick and dirty implementation in
Anyway, there is a “guy” that keep track of
KnownDlls across Windows versions : https://windowssucks.wordpress.com/knowndlls/.