add custom DLL search path # application startup - dll

I'm racking my brain trying to come up with an elegant solution to a DLL load problem. I have an application that statically links to other lib files which load DLLs. I'm not loading the DLLs directly. I'd like to have some DLLs in another folder other than the folder that the executable is in. Something like %working_folder%\dlls - I'd rather not have dozens (yes ... dozens) of DLLs in my %working_folder%.
I'm trying to develop something that is part of the main app that will adjust the search path # startup. The problem I'm running into is that this new custom DLL path isn't in the system search path. When I start the app it crashes (STATUS_DLL_NOT_FOUND) because the necessary DLLs are not in the appropriate places. What I'd like to do is to check # startup if this new custom DLL folder is in the process environment variable search path and if not add it. Problem is, the application attempts to load all these DLLs before the app executes one line of code.
How do I fix this? I've considered writing a help app that starts first, adjusts the environment variables appropriately and the launches the main app via CreateProcess. This will work I'm sure of it but it makes things difficult on the developers. When they debug the main app they're not going to launch a helper app first - not that they could even do that.
I've tried the registry app path feature with no success. Same chicken and egg problem as before.
What can I do here?

I found Matthew's answer worked for me.
In visual studio 2012 goto your project properties and in
Configuration Properties->Linker->Input->Delay Loaded Dlls
add each dll file that you want to not load until needed.
Although it no longer needs to run before main, this is my code to set the new search path
class RunBeforeMain
{
public:
RunBeforeMain()
{
const TCHAR* dllPathEnvName= name of env variable to directory containing dlls
const TCHAR* pathEnvName= TEXT("Path");
TCHAR newSearchPath[4096];
::GetEnvironmentVariable(dllPathEnvName, newSearchPath, MAX_PATH);
//append bin
_tcscat_s(newSearchPath, MAX_PATH, TEXT("bin;"));
size_t length = _tcslen(newSearchPath);
//append existing Path
::GetEnvironmentVariable(pathEnvName, newSearchPath + length, 4096-length);
::SetEnvironmentVariable(pathEnvName, newSearchPath);
}
};
static RunBeforeMain runBeforeMain; //constructor code will run before main.

[Edit - after re-reading the question I see that the problem you're having is that the DLLs are getting loaded before main starts]
I'm guessing that those libraries are written in C++ and are loading the DLLs from the constructor of some objects in global scope. This is problematic. Allow me to quote Yossi Kreinin:
Do it first thing in main(). If you use C++, you should do it first thing before main(), because people can use FP in constructors of global variables. This can be achieved by figuring out the compiler-specific translation unit initialization order, compiling your own C/C++ start-up library, overriding the entry point of a compiled start-up library using stuff like LD_PRELOAD, overwriting it in a statically linked program right there in the binary image, having a coding convention forcing to call FloatingPointSingleton::instance() before using FP, or shooting the people who like to do things before main(). It’s a trade-off.
[Original answer below]
See this page for the search algorithm used for loading DLLs. You can use SetDllDirectory() to add a directory to the DLL search path.
You also should be able to add a directory to the PATH environment variable using GetEnvironmentVariable() and SetEnvironmentVariable().
Another option is to change the current working directory to the folder containing the DLLs with SetCurrentDirectory(). Just make sure to change the working directory back after loading the DLLs if you ever load any files using relative filenames.

My recommendation is to use delayload linking for the DLLs and call SetDllDirectory() early enough so it can find them when the methods/functions are invoked.

Related

What is the most easy and fast way to edit PE executable file to make it load specified DLL at startup?

I need to make some exe file to load my DLL at startup...
What is the easiest way to do it?
I need this exactly, no any injectors or starters.
I though about adding one more code section into exe, rewriting to there entry point logic and placing DLL loading code, then NOPing original entry point and calling my custom made entry point function. Will this work?
Are there any other easer ways?
I also thinking about changing one of system dll name in hex editor to name of my DLL. Will this work? If my dll then load that replaced system dll?
Any thoughts?
Adding it to the PE's import table should be enough. Woodman's lists a few tools which can do it:
http://www.woodmann.com/collaborative/tools/index.php/Category:Import_Editors

MFC: Steps localizing MFC APP with seperate resource dlls

Before anyone bashes me with, read this first and that second, I have tried following links below to achieve internationalization with MFC.
Creating resourse DLL:
Localization of MFC Components
http://msdn.microsoft.com/en-us/library/x6h91d9w.aspx
Localization for older MFC
htp://support.microsoft.com/kb/198846/en-us
I am new to MFC so please be kind with your answers. So in order to get localization with MFC 7 and above I followed these steps. (Currently using MFC with Visual Studio11)
Created a MFC Project (MyApp) with MFC in a shared DLL
To add a another language (German) to the app, I created a win32 Dll project (MyAppDEU)
Copied the resource file (MyApp.rc) inside same folder and renamed it MyAppDEU.rc
Added the MyAppDEU.rc file to the dll project
In resource view of MyAppDEU.rc, changed the VS_VERSION_INFO -> Block header to "Deutsch (000704b0)"
Changed some strings in the string table to see the difference when the main app loads
Changed the ouput of the MyAppDEU project to build inside the MyApp Output folder
Compiled MyAppDEU to get the Dll
Compiled MyApp with and without following the instructions from point 9
http://support.microsoft.com/kb/198846/en-us
So with all these done, I failed to see any difference in my Application. It loads with the English resouce file which I created the App with. My computer has a German Windows 8 OS. From what I know MFC has inbuilt multilanguage support with Satellite Dlls. I have the correct naming format ApplicationNameXXX.dll. The dlls are in the same directory as the exe.
I hope someone can see what Im doing wrong or missing here. I am fairly new to MFC and appreciate any help regarding this.
[answer adaapted from this SO answer]
I have used a slightly different approach successfully, skipping the MFC inbuilt multilanguage support with Satellite DLLs.
We have multiple DLL projects in our solution, each one containing just one set of resources for a single language (e.g.: AppRes_ENU.DLL). At run-time InitInstance(), we select the appropriate language DLL with code like
CString sResourceDllName;
// format sResourceDllName according to the language ("%s\AppRes_%s.DLL")
hInst_aRes = LoadLibrary(sResourceDllName);
if (hInst_aRes == NULL)
{ // handle <resoure-DLL not available>
return FALSE;
}
AfxSetResourceHandle(hInst_aRes);
and use hInst_aRes to load strings, dialog boxes, ...
Have a look at this software: http://www.apptranslator.com/ . It helps with localisation using satellite dll's; the documentation probably describes how to do it. It's quite simple once you figure our the relationships between ::AfxGetResourceHandle() and hInstanceHandle and all that jazz - the easiest way to learn about that is to read the MFC source. Then you write a few helper classes and off you go :)

asm: Call a DLL

I disassemled a game's DLL and want to insert some code.
I need asm code to call another DLL in the current directory(I'm on Windows).
The background is, that I want to be able to execute custom code in my DLL,
but I can't load the DLL. So my idea was to load the DLL via modified game DLL.
There may be a function in the game which gives me the current directory path the DLL's are but I think I won't find it.
The calls you are looking for are LoadLibrary, which will search in a selection of places including the current directory for the DLL and then load it, then GetProcAddress.
If the DLL makes any other Win32 calls it is probably already linked against kernel32.dll, so that's all you need to do.
It is arguable as to whether modifying the DLL or using DLL injection is faster in terms of how long it takes to write the code since you're going to have to reverse engineer anyway, however, one advantage of pure DLL injection is that all existing code remains unmodified in terms of the installation, making these modifications easier to undo should the user wish to "unpatch" whatever you are doing.
Microsoft Detours comes with setdll.exe and withdll.exe, those utilities will let you start an exe with a custom dll file.

boost::interprocess::shared_memory_object::remove fails

I made some test and I was able to create and remove boost::interprocess::shared_memory_object in a C++/CLI executable without problems. In a C++/CLI dll plugin I'm only able to create the boost::interprocess::shared_memory_object but the removal fails. I verified that the file exists at the time of removal - it is present in boost::interprocess folder in a subfolder named "20110606204418.125000". The memory hasn't been mapped by any other process. Any ideas what might be the cause? At the beginning I thought it may have something to do with the project being a dll and targeting CLR but honestly I don't know.
EDIT: the removal code is called by a different thread than the creation code - is this disallowed?
During debugging I noticed that the file path that is to be removed inside boost::interprocess::shared_memory_object::remove is different from the file created by boost::interprocess::shared_memory_object constructor - the path to be removed points at the root of "boost_interprocess" folder while the actually created file is in the "boost_interprocess/20110606204418.125000" folder. So I reported a bug to boost. We will see what they do about it.

Meaning of building a dll as export library

What is the meaning of building a dll as export library ? I just googled it.I found its a dynamic link library.Can anyone please explain what actually dll is ? and why do we need to add these statement in the .dll file
extern "c" _declspec(dllexport)
I studied the static and shared libraries but Im not sure why do we go for dll files.I learnt .dll is used for the run time. But can you help me and give me more information.Thank you in advance
I may have been a bit harsh in my comments. I am not an authority on dlls, but I have a bit of working knowledge of them, so I will try to give a short explanation.
The difference between static and shared libraries should be easy to find in a web search, but basically the code in a static library gets included into the final executable, so after the linking stage, the actual library file is not needed anymore to run the program; on the other hand, code in a shared library doesn't get included in the main program - the two parts remain separate, so the shared library (called dll on windows) will be needed every time the program is run.
"Building a dll as export library" is a bit of a confusing term. I had not heard of it before, and during a short search could only find it on a cygwin page, which you might have read, considering your initial tags. A dll can export some or all of its functions and data. Exporting means that they are available for other programs and dlls to use. Which names get exported can be controlled in various ways. One of those is inserting _declspec(dllexport) in the declaration of the function. Another way is by using a definition file with an exports section.
When creating a dll, an import library can be created. This is a file that can then be used when building an executable that uses the dll, during the linking stage, to let it know which names are exported from the dll, so the program knows how to resolve references to those functions; in other words: how to import them. (This is not always necessary. Many linkers allow you to directly link against the dll itself, thereby removing the need for an import library.)
I realize it can be confusing, but try to find a tutorial and some small examples to see how it works, and play with it a bit.