La vie secrète de WindowsL'art de l'équilibrage des DLL connues

Raymond Chen

La fonctionnalité de Windows appelée familièrement « DLL connues » concerne une liste de DLL (bibliothèques de liens dynamiques) qui bénéficient d'un traitement spécial de la part du chargeur de module du noyau. Lorsque le chargeur voit un programme avec un lien dynamique vers une DLL connue lors du chargement, la copie connue est immédiatement utilisée, sans tenir compte de l'algorithme de recherche qui s'applique normalement au chargement de module. Ce mécanisme est parfois considéré comme une fonctionnalité de sécurité (fonctionnalité plutôt faible, soit), mais les DLL connues n'ont en fait jamais été conçues dans une optique de sécurité. L'objectif des DLL connues visait uniquement les performances.

La mécanique de la fonctionnalité des DLL connues s'est modifiée au fil du temps. Dans certaines versions de Windows®, le noyau utilise la liste des DLL connues comme un point de départ, examine ensuite toutes les DLL auxquelles sont liées ces DLL connues, puis toutes les DLL auxquelles sont liées ces DLL, etc. Ce processus développe la fermeture transitive de toutes les dépendances et les traite toutes comme connues. Dans d'autres versions de Windows, cette fermeture transitive n'est pas générée ; au lieu de cela, seules les DLL répertoriées explicitement comme connues sont traitées comme telles. Dans certaines versions de Windows, les DLL connues sont préchargées par le noyau lors du démarrage du système ; dans d'autres versions, ce n'est pas le cas et le noyau utilise simplement la liste pour ne pas avoir à rechercher le chemin pour une DLL.

Mais l'interprétation de la liste des DLL connues n'est pas le seul aspect qui évolue de version en version. Le contenu de la clé de Registre KnownDLLs fait également l'objet de modifications. L'équipe performances de Windows modifie à la fois la liste des DLL connues et les règles par lesquelles la liste est convertie en une série de DLL, en fonction de sa compréhension de l'utilisation de Windows par les applications. Comme souvent dans l'ingénierie, c'est un jeu d'échanges. Le préchargement de DLL connues au démarrage du système permet aux applications qui utilisent ces DLL de démarrer plus rapidement, mais cela a un prix. Le démarrage du système est plus long et la consommation de mémoire augmente, puisque ces DLL restent en mémoire, qu'elles soient utilisées ou non. Le but est d'améliorer les performances de certains composants aux dépends d'autres. Il est très difficile de parvenir à un bon équilibre et, comme vous pouvez le voir, cet équilibre est constamment ajusté pour s'adapter à l'évolution du schéma d'utilisation.

Les DLL connues ont des conséquences plus subtiles, notamment le fait qu'elles ont la priorité sur les DLL redirigées localement. (Nous avons analysé les DLL redirigées localement dans l'édition de janvier 2007 de cette chronique). En y réfléchissant bien, vous vous rendrez peut-être compte qu'il s'agit en fait d'un comportement normal, et non d'une faiblesse. Après tout, le but de la liste de DLL connues est de contourner le chemin de recherche et donc d'augmenter la vitesse de chargement des DLL. Si le noyau devait vérifier les DLL redirigées localement, cela ne ferait que ralentir le processus. Vous pensez peut-être qu'il est facile d'ajouter un seul annuaire au chemin de recherche, mais lorsque que cet annuaire peut se trouver sur un serveur réseau de l'autre côté du monde, l'ajout d'un seul annuaire peut provoquer d'énormes pertes de performances.

Croyez-le si vous voulez, nous avons rencontré certains programmes qui s'appuient sur le fait que des DLL spécifiques sont connues. L'un de ces programmes possédait un fichier appelé Version.dll dans l'annuaire d'applications. En temps normal, cette copie privée de Version.dll remplacerait celle présente dans le répertoire système, mais dans Windows XP, Version.dll est répertoriée en tant que DLL connue. Cela signifie que la copie présente dans l'annuaire d'applications est ignorée et que la version du répertoire système l'emporte.

Dans Windows Vista®, Version.dll n'est pas répertoriée en tant que DLL connue, probablement parce que les ingénieurs de performances ont déterminé que les applications ne l'utilisaient pas suffisamment pour justifier son coût. Par conséquent, ce programme ne fonctionnait plus sous Windows Vista parce que l'application s'appuyait sur le fait que le noyau ignorerait la DLL que le programme avait installée dans son propre annuaire d'applications. Le programme installait volontairement une DLL dans le chemin de recherche et comptait ensuite sur Windows pour l'ignorer ! Il me semble que si l'on souhaite que Windows ignore un fichier, le mécanisme le plus efficace consiste simplement à ne pas installer le fichier au départ. Le comble, c'est que l'entreprise auteur du programme a soumis un rapport de bogue soutenant qu'elle avait découvert une faille de sécurité.

Raymond Chen, The Old New Thing, et son livre du même titre (Addison-Wesley, 2007) traitent de l’historique de Windows et de la programmation Win32. Il n'a aucune idée de sa taille de Tee-shirt.

© 2008 Microsoft Corporation et CMP Media, LLC. Tous droits réservés. Toute reproduction, totale ou partielle, est interdite sans autorisation préalable.