Ordem de pesquisa da biblioteca de vínculo dinâmico

É comum que várias versões da mesma DLL (biblioteca de vínculo dinâmico) existam em diferentes locais do sistema de arquivos em um sistema operacional (SO). Você pode controlar o local específico do qual qualquer DLL determinada é carregada especificando um caminho completo. Mas se você não usar esse método, o sistema pesquisa a DLL no tempo de carregamento, conforme descrito neste tópico. O carregador de DLL é a parte do sistema operacional (SO) que carrega DLLs e/ou resolve referências a DLLs.

Dica

Para obter definições de aplicativos empacotados e não empacotados , confira Vantagens e desvantagens de empacotar seu aplicativo.

Fatores que afetam a pesquisa

Aqui estão alguns fatores de pesquisa especiais que são discutidos neste tópico: você pode considerá-los como parte da ordem de pesquisa da DLL. Seções posteriores neste tópico listam esses fatores na ordem de pesquisa apropriada para determinados tipos de aplicativo, juntamente com outros locais de pesquisa. Esta seção é apenas para introduzir os conceitos e dar a eles nomes que usaremos para fazer referência a eles mais adiante no tópico.

  • Redirecionamento de DLL. Para obter detalhes, consulte Redirecionamento de biblioteca de link dinâmico.
  • Conjuntos de API. Para obter detalhes, consulte Conjuntos de API do Windows.
  • Redirecionamento de manifesto SxS (lado a lado) – somente aplicativos da área de trabalho (não aplicativos UWP). Você pode redirecionar usando um manifesto do aplicativo (também conhecido como um manifesto de aplicativo lado a lado ou um manifesto de fusão). Para obter detalhes, consulte Manifestos.
  • Lista de módulos carregados. O sistema pode verificar se uma DLL com o mesmo nome de módulo já está carregada na memória (independentemente de qual pasta ela foi carregada).
  • DLLs conhecidas. Se a DLL estiver na lista de DLLs conhecidas para a versão do Windows na qual o aplicativo está em execução, o sistema usará sua cópia da DLL conhecida (e as DLLs dependentes da DLL conhecida, se houver). Para obter uma lista de DLLs conhecidas no sistema atual, consulte a chave HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLsdo Registro .

Se uma DLL tiver dependências, o sistema pesquisa as DLLs dependentes como se fossem carregadas usando apenas seus nomes de módulo. Isso é verdadeiro mesmo que a primeira DLL tenha sido carregada especificando um caminho completo.

Ordem de pesquisa para aplicativos empacotados

Quando um aplicativo empacotado carrega um módulo empacotado (especificamente, um módulo de biblioteca — um .dll arquivo) chamando a função LoadPackagedLibrary , a DLL deve estar no grafo de dependência do pacote do processo. Para obter mais informações, consulte LoadPackagedLibrary. Quando um aplicativo empacotado carrega um módulo por outros meios e não especifica um caminho completo, o sistema pesquisa a DLL e suas dependências no tempo de carregamento, conforme descrito nesta seção.

Quando o sistema pesquisa um módulo ou suas dependências, ele sempre usa a ordem de pesquisa para aplicativos empacotados; mesmo que uma dependência não seja um código de aplicativo empacotado.

Ordem de pesquisa padrão para aplicativos empacotados

O sistema pesquisa nesta ordem:

  1. Redirecionamento de DLL.
  2. Conjuntos de API.
  3. Somente aplicativos da área de trabalho (não aplicativos UWP). Redirecionamento de manifesto SxS.
  4. Lista de módulos carregados.
  5. DLLs conhecidas.
  6. O grafo de dependência do pacote do processo. Esse é o pacote do aplicativo mais as dependências especificadas como <PackageDependency> na <Dependencies> seção do manifesto do pacote do aplicativo. As dependências são pesquisadas na ordem em que aparecem no manifesto.
  7. A pasta da qual o processo de chamada foi carregado (a pasta do executável).
  8. A pasta do sistema (%SystemRoot%\system32).

Se uma DLL tiver dependências, o sistema pesquisa as DLLs dependentes como se fossem carregadas apenas com seus nomes de módulo (mesmo que a primeira DLL tenha sido carregada especificando um caminho completo).

Ordem de pesquisa alternativa para aplicativos empacotados

Se um módulo alterar a ordem de pesquisa padrão chamando a função LoadLibraryEx com LOAD_WITH_ALTERED_SEARCH_PATH, a ordem de pesquisa será igual à ordem de pesquisa padrão, exceto que na etapa 7 o sistema pesquisa a pasta da qual o módulo especificado foi carregado (a pasta do módulo de carregamento superior) em vez da pasta do executável.

Ordem de pesquisa para aplicativos não empacotados

Quando um aplicativo não empacotado carrega um módulo e não especifica um caminho completo, o sistema pesquisa a DLL no tempo de carregamento, conforme descrito nesta seção.

Importante

Se um invasor obtiver o controle de um dos diretórios pesquisados, ele poderá colocar uma cópia mal-intencionada da DLL nessa pasta. Para obter maneiras de ajudar a evitar esses ataques, confira Segurança da biblioteca de vínculo dinâmico.

Ordem de pesquisa padrão para aplicativos não empacotados

A ordem de pesquisa de DLL padrão usada pelo sistema depende se o modo de pesquisa de DLL seguro está ou não habilitado.

O modo de pesquisa de DLL segura (que está habilitado por padrão) move a pasta atual do usuário mais tarde na ordem de pesquisa. Para desabilitar o modo de pesquisa de DLL segura, crie o valor do Registro e defina-o HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode como 0. Chamar a função SetDllDirectory desabilita efetivamente o modo de pesquisa de DLL seguro (enquanto a pasta especificada está no caminho de pesquisa) e altera a ordem de pesquisa conforme descrito neste tópico.

Se o modo de pesquisa de DLL seguro estiver habilitado, a ordem de pesquisa será a seguinte:

  1. Redirecionamento de DLL.
  2. Conjuntos de API.
  3. Redirecionamento de manifesto SxS.
  4. Lista de módulos carregados.
  5. DLLs conhecidas.
  6. Windows 11, versão 21H2 (10.0; Build 22000) e posterior. O grafo de dependência do pacote do processo. Esse é o pacote do aplicativo mais as dependências especificadas como <PackageDependency> na <Dependencies> seção do manifesto do pacote do aplicativo. As dependências são pesquisadas na ordem em que aparecem no manifesto.
  7. A pasta da qual o aplicativo foi carregado.
  8. A pasta do sistema. Use a função GetSystemDirectory para recuperar o caminho dessa pasta.
  9. A pasta do sistema de 16 bits. Não há nenhuma função que obtenha o caminho dessa pasta, mas ela é pesquisada.
  10. A pasta do Windows. Use a função GetWindowsDirectory para obter o caminho dessa pasta.
  11. A pasta atual.
  12. Os diretórios listados na variável de PATH ambiente. Isso não inclui o caminho por aplicativo especificado pela chave do Registro de Caminhos de Aplicativo . A chave Caminhos do Aplicativo não é usada ao calcular o caminho de pesquisa da DLL.

Se o modo de pesquisa de DLL seguro estiver desabilitado, a ordem de pesquisa será a mesma, exceto que a pasta atual passa da posição 11 para a posição 8 na sequência (imediatamente após a etapa 7. A pasta da qual o aplicativo foi carregado).

Ordem de pesquisa alternativa para aplicativos não empacotados

Para alterar a ordem de pesquisa padrão usada pelo sistema, você pode chamar a função LoadLibraryEx com LOAD_WITH_ALTERED_SEARCH_PATH. Você também pode alterar a ordem de pesquisa padrão chamando a função SetDllDirectory .

Observação

A ordem de pesquisa padrão do processo também será afetada chamando a função SetDllDirectory no processo pai antes do início do processo atual.

Se você especificar uma estratégia de pesquisa alternativa, seu comportamento continuará até que todos os módulos executáveis associados tenham sido localizados. Depois que o sistema inicia o processamento de rotinas de inicialização de DLL, o sistema é revertido para a estratégia de pesquisa padrão.

A função LoadLibraryEx dá suporte a uma ordem de pesquisa alternativa se a chamada especificar LOAD_WITH_ALTERED_SEARCH_PATH e o parâmetro lpFileName especificar um caminho absoluto.

  • A estratégia de pesquisa padrão começa (após as etapas iniciais) na pasta do aplicativo de chamada.
  • A estratégia de pesquisa alternativa especificada por LoadLibraryEx com LOAD_WITH_ALTERED_SEARCH_PATH começa (após as etapas iniciais) na pasta do módulo executável que LoadLibraryEx está carregando.

Essa é a única maneira pela qual eles diferem.

Se o modo de pesquisa de DLL seguro estiver habilitado, a ordem de pesquisa alternativa será a seguinte:

As etapas 1 a 6 são as mesmas que a ordem de pesquisa padrão.

  1. A pasta especificada por lpFileName.
  2. A pasta do sistema. Use a função GetSystemDirectory para recuperar o caminho dessa pasta.
  3. A pasta do sistema de 16 bits. Não há nenhuma função que obtenha o caminho dessa pasta, mas ela é pesquisada.
  4. A pasta do Windows. Use a função GetWindowsDirectory para obter o caminho dessa pasta.
  5. A pasta atual.
  6. Os diretórios listados na variável de PATH ambiente. Isso não inclui o caminho por aplicativo especificado pela chave do Registro de Caminhos de Aplicativo . A chave Caminhos do Aplicativo não é usada ao calcular o caminho de pesquisa da DLL.

Se o modo de pesquisa de DLL seguro estiver desabilitado, a ordem de pesquisa alternativa será a mesma, exceto que a pasta atual passa da posição 11 para a posição 8 na sequência (imediatamente após a etapa 7. A pasta especificada por lpFileName).

A função SetDllDirectory dá suporte a uma ordem de pesquisa alternativa se o parâmetro lpPathName especificar um caminho. A ordem de pesquisa alternativa é a seguinte:

As etapas 1 a 6 são as mesmas que a ordem de pesquisa padrão.

  1. A pasta da qual o aplicativo foi carregado.
  2. A pasta especificada pelo parâmetro lpPathName de SetDllDirectory.
  3. A pasta do sistema.
  4. A pasta do sistema de 16 bits.
  5. A pasta do Windows.
  6. Os diretórios listados na variável de PATH ambiente.

Se o parâmetro lpPathName for uma cadeia de caracteres vazia, a chamada removerá a pasta atual da ordem de pesquisa.

SetDllDirectory desabilita efetivamente o modo de pesquisa de DLL seguro enquanto a pasta especificada está no caminho de pesquisa. Para restaurar o modo de pesquisa de DLL seguro com base no valor do registro SafeDllSearchMode e restaurar a pasta atual para a ordem de pesquisa, chame SetDllDirectory com lpPathName como NULL.

Ordem de pesquisa usando sinalizadores de LOAD_LIBRARY_SEARCH

Você pode especificar uma ordem de pesquisa usando um ou mais sinalizadores LOAD_LIBRARY_SEARCH com a função LoadLibraryEx . Você também pode usar sinalizadores LOAD_LIBRARY_SEARCH com a função SetDefaultDllDirectories para estabelecer uma ordem de pesquisa de DLL para um processo. Você pode especificar diretórios adicionais para a ordem de pesquisa de DLL do processo usando as funções AddDllDirectory ou SetDllDirectory .

Os diretórios pesquisados dependem dos sinalizadores especificados com SetDefaultDllDirectories ou LoadLibraryEx. Se você usar mais de um sinalizador, os diretórios correspondentes serão pesquisados nesta ordem:

  1. LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR. A pasta que contém a DLL é pesquisada. Essa pasta é pesquisada apenas para que as dependências da DLL sejam carregadas.
  2. LOAD_LIBRARY_SEARCH_APPLICATION_DIR. A pasta do aplicativo é pesquisada.
  3. LOAD_LIBRARY_SEARCH_USER_DIRS. Os caminhos adicionados explicitamente com a função AddDllDirectory ou a função SetDllDirectory são pesquisados. Se você adicionar mais de um caminho, a ordem na qual os caminhos são pesquisados não será especificada.
  4. LOAD_LIBRARY_SEARCH_SYSTEM32. A pasta Sistema é pesquisada.

Se você chamar LoadLibraryEx sem sinalizadores de LOAD_LIBRARY_SEARCH ou estabelecer uma ordem de pesquisa de DLL para o processo, o sistema procurará por DLLs usando a ordem de pesquisa padrão ou a ordem de pesquisa alternativa.