DLL that depends on other DLLs? - c++

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.

Related

Plugin DLL can't locate its DLL dependencies

I have a plugin application (.DLL) that links dynamically to multiple other QT DLLs.
When the plugin is loaded in the third party software, it fails to find the dependencies which are located exactly in the same folder as the plugin DLL.
The structure looks like this:
myplugin.dll
platforms\
qwindowsd.dll
QtQml\
qmlplugind.dll
...
The executable of the software that loads the Plugin is installed under C:/Program Files/MySoftware/Application.exe
Weirdly enough, when I copy the contents of my packaged plugin (dlls and its dependencies) directly into the software's executable directory, next to the executable, it works like a charm, and the plugin is able to find all its DLLs in that directory. So my guess is the DLL lookup isn’t appropriate?
This might relate to this: Search path for a DLL referenced by a plug-in DLL
but the solution to load every QT dll explicitly seems wrong.
Any help on that matter would be appreciated. Thanks
EDIT:
I tried to put the path to where the DLLs are explicitly in the PATH variable without success.

dll loaded from system32 instead of local folder

I noticed some trouble with a dll in my software when deployed. I usually include all required 3rd party dlls in the folder of my executable. However, I noticed a dll not being found on some machines even though it is right there. On my development machine, I found out via Dependencies that the dll is taken in C:/windows/system32/. So from that I infer that on other machines it may be searched for in system32 directory and since it's not there, it's not loaded. I'd like to add that the dll is NOT a known dll, i.e. it is NOT present in the registry at HKML\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs. The library I'm talking about is in this case kinect10.dll and I link my code with #pragma comment( lib, "kinect10.lib" ). So my question is why is the local dll (the one next to the exe file) ignored in this case?

Ensure all dependency dlls are packaged into executable

I thought if you compile a Visual-studio 2013 Win32 project using /MT Code Generation->Runtime library then it will automatically package all dependency dll's - including 3rd party dll's - into the executable?
Currently certain users get an error when running my .exe. Its related to not having a 3rd party dll (OpenSSL):
The program can't start because LIBEAY32.dll is missing from your computer
This error has occurred for users using my .exe on Windows 10 OS's. How can I ensure all dependency dll's are packaged into my .exe?
I currently compile my application on my 64bit Windows 8.1 OS. The win32 visual-studio project is compiled using the following project properties:
Character Set: Unicode char set
Use of MFC: Use standard windows libraries
Whole Program Optimisation: Use Link Time Code Generation
Debug info format: none
Code Generation->Runtime library: /MT
/MT indicates that you are using multithread, static version of the run-time library. This doesn't affect third party dependency, e.g. OpenSSL is still linked dynamically.
To check your dll's dependency I prefer Dependency Walker tool. It will show if some of dependency is missed.
To ensure all dependency linked into your .exe file use static linking for all your third party dependency, e.g. for OpenSSL you should use libeay32MT.lib library.
Nikita is right, use Dependency Walker and I'd add that you're missing some knowledge about what a DLL really is. No offence meant, I know dlls can be a pita. What is a DLL?
By definition a DLL is not included in your .exe but it is loaded at runtime and could be shared amongst several applications. If you want to include it in your .exe it will require some extra non trivial work to embed them into your exe, unpack and load at runtime.
See this post
I'd suggest to use an installer instead, much easier to handle! Just create an installer (you know the click click click "yes-yes-I agree-Ok-Done" wizard installer) that will include your .exe and all needed dependency files. As a reference Inno setup is quite great.

Dll dependency and search order

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.

How to load side by side same name DLLs (Visual Studio)

I have a question about side-by-side assemblies.
Here's the situation:
I have an executable, app.exe, which loads plugins by searching a plugins directory. app.exe depends on a certain A.dll.
I'm developing a plugin which depends on an older, customized version of A.dll that has the same name. Updating this older, customized version to the newer version is impossible, so I thought I might be able to load the two A.dll files simultaneously.
Here's the directory structure:
\bin
app.exe
A.dll (newer version)
\plugins
myplugin.dll
Both versions of A.dll themselves depend on a huge number of other DLLs, which could have similar version problems. (I should also mention I'm working with a 64-bit application, if that makes a difference.)
How do I set this up in Visual Studio such that I can load both A.dll libraries at the same time, so that myplugin.dll uses the older version, whereas app.exe uses the newer version?
Since these are plugins, you load them by calling LoadLibrary, or similar. In which case you can simply pass the full path to the DLL in order to load it.