8
votes

Comment pouvons-nous nous protéger d'autres tiers d'installer des DLL avec les mêmes noms que certains des nôtres en C: \ Windows?

Notre produit comprend plusieurs dlls construits à partir d'open source dans des fichiers avec des noms par défaut tels que livrés par les développeurs open source. Nous sommes prudents d'installer les fichiers de nos propres répertoires et nous gérons soigneusement le chemin de recherche (uniquement pour nos processus) pour garder le chargeur heureux.

Un autre développeur - un intellect imposant - décidé qu'il serait plus facile d'installer sa propre construction de certaines des mêmes source ouverte dans C: \ Windows sous les mêmes noms de fichiers DLL par défaut. Par conséquent, lorsque nous lancons un processus qui dépend de ces DLL open source, le système recherche C: \ Windows avant nos répertoires et trouve les DLL installées par l'autre développeur. Et ils sont, bien sûr, incompatibles.

Idées qui me sont produites jusqu'à présent:

  • renommer toutes nos DLL pour éviter les noms par défaut qui ne feraient que faire il moins probable nous rencontrerions des collisions
  • chargez toutes nos dlls par chemin complet afin que le chargeur capture leurs noms dans Ram et ne cherche nulle part ailleurs la prochaine fois qu'ils sont demandés

    Pour diverses raisons, aucune de ces options n'est acceptable pour le moment.

    Que pouvons-nous faire d'autre pour vous défendre contre les énormes intellectuels du monde?


6 commentaires

Si vous utilisez des versions récentes de MSVC, les informations manifestes / assemblées ne garantissent pas de ne pas tenter de charger les DLL incorrects?


Chargez-vous vos dlls implicitement (via une liaison avec une liberme importe) ou explicitement (via LoadLibrary)? Si ce dernier, pouvez-vous fournir un chemin complet sur vos dlls?


Kaleb, nous utilisons VS2005, et il génère des manifestes, mais il semble ne le faire que pour les DLL qu'elle sait sont livrées dans SXS. Les nôtres ne sont pas. Il se peut que nous puissions faire quelque chose avec des manifestes de toute façon; Je vais regarder dans ça.


Scott, nous les chargons implicitement.


Versions incompatibles entre l'interface de la même DLL déployée directement dans C: \ Windows? Se sent comme les mauvais jours.


Ouais - d'où la mention de l'intellect dominant. Je suis en fait reconnaissant que les interfaces soient incompatibles, car si cela n'avait été que la mise en œuvre, cela pourrait nous avoir donné à jamais pour déterminer.


4 Réponses :


5
votes

Vous n'avez que deux options: Déployez la DLL dans le même répertoire que l'EXE (c'est là que Windows regarde d'abord) ou en utilisant des manifestes et déployez la DLL vers le cache côte à côte Windows. Je ne pense pas que cette dernière option est courante dans le monde open source, mais c'est le seul réel correction si vous souhaitez partager des DLL entre différentes applications.


2 commentaires

Ouais, la dernière documentation (qui semble être à MSDN2.MicRosoft. com / fr-nous / bibliothèque / ms972822.aspx ) ne mentionne pas l'annuaire EXE, mais je faisais juste une expérience que je pense établit cela.


Meilleure documentation ici: MSDN.MicRosoft.com/EN-US /Library/ms682586(vs.85).aspx



0
votes

Peut-être juste les compiler à une bibliothèque statique?

Pourquoi pas?

En outre, le répertoire actuel, où l'EXE est activé à partir de la recherche avant C: \ Windows.


4 commentaires

Nous avons beaucoup, beaucoup d'exètes. La compilation des DLL statilement dans toutes les choses les rendraient prohibitivement. De plus, il existe plusieurs équipes impliquées qui opèrent sur des calendriers coopératifs et des DLL fournissent un moyen de gérer les livrables.


Et, à propos, le répertoire actuel n'est pas recherché avant les répertoires système à partir de XP SP1 et Server 2003, sauf si vous faites quelque chose avec SetDllDirectory, ce qui n'est pas clair de la documentation disponible. (Si je devais adopter cette approche, je voudrais simplement passer le répertoire actuel pour éliminer tout doute.) Cependant, je pense que ce que vous vouliez vraiment dire, c'est que le répertoire parent de l'EXE est recherché en premier, et c'est bien vrai.


Oui, c'est ce que je disais. Pourquoi ça ne résout-t-il pas votre problème?


Les DLL ne sont pas localisées dans le même répertoire que les exes.



1
votes

Le répertoire à partir de laquelle l'application chargée est normalement le premier répertoire recherché lorsque vous chargez une DLL. Vous pouvez cependant utiliser setdlldirectory pour obtenir la "commande de recherche alternative". Dans ce cas, le répertoire que vous spécifiez à setdlldirectory est recherché en premier.

Il existe également un SafeDllSearchMode qui affecte ceci à un degré. Tourner sur exclut le répertoire actuel de la recherche.


2 commentaires

Le problème avec SetdllDirectory est que la valeur n'est pas héritée par les processus d'enfants. Nous avons beaucoup d'enfants et de processus petits-enfants (et probablement plus profonds). SafedllSearchMode semble intriguant et je la regarde.


SafedLLSearchMode ne supprime pas le répertoire actuel du chemin de recherche. Il déplace plutôt le répertoire actuel vers la fin des endroits pour regarder. Cela peut aider. Si vous essayez de charger une bibliothèque système ou celle installée avec votre exécutable, vous êtes tous définis. Mais si vous faites un LoadLibrary pour déterminer si une DLL existe, alors cela vous laisse toujours ouvrir une attaque de précharge.



3
votes

Pour ajouter aux réponses déjà excellentes, vous avez quelques choix supplémentaires:

La ou les solutions préférées à ce problème, prises en charge depuis Windows XP, consiste à transformer votre DLL en un assemblage Win32 (ils ne doivent pas nécessairement être .NET, mais la documentation sur la création d'assemblages Win32 avec des noms forts est épouvantablement Donc, il est facile de devenir confus et de penser que c'est une technologie .NET unique).

Un assembly ne se présente pas plus compliqué qu'un dossier (avec le nom de l'assemblage) contenant les DLL et un .Manifest (avec le nom de l'assemblage) contenant un élément de montididique et un certain nombre de nœuds de fichier pour chaque DLL Dans l'assemblée.

La recherche basée sur l'assemblage fonctionne même lorsque des DLL sont liées statiquement!

  • L'option la plus simple consiste à créer des assemblages non aversés et à les stocker dans le même dossier que vos fichiers .exe (en supposant que tous vos exe sont dans un seul dossier).

    Si les exe sont dans différents dossiers, il existe deux façons d'accéder aux assemblys partagés:

    • Vous pouvez stocker vos assemblages dans un emplacement privé alternatif si vous vous attendez à ce que votre application soit utilisée sur Windows 7 et supérieure. Créez un fichier app.exe.config pour chacun de vos exe, et pointez A PROBORATION DE PRIVÉEPATH Élément à un dossier commun dans lequel vous stockez les assemblages.

    • Si vous êtes d'accord avec un accès administratif à effectuer des installations, (via MSI), vous pouvez faire face à une documentation effroyable (bien, de documentation absente) qui traite de donner à vos assemblées un nom fort, puis de stocker l'assemblage en winsxs.

      Si vous ne pouvez pas, sinon vous ne voulez pas regrouper vos dlls comme des assemblages, alors Cette page couvre la commande de recherche DLL

      Utiliser des fonctions telles que SETDLLLDIRECTORY ne sont que Aller à aider pour les DLL chargées de manière dynamique à l'exécution (via LoadLibrary).

      commande de recherche dll utilisé être:

      1. Répertoire contenant le processus EXE
      2. Répertoire actuel
      3. Divers Dossiers Windows
      4. chemin

        que vous auriez pu utiliser à votre avantage - lancez chaque EXE, définissant le répertoire "actuel" dans le dossier contenant les dlls OSS.

        Avec l'avènement de SafedllSearchMode La commande de recherche est la suivante:

        1. Répertoire contenant le processus EXE
        2. Divers Dossiers Windows
        3. Répertoire actuel
        4. chemin

          Signifie Theres Maintenant moins de contrôle que jamais :( - Cela va encore plus rapidement aux dossiers "non rigoureux" C: \ Windows et System32.

          Encore une fois, si la DLL initiale est en cours de chargement via LoadLibrary et que sa DLL dépendante qui sont le problème, Loadlibraryex avec le drapeau de recherche_with_altered_search_Path entraînera la commande de recherche suivante (en supposant que vous passez un chemin complet à LoadLibraryex): -

          1. Une partie du répertoire du trajet DLL est passée à LoadLibraryex
          2. Divers Dossiers Windows
          3. Répertoire actuel
          4. chemin

0 commentaires