search dll winapi path

search - ¿Cómo podemos protegernos de otros terceros instalando DLL con los mismos nombres que algunos de los nuestros en C: / WINDOWS?



winapi path (4)

¿Tal vez simplemente compilarlos en una biblioteca estática?

Por qué no?

Además, el directorio actual, desde donde se activa el exe, se busca antes que c: / windows.

Nuestro producto incluye varias DLL creadas a partir de código abierto en archivos con nombres predeterminados entregados por los desarrolladores de código abierto. Tenemos cuidado de instalar los archivos en nuestros propios directorios y administramos cuidadosamente la ruta de búsqueda (solo para nuestros procesos) para mantener el cargador feliz.

Otro desarrollador, un intelecto imponente, decidió que sería más fácil instalar su propia compilación de la misma fuente abierta en C: / WINDOWS bajo los mismos nombres de archivo DLL predeterminados. En consecuencia, cuando lanzamos un proceso que depende de estas DLL de código abierto, el sistema busca C: / WINDOWS antes de nuestros directorios y encuentra las DLL instaladas por el otro desarrollador. Y son, por supuesto, incompatibles.

Ideas que me han ocurrido hasta ahora:

  • renombrar todas nuestras DLL para evitar los nombres predeterminados, lo que haría menos probable que encontráramos colisiones
  • cargar todas nuestras DLL por ruta completa para que el cargador capture sus nombres en la RAM y no busque en otro lugar la próxima vez que se soliciten

Por diversas razones, ninguna de estas opciones es aceptable en este momento.

¿Qué más podemos hacer para defendernos de los intelectos imponentes del mundo?


Para agregar a las respuestas ya excelentes, tiene un par de opciones más:

La (s) solución (es) preferida (s) para este problema, compatible desde Windows XP, es convertir su dll en un ensamble win32 (No tienen que ser .NET pero la documentación sobre la creación de ensamblajes win32 con nombres fuertes es terriblemente ligera, así que es fácil confundirse y pensar que esta es una tecnología .NET solamente).

Un ensamblaje es más complicado que una carpeta (con el nombre del ensamblaje) que contiene los dlls y un .manifest (con el nombre del ensamblaje) que contiene un elemento assemblyIdentiy y varios nodos de archivos para cada dll en el ensamblaje .

¡La búsqueda basada en conjuntos funciona incluso cuando los dlls están vinculados estáticamente!

  • La opción más fácil es crear ensamblajes no versionados y almacenarlos en la misma carpeta que sus archivos .exe (suponiendo que todos sus ejecutables estén en una sola carpeta).

Si los exe están en carpetas diferentes, entonces hay dos maneras de acceder a los ensambles compartidos:

  • Puede almacenar sus ensamblajes en una ubicación alternativa privada si espera que su aplicación se use en Windows 7 y superior. Cree un archivo app.exe.config para cada uno de sus ejecutables y señale un elemento privatePath de sondeo en una carpeta común donde está almacenando los ensamblajes.

  • Si está de acuerdo con que se requiera acceso administrativo para realizar instalaciones (a través de MSI), entonces puede lidiar con la documentación terriblemente mala (bueno, falta documentación) que trata de darle a sus ensamblajes un buen nombre, y luego almacenar el ensamblado en WinSxS.

Si no puede, o no quiere agrupar sus dlls como ensamblajes, esta página cubre todo el orden de búsqueda

Usar funciones como SetDllDirectory solo ayudará a los dlls cargados dinámicamente en el tiempo de ejecución (a través de LoadLibrary).

Toda la orden de búsqueda solía ser:

  1. Directorio que contiene el proceso exe
  2. Directorio actual
  3. varias carpetas de Windows
  4. CAMINO

Que podría haber usado a su favor: ejecute cada exe, establezca el directorio "actual" en la carpeta que contiene los dlls de OSS.

Con la llegada de SafeDllSearchMode, el orden de búsqueda ahora es:

  1. Directorio que contiene el proceso exe
  2. varias carpetas de Windows
  3. Directorio actual
  4. CAMINO

Significa que ahora hay menos control que nunca :( - Va incluso más rápido a las carpetas "no confiables" c: / windows & System32.

De nuevo, si el dll inicial se carga a través de LoadLibrary, y es el dll dependiente el problema, LoadLibraryEx con el indicador LOAD_WITH_ALTERED_SEARCH_PATH generará el siguiente orden de búsqueda (suponiendo que pase una ruta completa a LoadLibraryEx): -

  1. Parte del directorio de la ruta Dll pasada a LoadLibraryEx
  2. varias carpetas de Windows
  3. Directorio actual
  4. CAMINO

Solo tiene dos opciones: implementar el archivo DLL en el mismo directorio que el archivo EXE (que es donde se ve primero Windows) o usar manifiestos y desplegar el archivo DLL en el caché de Windows de lado a lado. No creo que esta última opción sea común en el mundo del código abierto, pero es la única solución real si quieres compartir archivos DLL entre diferentes aplicaciones.


El directorio desde el que se cargó la aplicación es normalmente el primer directorio buscado cuando carga una DLL. Sin embargo, puede usar SetDllDirectory para obtener el "orden de búsqueda alternativo". En este caso, el directorio que especifique para SetDllDirectory se busca primero.

También hay un SafeDllSearchMode que afecta esto hasta cierto punto. Al encenderlo, se excluye el directorio actual de la búsqueda.