Kolejność wyszukiwania biblioteki łącza dynamicznego
Często zdarza się, że wiele wersji tej samej biblioteki łącza dynamicznego (DLL) istnieje w różnych lokalizacjach systemu plików w systemie operacyjnym. można kontrolować określoną lokalizację, z której jest ładowana dowolna biblioteka DLL, określając pełną ścieżkę. Jeśli jednak nie używasz tej metody, system wyszukuje bibliotekę DLL w czasie ładowania zgodnie z opisem w tym temacie. moduł ładujący DLL jest częścią systemu operacyjnego, który ładuje biblioteki DLL i/lub rozpoznaje odwołania do bibliotek DLL.
Napiwek
Aby zapoznać się z definicjami spakowanych i rozpakowanych aplikacji, zobacz Zalety i wady pakowania aplikacji.
Czynniki wpływające na wyszukiwanie
Poniżej przedstawiono kilka specjalnych czynników wyszukiwania, które zostały omówione w tym temacie — można je wziąć pod uwagę jako część kolejności wyszukiwania bibliotek DLL. W kolejnych sekcjach tego tematu wymieniono te czynniki w odpowiedniej kolejności wyszukiwania dla niektórych typów aplikacji wraz z innymi lokalizacjami wyszukiwania. Ta sekcja zawiera tylko wprowadzenie do pojęć i nadanie im nazw, których będziemy używać do odwoływania się do nich w dalszej części tematu.
- przekierowanie bibliotek DLL. Aby uzyskać szczegółowe informacje, zobacz przekierowanie biblioteki dynamicznej.
- zestawy interfejsów API . Aby uzyskać szczegółowe informacje, zobacz zestawy interfejsów API systemu Windows.
- przekierowanie manifestu równoległego (SxS)— tylko aplikacje klasyczne (a nie aplikacje platformy UWP). Można przekierować przy użyciu manifestu aplikacji (znanego również jako manifest aplikacji równoległej lub manifestu łączenia). Aby uzyskać szczegółowe informacje, zobacz Manifests.
- lista załadowanych modułów. System może sprawdzić, czy biblioteka DLL o tej samej nazwie modułu jest już załadowana do pamięci (niezależnie od folderu, z którego został załadowany).
-
znane biblioteki DLL. Jeśli biblioteka DLL znajduje się na liście znanych bibliotek DLL dla wersji systemu Windows, na której działa aplikacja, system używa jego kopii znanej biblioteki DLL (i znanych bibliotek DLL zależnych, jeśli istnieją). Aby uzyskać listę znanych bibliotek DLL w bieżącym systemie, zobacz klucz rejestru
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
.
Jeśli biblioteka DLL ma zależności, system wyszukuje zależne biblioteki DLL tak, jakby zostały załadowane przy użyciu tylko nazw modułów. To prawda, nawet jeśli pierwsza biblioteka DLL została załadowana, określając pełną ścieżkę.
Kolejność wyszukiwania spakowanych aplikacji
Gdy spakowana aplikacja ładuje spakowany moduł (w szczególności moduł biblioteki — plik .dll
), wywołując funkcję LoadPackagedLibrary, biblioteka DLL musi znajdować się w grafie zależności pakietu procesu. Aby uzyskać więcej informacji, zobacz LoadPackagedLibrary. Gdy spakowana aplikacja ładuje moduł w inny sposób i nie określa pełnej ścieżki, system wyszukuje bibliotekę DLL i jej zależności w czasie ładowania zgodnie z opisem w tej sekcji.
Gdy system wyszukuje moduł lub jego zależności, zawsze używa kolejności wyszukiwania spakowanych aplikacji; nawet jeśli zależność nie jest spakowana w kodzie aplikacji.
Standardowa kolejność wyszukiwania dla spakowanych aplikacji
System wyszukuje w następującej kolejności:
- Przekierowanie biblioteki DLL.
- Zestawy interfejsów API.
- tylko aplikacje klasyczne (nie aplikacje platformy UWP). Przekierowanie manifestu SxS.
- Lista załadowanych modułów.
- Znane biblioteki DLL.
- Wykres zależności pakietu procesu. Jest to pakiet aplikacji oraz wszystkie zależności określone jako
<PackageDependency>
w sekcji<Dependencies>
manifestu pakietu aplikacji. Zależności są przeszukiwane w kolejności, w której są wyświetlane w manifeście. - Folder, z którego został załadowany proces wywołujący (folder pliku wykonywalnego).
- Folder systemowy (
%SystemRoot%\system32
).
Jeśli biblioteka DLL ma zależności, system wyszukuje zależne biblioteki DLL tak, jakby zostały załadowane przy użyciu tylko nazw modułów (nawet jeśli pierwsza biblioteka DLL została załadowana, określając pełną ścieżkę).
Kolejność wyszukiwania alternatywnego dla spakowanych aplikacji
Jeśli moduł zmieni standardową kolejność wyszukiwania przez wywołanie funkcji LoadLibraryEx z LOAD_WITH_ALTERED_SEARCH_PATH, kolejność wyszukiwania jest taka sama jak standardowa kolejność wyszukiwania, z tą różnicą, że w kroku 7 system przeszukuje folder, z którego załadowano określony moduł (folder modułu ładowania najwyższego poziomu) zamiast folderu pliku wykonywalnego.
Kolejność wyszukiwania dla niezapakowanych aplikacji
Gdy rozpakowana aplikacja ładuje moduł i nie określa pełnej ścieżki, system wyszukuje bibliotekę DLL w czasie ładowania zgodnie z opisem w tej sekcji.
Ważny
Jeśli osoba atakująca uzyska kontrolę nad jednym z przeszukanych katalogów, może umieścić złośliwą kopię biblioteki DLL w tym folderze. Aby uzyskać informacje na temat sposobów zapobiegania takim atakom, zobacz zabezpieczenia biblioteki dynamicznej.
Standardowa kolejność wyszukiwania dla niezapakowanych aplikacji
Standardowa kolejność wyszukiwania bibliotek DLL używana przez system zależy od tego, czy bezpieczny tryb wyszukiwania dll jest włączony.
Tryb wyszukiwania bezpiecznej biblioteki DLL (domyślnie włączony) przenosi bieżący folder użytkownika w dalszej części kolejności wyszukiwania. Aby wyłączyć tryb wyszukiwania bezpiecznej biblioteki DLL, utwórz wartość rejestru HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode
i ustaw ją na 0. Wywoływanie funkcji SetDllDirectory skutecznie wyłącza tryb wyszukiwania bezpiecznej biblioteki DLL (podczas gdy określony folder znajduje się w ścieżce wyszukiwania) i zmienia kolejność wyszukiwania zgodnie z opisem w tym temacie.
Jeśli tryb wyszukiwania bezpiecznej biblioteki DLL jest włączony, kolejność wyszukiwania jest następująca:
- Przekierowanie biblioteki DLL.
- Zestawy interfejsów API.
- Przekierowanie manifestu SxS.
- Lista załadowanych modułów.
- Znane biblioteki DLL.
-
Windows 11, wersja 21H2 (10.0; Skompiluj 22000) i nowsze. Wykres zależności pakietu procesu. Jest to pakiet aplikacji oraz wszystkie zależności określone jako
<PackageDependency>
w sekcji<Dependencies>
manifestu pakietu aplikacji. Zależności są przeszukiwane w kolejności, w której są wyświetlane w manifeście. - Folder, z którego załadowano aplikację.
- Folder systemowy. Użyj funkcji GetSystemDirectory, aby pobrać ścieżkę tego folderu.
- 16-bitowy folder systemowy. Nie ma funkcji, która uzyskuje ścieżkę tego folderu, ale jest przeszukiwana.
- Folder systemu Windows. Użyj funkcji GetWindowsDirectory, aby uzyskać ścieżkę tego folderu.
- Bieżący folder.
- Katalogi wymienione w zmiennej środowiskowej
PATH
. Nie obejmuje to ścieżki dla aplikacji określonej przez ścieżki aplikacji klucza rejestru. Ścieżka aplikacji nie jest używana podczas obliczania ścieżki wyszukiwania biblioteki DLL.
Jeśli bezpieczny tryb wyszukiwania dll jest wyłączony, kolejność wyszukiwania jest taka sama, z tą różnicą, że bieżący folder przechodzi z pozycji 11 do pozycji 8 w sekwencji (natychmiast po kroku 7. Folder, z którego aplikacja załadowała).
Kolejność wyszukiwania alternatywnego dla niezapakowanych aplikacji
Aby zmienić standardową kolejność wyszukiwania używaną przez system, możesz wywołać funkcję LoadLibraryEx za pomocą LOAD_WITH_ALTERED_SEARCH_PATH. Możesz również zmienić standardową kolejność wyszukiwania, wywołując funkcję SetDllDirectory.
Nuta
Na standardową kolejność wyszukiwania procesu wpłynie również wywołanie funkcji SetDllDirectory w procesie nadrzędnym przed rozpoczęciem bieżącego procesu.
Jeśli określisz alternatywną strategię wyszukiwania, jego zachowanie będzie kontynuowane do momentu zlokalizowania wszystkich skojarzonych modułów wykonywalnych. Po rozpoczęciu przetwarzania procedur inicjowania bibliotek DLL system wraca do standardowej strategii wyszukiwania.
Funkcja LoadLibraryEx obsługuje kolejność wyszukiwania alternatywnego, jeśli wywołanie określa LOAD_WITH_ALTERED_SEARCH_PATH, a parametr lpFileName określa ścieżkę bezwzględną.
- Standardowa strategia wyszukiwania rozpoczyna się (po początkowych krokach) w folderze aplikacji wywołującej.
- Alternatywna strategia wyszukiwania określona przez LoadLibraryEx z LOAD_WITH_ALTERED_SEARCH_PATH rozpoczyna się (po początkowych krokach) w folderze modułu wykonywalnego, który loadLibraryEx jest ładowany.
To jedyny sposób, w jaki się różnią.
Jeśli tryb wyszukiwania bezpiecznej biblioteki DLL jest włączony, kolejność wyszukiwania alternatywnego wygląda następująco:
Kroki 1–6 są takie same jak standardowe kolejność wyszukiwania.
- Folder określony przez lpFileName.
- Folder systemowy. Użyj funkcji GetSystemDirectory, aby pobrać ścieżkę tego folderu.
- 16-bitowy folder systemowy. Nie ma funkcji, która uzyskuje ścieżkę tego folderu, ale jest przeszukiwana.
- Folder systemu Windows. Użyj funkcji GetWindowsDirectory, aby uzyskać ścieżkę tego folderu.
- Bieżący folder.
- Katalogi wymienione w zmiennej środowiskowej
PATH
. Nie obejmuje to ścieżki dla aplikacji określonej przez ścieżki aplikacji klucza rejestru. Ścieżka aplikacji nie jest używana podczas obliczania ścieżki wyszukiwania biblioteki DLL.
Jeśli tryb wyszukiwania bezpiecznej biblioteki DLL jest wyłączony, kolejność wyszukiwania alternatywnego jest taka sama, z tą różnicą, że bieżący folder przechodzi z pozycji 11 do pozycji 8 w sekwencji (natychmiast po kroku 7. Folder określony przez lpFileName).
Funkcja SetDllDirectory obsługuje kolejność wyszukiwania alternatywnego, jeśli parametr lpPathName określa ścieżkę. Kolejność wyszukiwania alternatywnego wygląda następująco:
Kroki 1–6 są takie same jak standardowe kolejność wyszukiwania.
- Folder, z którego załadowano aplikację.
- Folder określony przez parametr lpPathNameSetDllDirectory.
- Folder systemowy.
- 16-bitowy folder systemowy.
- Folder systemu Windows.
- Katalogi wymienione w zmiennej środowiskowej
PATH
.
Jeśli parametr lpPathName jest pustym ciągiem, wywołanie usuwa bieżący folder z kolejności wyszukiwania.
SetDllDirectory skutecznie wyłącza bezpieczny tryb wyszukiwania dll, gdy określony folder znajduje się w ścieżce wyszukiwania. Aby przywrócić bezpieczny tryb wyszukiwania dll na podstawie wartości rejestru SafeDllSearchMode, a następnie przywrócić bieżący folder do kolejności wyszukiwania, wywołaj SetDllDirectory za pomocą lpPathName jako NULL.
Kolejność wyszukiwania przy użyciu flag LOAD_LIBRARY_SEARCH
Kolejność wyszukiwania można określić przy użyciu co najmniej jednej flagi LOAD_LIBRARY_SEARCH z funkcją LoadLibraryEx. Można również użyć flag LOAD_LIBRARY_SEARCH z funkcją SetDefaultDllDirectories, aby ustanowić kolejność wyszukiwania bibliotek DLL dla procesu. Możesz określić dodatkowe katalogi dla kolejności wyszukiwania bibliotek DLL procesu przy użyciu funkcji AddDllDirectory lub SetDllDirectory.
Przeszukiwane katalogi zależą od flag określonych za pomocą SetDefaultDllDirectories lub LoadLibraryEx. Jeśli używasz więcej niż jednej flagi, odpowiednie katalogi są przeszukiwane w następującej kolejności:
- LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR. Przeszukiwany jest folder zawierający bibliotekę DLL. Ten folder jest wyszukiwany tylko pod kątem zależności biblioteki DLL do załadowania.
- LOAD_LIBRARY_SEARCH_APPLICATION_DIR. Przeszukiwany jest folder aplikacji.
- LOAD_LIBRARY_SEARCH_USER_DIRS. Ścieżki jawnie dodane za pomocą funkcji AddDllDirectory lub funkcji SetDllDirectory są przeszukiwane. Jeśli dodasz więcej niż jedną ścieżkę, kolejność wyszukiwania ścieżek jest nieokreślona.
- LOAD_LIBRARY_SEARCH_SYSTEM32. Przeszukiwany jest folder System.
Jeśli wywołasz LoadLibraryEx bez flag LOAD_LIBRARY_SEARCH lub ustanowisz kolejność wyszukiwania bibliotek DLL dla procesu, system wyszukuje biblioteki DLL przy użyciu standardowej kolejności wyszukiwania lub alternatywnej kolejności wyszukiwania.