Dll dependency and search order - c++

I have an A.DLL which dependent on B.DLL, so does the DLL search order that applies to applications also holds for DLLs, what I meant is when A.DLL is loaded then how does it search for B.DLL? If the DLL search order does not apply to DLLs, where should I keep the B.DLL? Should i keep it in the Current Directory where A.DLL is located or should I use form Environment paths
Note: I can't put B.DLL is System32
Any suggestions are appreciated.

The search order that applies to both exe and dll: https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#standard-search-order-for-desktop-applications. The first one regardless of safe mode is always "The directory from which the application loaded." In terms of dll, according to my finding via Process Monitor, it depends on if the dll is statically linked or dynamically loaded via LoadLibrary. For static link, this is the directory of the dll, whereas for dynamic load, this is the directory of the exe.
For example, when C:\App.exe loads D:\A.dll, which depends on B.dll as in your example, Windows searches B.dll in D:\ if static linked, or C:\ if loaded with LoadLibrary. If B.dll is not found there, then it proceeds to search other directories such as System32.
Down that line of search order is "The current directory". Many applications that loads external modules may have SetDllDirectory("") to remove current directory in the search in order to avoid dll preloading vulnerability.

Related

On windows is it possible to get dll's to look for dependencies in another folder without using the PATH environment variable?

On linux I am able to set theRPATH of a shared library to $ORIGIN:$ORIGIN../lib. This tells the DLL to look in the same directory as the shared library as well as in the ../lib folder. I've read that on windows you just add the absolute path to ../lib (for example) to the PATH. Is there an alternative to this method? I want my dll to look in the ../lib folder but don't really want it on the path. Is this possible?
If the main DLL dynamic/delay-loads the dependent DLLs, it can call SetDllDirectory() (or better, AddDllDirectory()) before loading them.
If the main DLL static-links to the dependent DLLs, but the EXE dynamic/delay-loads the main DLL, then the EXE can call (Add|Set)DllDirectory() before loading the main DLL.
Otherwise, you will have to either:
update the %PATH% environment variable.
use an application manifest that specifies the paths of the dependent DLLs.
use DLL Redirection.

How to include dll as relative path?

I have a dll in my project which I am referring through absolute path(C:\test\something\abc.dll) to load in my project. How do load it relatively or is there is better way to include it in visual studio project?
MSDN::
Before the system searches for a DLL, it checks the following:
If a DLL with the same module name is already loaded in memory, the system
uses the loaded DLL, no matter which directory it is in. The system
does not search for the DLL.
If the DLL is on the list of known DLLs
for the version of Windows on which the application is running, the
system uses its copy of the known DLL (and the known DLL's dependent
DLLs, if any). The system does not search for the DLL. For a list of
known DLLs on the current system, see the following registry key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session
Manager\KnownDLLs.
The standard searching order for Dlls is::
The directory from which the application loaded.
The current directory.
The system directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory.
The directories that are listed in the PATH environment variable.
You can always have your Dll with the application in the same directory. Carrying it as resource within application is not advisable.
You can specify dll name without path and place the dll in the same directory where the executable loading it resides, or in the current directory (the one from which you launch the program).

C++ Moving DLL out of root directory into a subfolder, visual studio

I'm a beginner with building software using C++. In my project I link to DLLs and I keep them stored in the root folder. I do this because I want the project to be portable from one machine to another, and I also want the release builds to have dependence from installing things into system32 and what not.
The problem is all the DLLs in the root folder is messy, so I want to organize them into subfolders. But I can't do that because putting the DLL in a root subfolder instead of the root, you get errors. I think because the DLL is copied to the output at the wrong location, not where the exe is, but in a subfolder, just like the source structure. Am I right about that?
What is a solution that will allow me to have the project be still be copy-pastable/portable between machines?
Windows searches for DLLs in predefined locations (see Dynamic-Link Library Search Order). Subdirectories of the directory where the application resides are not part of the search order.
To implement your requirement, you will need to explicitly add the directories to the searched locations. This process consists of two steps:
Call AddDllDirectory for each directory you want searched, in addition to the default search locations on application startup.
By default, DLL imports are resolved prior to starting a process' primary thread. To allow your application to change the DLL search path, import resolution needs to be postponed. The easiest way to do this is by using the /DELAYLOAD (Delay Load Import) linker option (see Linker Support for Delay-Loaded DLLs for additional information).
While it is possible, to segregate DLLs into subdirectories, it is best to keep them all alongside the executable image.
If you put the DLLs into subfolders instead of keeping them in the same directory as the executable, you would either have to modify PATH environment variable in Windows to point to every subfolder, or use the DLLs in LoadLibrary+GetProcAddress way instead of linking them to the executable via import libs.

DLL that depends on other DLLs?

Static linking is not an option.
Let's say that I have an executable that relies on a DLL. One solution is to ship the DLL in the same folder as the executable. Now let's say that I need to inject a DLL into a process that relies on a DLL. Because the DLL is injected, where would I put the DLLs that it relies on? In the same folder? Or in the directory of the process that is injected to?
DLLs depending on one or more other DLLs is not something special. Even a trivial DLL will have dependencies on Windows shared components which are residing in other DLLs. A good example of these "shared components" would be Kernel32.dll and the CRT DLL such as MSVCR80.DLL etc.
You can find out exactly which other DLLs your DLL or EXE requires on by invoking the Dependency Walker. To do that, just run depends.exe from a Visual Studio Command Prompt and drag-and-drop the DLL of interest into the Window that appears. In case you don't have dependency walker available, you can download it from the above link.
I'm not sure of the DLL injection stuff, but it should generally be sufficient if you place all your (other DLL) dependencies in the same folder as your DLL, which would be the folder in which the EXE loading these DLLs resides.
Eg: If C:\test\foo.exe requires bar.dll (which in turn requires baz.dll, assuming baz.dll is not a standard windows shared component), then you would place both bar.dll and baz.dll in C:\test.
There is a lot more to how the OS determines which DLL to load, since multiple versions of the same DLL may exist at various locations and MSDN has a helpful article on the search order for dynamic linked libraries.

Infernal Libraries (aka DLL Hell)

In a Project of mine, I use a Delphi Application which dynamically loads a wrapper DLL (exporting C-Style functions) which in turn is statically link against a bunch of 3rd party DLLs.
It works fine on my test machines, but on my customers computer it failed to initialize with an error Message like "Couldn't find entrypoint _somefunction#4AKKZ in TMYlibrary.dll".
After some investigation with sysinternal's process monitor, I realized that Windows would look fror DLLs in windows/sytem32 first, so if a DLL named similar to my DLL was present in system32, windows would pick that one and try to find my function entry points in it - which would fail.
Do you know of a possiblity to change windows' DLL the searching behaviour?
Additional Information
[Update] The .exe file is located on the top level of the application's folder tree.
The Wrapper and the 3rd-party-DLLs ar e both located in the Subfolder /bin of my apps Folder
Dev platform is windows XP/7, using VS2008 for the dlll and Delphi 2010 for the application
I found another solution myself:
SetDllDirectory adds an additional search path to the list of locations to look at.
From http://msdn.microsoft.com/en-us/library/ms686203%28v=VS.85%29.aspx
After calling SetDllDirectory, the DLL search path is:
The directory from which the application loaded.
The directory specified by the lpPathName parameter.
The system directory. Use the GetSystemDirectory function to get the
path of this directory. The name of
this directory is System32.
The 16-bit system directory. There is no function that obtains the
path of this directory, but it is
searched. The name of this directory
is System.
The Windows directory. Use the GetWindowsDirectory function to get
the path of this directory.
The directories that are listed in the PATH environment variable.
(maybe i should do my googling before I post on SO ;)
Ship the DLL in your program's folder. (same as the exe file).
Then Windows should try your version first.