Confidencial de WindowsActos de equilibrio de DLL conocidas

Raymond Chen

La característica de Windows denominada de manera informal "DLL conocidas" se refiere a una lista de DLL (bibliotecas de vínculos dinámicos) que reciben tratamiento especial por parte del cargador de módulos del kernel. Cuando el cargador encuentra un programa con un vínculo dinámico en tiempo de carga a una DLL conocida, usa inmediatamente la copia conocida, pasando por alto el algoritmo de búsqueda que normalmente se aplica a la carga del módulo. Es posible que algunas personas consideren que esta es una característica de seguridad (aunque hay que reconocer que bastante deficiente), pero en realidad la seguridad nunca fue la intención de esta característica. Las DLL conocidas son en realidad una característica de rendimiento.

La mecánica de la característica de DLL conocidas ha cambiado con el tiempo. En algunas versiones de Windows®, el kernel usa la lista de DLL conocidas como un punto de partida, posteriormente examina todas las DLL a las que se vinculan esas DLL conocidas, a continuación todas las DLL a las que aquellas DLL se vinculan, etc. Este proceso construye el cierre transitivo de todas las dependencias y las trata a todas como conocidas. En otras versiones de Windows, este cierre transitivo no se construye; en vez de eso, sólo las DLL explícitamente enumeradas como conocidas se tratan como tales. En algunas versiones de Windows, el kernel carga de antemano las DLL conocidas cuando se inicia el sistema; en otras versiones, no se produce esta carga anticipada y el kernel solamente usa la lista para ahorrarse el problema de tener que buscar la ruta de acceso de una DLL.

No es sólo la interpretación de la lista de DLL conocidas que cambia entre una versión y versión. El contenido de la clave de registro de las DLL conocidas también están sujetos a cambios. El equipo de rendimiento de Windows cambia tanto la lista de DLL conocidas como las reglas mediante las cuales la lista se convierte en un conjunto de DLL según su comprensión de cómo las aplicaciones usan Windows. Como es típico en la ingeniería, es un juego de equilibrios. La carga anticipada de DLL conocidas en el inicio del sistema permite que las aplicaciones usen esas DLL para iniciar más rápido, pero hay un precio. Lleva más tiempo iniciar el sistema y aumenta el consumo de memoria, debido a que esas DLL permanecen en memoria independientemente de si se usan en realidad. Es un juego de equilibrio, de mejorar el rendimiento de algunos componentes al costo de otros. Obtener el equilibrio correcto es una tarea difícil y, como puede ver, se ajusta constantemente a medida que evoluciona el patrón de uso.

Una consecuencia de las DLL conocidas que no es obvia de inmediato es que tienen prioridad sobre la redirección de DLL realizada de forma local. (Analizamos la redirección de DLL realizada de forma local en la edición de enero 2007 de esta columna). Si lo piensa, se dará cuenta que se trata de un comportamiento realmente esperado antes que de una rareza. A fin de cuentas, el propósito de la lista de DLL conocidas es omitir la ruta de acceso de la búsqueda y de este modo acelerar la carga de DLL. Si el kernel tuviera que buscar las DLL redirigidas de forma local, sólo se demoraría más el proceso. Es posible que piense que solamente agregar un directorio a la ruta de acceso de la búsqueda no es gran cosa, pero cuando ese único directorio puede ser un servidor de red en la otra mitad del planeta, agregar incluso un directorio puede representar un enorme consumo del rendimiento.

Créalo o no, hemos visto programas que dependen de que DLL específicas sean conocidas. Había un programa que tenía un archivo denominado Version.dll en el directorio de la aplicación. Normalmente, esta copia privada de Version.dll invalidaría la que se encuentra en el directorio de sistema, pero en Windows XP, Version.dll se incluye como DLL conocida. Esto significa que se omite la copia en el directorio de la aplicación y que prevalece la versión en el directorio de sistema.

En Windows Vista®, Version.dll ya no se incluye como DLL conocida, probablemente porque la gente de rendimiento determinó que las aplicaciones no la usaban lo suficiente como para justificar el costo. Como resultado, este programa deja de funcionar en Windows Vista porque la aplicación dependía de que el kernel omitiere la DLL que el programa instalaba en su propio directorio de la aplicación. El programa instalaba con toda su voluntad una DLL en la ruta de acceso de búsqueda y posteriormente dependía de Windows para omitirla. Seguramente si deseaba que Windows omita un archivo, un mecanismo mucho más eficiente hubiera sido simplemente no instalar primero el archivo. Lo más gracioso fue que la compañía que escribió el programa archivó un error que reclamaba que había encontrado un agujero de seguridad.

Raymond Chen The Old New Thing, y en su libro del mismo nombre (Addison-Wesley, 2007) se trata la historia de Windows y la programación de Win32. Ya no tiene la menor idea de cuál es el tamaño de su propia camiseta.

© 2008 Microsoft Corporation and CMP Media, LLC. Reservados todos los derechos; queda prohibida la reproducción parcial o total sin previa autorización.