How to prevent DLL from loading other standard DLLs? - c++

I was experimenting with DLL injection via CreateRemoteThread() (see my other question for details). I injected it into CMD.exe process (note, not the conhost.exe process). The thing is, I noticed that it actually loads 8 other Windows DLLs along with it. It loads them even if I never use any functions from those DLLs.
Now I wonder, is there a way to prevent this? My only guess for now is to not include <windows.h>, then copy definitions for most macros and load libraries that are actually needed via calls to LoadLibrary(). Yet, I guess, it's not the most elegant solution.
Maybe there is some well established method of preventing standard satellite DLL loads?

An option for cases where you only occasionally rely on a particular library is to treat it as delay-loaded.
In Visual Studio, this setting is found in the project properties window under Linker -> Input.
So, for example, if you expect to only sometimes call something from user32.dll you could add "user32.dll" to the Delay Loaded DLLs line (note that this does take .dll not .lib as for input libraries).

Related

What (if any) are the pitfalls of leaving unused dynamically loaded libs linked into a C++ application build?

Question says it all really. This is more for my own curiosity to see if anyone knows of a particular reason why this should be avoided!
The only thought I have had is that perhaps, even if no library functions are called, the compiler will still generate loading code and load the library even though it will not be used. I'm guessing here, would be interested to know what the implications actually are!
Thanks!
At program start up you should expect that the library will be loaded. This is a memory usage and start up time impact (I am not saying how small/big an impact). This is the standard case on Windows with the Microsoft tool chain and, as I understand this answer to another question, is also the case on Linux.
Note that this is different than using LoadLibrary on Windows. LoadLibrary is a Windows facility to explicitly load and use a dynamic library at run time without linking at build time.
The Microsoft tool chain does allow you to optionally specify that a Dll is to be delay loaded. If you do this, then the dll will not actually be loaded until/unless you use the dll. The tool chain does this by substituting build time dll linking with run time loading on demand.
At least on Linux, whenever loader loads a library, it'll spend some time resolving it's dynamic relocations (hit 1). Also having unused libraries sitting in memory will slow down symbol resolution for subsequently loaded libs (hit 2). And finally, loader will run initializers for all loaded libraries (typically C++ constructors but often other stuff) which will consume time (hit 3) and may also effectively disable lazy loading (as initializer calls functions defined in library thus forcing them to be resolved by loader) (hit 4).
As a side note - modern Linux toolchains have a nice flag -Wl,--as-needed which will automatically get rid of unused dynamic dependencies (it's not always straightforward due to transitive dependencies but result is worth it).
If you don't call LoadLibrary, or automatically delay-load the DLL, there are no pitfalls.
https://msdn.microsoft.com/en-us/library/hf3f62bz.aspx
If the library is actually loaded, DllMain will be called. If the DllMain contains bugs or malicious code, anything can happen.

Static link an existing windows binary

I was wondering if I can take an existing windows DLL and static link the dynamically-linked files?
I saw a number of projects to do this with Linux/elf
http://magicermine.com/
http://statifier.sourceforge.net/
http://bitwagon.com/jumpstart/jumpstart.html
I imagine this is most likely not possible, but I am running into some issues in WinPE where when I statically linked the DLLs everything started working great.
I don't have the source to the existing DLL.
I guess I could make a pass-through DLL that exposed all of the same functions and static linked?
There is no tool support for linking in the code of a DLL statically.
The problem is that a DLL is a full Windows PE executable, not a C or C++ “library” in any sense. The C++ standard has only one statement that is vaguely in support of DLL-like things (in the para about dynamic initialization after first statement of main). You’re out of luck.
But if you had the source code (as e.g. with MFC), which you say you don’t, then you could just have created static libraries.
Do note that there already is a meaning for “linking statically” a DLL, namely to have it loaded and have its functions resolved automatically.
Which is the usual way of using a DLL.
And which is in contrast to explicitly loading it dynamically and using GetProcAddress to resolve its functions.
Regarding
” when I statically linked the DLLs everything started working great
presumably earlier you have explictly loaded the DLLs dynamically, and used GetProcAddress, and presumably something about that did not work perfectly.
One main problem with GetProcAddress is that it assumes that the provided function name is encoded as Windows ANSI (the machine-dependent encoding reported by GetACP), and then (apparently) translates that to UTF-8 for the function lookup.
One workaround could be to access the function by ordinal rather than name.
One way to find the ordinal with Microsoft's tools, is to use dumpbin /exports.

Why does my application not need msado15.dll?

This program's stdafx.h is a little like this below.
// ...
#import "./lib/64/msado15.dll" rename("EOF", "EndOfFile") no_namespace
// ...
The program works okay and there are no problems.
I was curious about what would happen if I deleted msado15.dll.
So, I deleted it, and the program still works fine.
I assumed that why the program works without msado15.dll in the same directory must be the dll file is loaded somewhere else.
To make sure exactly where the dll is loaded, I used "Dependancy Walker", and I found out this program is not loading msado15.dll at all.
I would be glad if I could figure out what I'm missing.
Thanks in advance.
Dependency Walker can only see static DLL dependencies (where there's a reference in the EXE's imports table). If a DLL is loaded at runtime via LoadLibrary (or by delay loading -- using /delayload), Dependency Walker will not be able to see this.
#import doesn't actually impose a static dependency on the DLL. It loads the COM typelibrary information from the DLL at compile time. This is transformed into C++ bindings for the COM classes and interfaces defined in the typelibrary. You can see these as .tli and .tlh files in your Debug or Release directory. You might be able to remove the DLL file, and -- as long as these files still exist -- VS might continue to build your project successfully.
Similarly, at runtime, since #import doesn't actually impose a static dependency on the DLL (that is: it won't add it to the imports table in the EXE), Dependency Walker will be unable to see this dependency.
At runtime, however, the EXE will call (indirectly) LoadLibrary, and (if the DLL is missing) this will cause a failure at runtime, which your program might deal with appropriately, or which might cause your program to crash.
Even with all that said, #import merely imports a COM typelibrary. The COM typelibrary defines the interfaces used in the COM objects, along with the CLSID values of those objects. In order to find the code that implements the COM objects, the CLSID values are resolved using the registry (in HKEY_CLASSES_ROOT\CLSID. The code implementing the COM objects may not actually be in the same binary as the original typelibrary.
This means that the DLL may not even be required at runtime. I think that this is rare, however.
Moreover, the COM objects may be implemented as out-of-process objects (meaning that another EXE is loaded). In this case, all that's loaded into your process will be the proxy/stub DLL configured for the relevant interfaces. Often, these will be defined using the TLB (in which case, your #import-ed DLL will be loaded); but they may be implemented in a completely different DLL. Either way, the DLL will be loaded dynamically, which means that Dependency Walker won't see it.
To see which DLLs are loaded by the process, you will need something like SysInternals Process Monitor or Process Explorer.

Dll dependency version conflict

I am using C++ with Visual Studio 2008 Express.
We are supplying a binary-only Windows library to a client, which itself uses a number of other libraries. Therefore we shipped both our dll file, along with the dll files that we use. Now the issue is that our client uses some of the libraries that we also use, but in another version. Therefore he can not use our library, since the libraries we both depend on are incompatible.
Technically I think it should be possible that both dependency versions are loaded into the process space. However, I am unsure how to do this, as both their application, as well as our dll look for the same dependency dll file name. Can anyone tell me what the best/cleanest way to deal with this problem is?
Thanks!
Generally speaking, it won't work. This is due to the fact that the third party DLL versions might interfere with each other when loaded into memory. One example could be if there is an exclusive resource like e.g. a file in a specific directory. Or a specific device. The problem is, nobody knows probably not even the manufacturer of the 3rd party DLLs - so extensive testing is necessary.
But maybe you're lucky and it works anyway. My recipe:
Put your DLL "DTAG.DLL" and all needed DLLs in a subdirectory of the applications directory with a fixed name e.g. "DTAG_LIB".
Write a import library by hand (there are other possibilities using DELAYLOAD). In that library load your DLL with LoadLibraryEx. Provide an absolute path ending with "DTAG_LIB\DTAG.DLL" and the flag LOAD_WITH_ALTERED_SEARCH_PATH. Windows will then load your DTAG.DLL from this directory and all needed DLLs from that directory also. Don't set the PATH to "DTAG_LIB"!
Your customer has to link against your manual import lib.
You could solve this kind of problem using a (new) additional DLL you would deliver and that would take care of handling the versions conflict (at runtime) - being a kind of proxy between your app and its dependencies.
An alternative would be to use the Windows Forwarded Libraries mechanism.
Forwarders are a handy way to accommodate functionality moving from one DLL to another
You can use several ways to declare forwarders, such as a module definition (.def) file and a #pragma:
#pragma comment(linker, "/export:function=otherdll.function")

Loosen DLL dependencies at start of application

in my Windows C++ program I have a few dependencies on DLLs (coming with drivers of input devices). I don't actually load the DLLs myself, but the drivers provide (small) .lib library that I statically link against (and I assume it is those libraries that make sure the DLLs are present in the system and loads them). I'm writing an application that can take input from a series of video cameras. At run-time, the user chooses which one to use. Currently my problem is that my routines that query whether a camera is connected already require the functionality of the camera being present on the system. I.e. let's say there is camera model A and B, the user has to install the drivers for A and B, even if he knows he just owns model B. The user has to do this, as otherwise my program won't even start (then when it started it will of course tell the user which of the two cameras are actually connected).
I'd like to know whether there is any possibility, at run-time, to determine which of the DLLs are present, and for those that aren't, somehow disable loading even the static (and, thus, dynamic) component.
So basically my problem is that you cannot do if(DLL was found){ #include "source that includes header using functions defined in lib which loads DLL"}
I think using the DELAYLOAD linker flag may provide the functionality required. It would allow linking with the .lib files but would only attempt to load the DLL if it is used:
link.exe ... /DELAYLOAD:cameraA.dll /DELAYLOAD:cameraB.dll Delayimp.lib
The code would be structured something similar to:
if (/* user selected A */)
{
// Use camera A functions, resulting in load of cameraA's DLL.
}
else
{
// Use camera B functions, resulting in load of cameraB's DLL.
}
From Linker Support for Delay-Loaded DLLs
:
Beginning with Visual C++ 6.0, when statically linking with a DLL, the
linker provides options to delay load the DLL until the program calls
a function in that DLL.
An application can delay load a DLL using the /DELAYLOAD (Delay Load Import)
linker option with a helper function (default implementation provided by
Visual C++). The helper function will load the DLL at run time by calling
LoadLibrary and GetProcAddress for you.
You should consider delay loading a DLL if:
- Your program may not call a function in the DLL.
- A function in the DLL may not get called until late in your program's
execution.
You need to load the libs at run-time. Take a look a look at LoadLibary.
This is an MSDN article about this: DLLs the Dynamic Way I just glanced over this. It's very old.
This one shows the usage of LoadLibrary: Using Run-Time Dynamic Linking