What are Known DLLs anyway?

In my previous post about DLLs and how they work, I commented that winmm.dll was a KnownDLL in Longhorn.  It turns out that this is a bug in an existing KnownDLL. But what in the heck ARE Known DLLs in the first place?

Well, it turns out that it’s in the KB, and I’ll summarize.

KnownDLL’s is a mechanism in Windows NT (and win9x) that allows the system to “cache” commonly used system DLLs.  It was originally added to improve application load time, but it also can be considered a security mechanism, since it prevents people from exploiting weak application directory permissions by dropping in Trojan horse versions of system DLLs (since the key system DLLs are all known DLLs, the version of the file in the application directory will be ignored).  As a security mechanism it's not a particularly strong mechanism (if you can write to the directory that contains a program, you can create other forms of havoc), but it can be considered a security mechanism.

If you remember from my previous article, when the loader finds a DLL import record in an executable, it opens the file and tries to map the file into memory.  Well, that’s not ENTIRELY the case.  In fact, before that happens the loader looks for an existing section called \KnownDlls\<dll filename>.  If that section exists, then instead of opening the file, the loader simply uses the existing section.   It then follows all the “normal” rules for loading a DLL.

When the system boots, it looks in the registry at HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\KnownDLLs and creates a \KnownDlls\<dll filename> section for every DLL listed under that registry key.

If you compare the HKLM\System\CCS\Control\Session Manager\KnownDLLs registry key with the sections under \KnownDlls (using a viewer like winobj), you’ll notice that the \KnownDlls object container always has more entries in it than the registry key.  This is because the \KnownDlls sections are computed as the transitive closure of the DLLs listed in KnownDLLs.  So if a DLL’s listed in KnownDLLs, all of the DLL’s that are statically linked with the DLL are ALSO listed in the \KnownDlls section.

Also, if you look in the KnownDLLs registry key, you’ll notice that there’s no path listed for the KnownDLLs.  That’s because all KnownDLLs are assumed to be in the directory pointed to by HKLM\System\CCS\Control\KnownDLLs\DllDirectory registry value.  Again, this is an aspect of KnownDLLs being a security feature – by requiring KnownDLLs to be in the same directory, it makes it harder for someone to inject their own Trojan version of one of the KnownDLLs.

Oh, and if the KnownDLLs processing causes any issues, or if for some other reason you don't want the system to load a DLL as a KnownDll, then you can set HKLM\System\CCS\Control\Session Manager\ExcludeFromKnownDlls to exclude a DLL from the KnownDll processing.  So in my example, until the bug is fixed in the existing KnownDLL, I’m adding winmm.dll to my ExcludeFromKnownDlls list.

Comments

  • Anonymous
    July 19, 2004
    <em>So if a DLL’s listed in KnownDLLs, all of the DLL’s that are statically linked with the DLL are ALSO listed in the KnownDlls section.</em>

    Should that not be dynamically linked? :-)

  • Anonymous
    July 19, 2004
    A good question Mo. Libraries can be one of two forms: Static libraries or Dynamically linked libraries.

    But Dynamically Linked Libraries can be either statically loaded or dynamically loaded. A statically linked DLL is one that is loaded into a process (or another DLL) by instructions to the loader at DLL load time. So when the DLL is loaded, it's static imports will always be loaded with the DLL.

    DLL's can also be loaded dynamically, with the LoadLibrary API (or by using the deferred loading feature in the linker). If a KnownDll loads another dll with LoadLibrary, then the other DLL won't be a KnownDll.

  • Anonymous
    July 19, 2004
    Ah, I misunderstood your terminology - apologies.

    I don't tend to think of LoadLibrary in terms of linking - just as loading, because you can't satisfy your own unresolved dependencies by using it.

    I saw "statically linked dynamic link library" and thought it was a thinko :-)

  • Anonymous
    July 19, 2004
    It's a terminology problem. How do you say "dll's that are loaded after my dll loads"? I've not come up with a better terminology.

  • Anonymous
    July 19, 2004
    Well, they're normally spoken about in context, I guess - so quite often 'Plugins' is the term used - but a generic term? I'm not so sure.

  • Anonymous
    July 19, 2004
    I'd say most people usually refer to these as "implicitly linked DLLs". Or, dependancies? So you might say something like this:

    So if a DLL is listed in KnownDLLs, all of the DLLs that the DLL implicitly links to are ALSO listed in the KnownDlls section

    OR:

    So if a DLL is listed in KnownDLLs, all of that DLL's load-time dependancies are ALSO listed in the KnownDLLs section.

  • Anonymous
    July 19, 2004
    MSDN calls them load-time dynamic linking and run-time dynamic linking.

    http://msdn.microsoft.com/library/en-us/dllproc/base/using_run_time_dynamic_linking.asp

  • Anonymous
    May 14, 2006
    PingBack from http://blogates.com/twinsant/2006/05/15/yesterday-readings/

  • Anonymous
    October 02, 2008
    PingBack from http://www.withinwindows.com/2008/10/02/tinkering-with-tinker-how-vista-ultimate-is-detected/

  • Anonymous
    October 02, 2008
    PingBack from http://www.withinwindows.com/2008/10/02/tinkering-with-tinker-how-vista-ultimate-is-detected/