why load the module at runtime? - c++

Sometimes, I read the source code, found that the module is loaded manually like below.
HMODULE hmodMscoree = LoadLibraryEx(L"mscoree.dll", NULL, 0);
typedef HRESULT (STDAPICALLTYPE *GETCORVERSION)(LPWSTR szBuffer, DWORD cchBuffer, DWORD* dwLength);
GETCORVERSION pfnGETCORVERSION = (GETCORVERSION)GetProcAddress(hmodMscoree, "GetCORVersion");
Why does it load the mscoree.dll at runtime?
Best Regards,

One advantage is that if you load a DLL dynamically, then the presence of a DLL (e.g. mscoree.dll), and the presence of a function in the DLL (e.g. GetCORVersion in mscoree.dll) will be checked only when the application tries to load the DLL and call the function, respectively. If the DLL is missing, or one of its function is missing because you only have an older version, then there won't be any problem in cases when the application does not use this functionality. On the contrary, if the DLL is statically linked, and it is missing, then the application simply won't start (you will get an error message).
Example: we have a complex industrial measurement software, which links wpcap.dll dynamically. In cases when the measurement does not include packet sniffing, we do not have to install WinPcap.

One reason for loading a module and using GetProcAddress is that the DLL may not be present on the computer. That way the application can run even if the DLL is not there. You would of course need to verify that both LoadLibrary and GetProcAddress were successful.

Related

Delay-load DLL in windows: can I dynamically choose what DLL name to look for? (c++)

I have a library that calls functions from foo.dll.
In my MSVS settings, I delay load foo.dll and manually check for its existence before attempting to call its functions (so that if it doesn't exist on a machine, my library won't crash).
If the DLL-existence check succeeds and I call its functions, the DLL is auto-loaded by the windows delay load helper and everything functions well.
However, on 50% of my user's machines, foo.dll was renamed to bar.dll. Even if I call LoadLibrary("path\bar.dll") and it succeeds, my library still crashes because the delay load helper still tries to load foo.dll when I call one of the functions.
I used a hex editor to view the content of my library, and in one location "foo.dll" is explicitly named. If I rename that entry to "bar.dll" using the hex editor, my library runs flawless when bar.dll is the name of the DLL on a user's machine (and crashes where foo.dll is the name). So it seems the issue is soley the delay load helper trying to load the explicitly-named DLL inside my library.
How can I tell the delay load helper that the DLL in question goes by a name that doesn't match the explicit file name in my compiled library?
To tell the delay load helper to use a different DLL than what is linked to, you can use a delay load failure hook. Per MSDN:
Linker Support for Delay-Loaded DLLs: Error Handling and Notification
If your code needs to recover or provide an alternate library and/or routine on failure, a hook can be provided to the helper function that can supply or remedy the situation. The hook routine needs to return a suitable value, so that processing can continue (an HINSTANCE or FARPROC) or 0 to indicate that an exception should be thrown. It could also throw its own exception or longjmp out of the hook. There are notification hooks and failure hooks.
When a delay-loaded DLL fails to load, the hook is called with a dliFailLoadLib notification containing details about the load operation and error. The hook can recover from the error by returning a valid HMODULE for the helper to use, or return 0 to fail the load operation.
If the notification is dliFailLoadLib, the hook function can return:
0, if it cannot handle the failure.
An HMODULE, if the failure hook fixed the problem and loaded the library itself.
So, if the error reports the failed DLL is foo.dll, your hook can load and return the HMODULE for bar.dll, and then the helper will load all of foo.dll's delay-loaded functions from bar.dll instead.

Loading all DLL functions

Is there a way to load all functions from runtime loaded DLL? Current code:
hGetProcIDDLL = LoadLibrary(dll);
typedef int(*f_connection_a)(args);
typedef int(*f_connection_b)(args);
typedef int(*f_connection_c)(args);
f_connection_a connection_a = (f_connection_a)GetProcAddress(hGetProcIDDLL, "connection_a");
f_connection_b connection_b = (f_connection_b)GetProcAddress(hGetProcIDDLL, "connection_b");
f_connection_c connection_c = (f_connection_c)GetProcAddress(hGetProcIDDLL, "connection_c");
As you can see, this gets cumbersome quickly as you have to define every DLL function like this. Is there a way to load all DLL functions instead of having to list them?
Since here the "connection_*" are only a variables, there is no way to initialize them other than to run a code such as calling a function to get an address of a function. WinAPI doesn't have bulk method for binding functions at run time. This is limitation of WinAPI. The intention of this method was to check the presence of a functions individually and to delay loading library up to the point when it will actually be needed (or to avoid loading at all if it is not used).
But you can avoid such messy code by binding DLL at program loading stage using Import Table feature. In this case Windows loads executable image into memory, then loads all dependent DLLs and automatically binds the imported functions before launching executable code. For this you need:
Prepare *.def file for the library you need to load. The simplest method is to launch "impdef.exe my.dll" command on dll file. You may find tiny impdef.exe that doesn't need installation in TinyC package (see https://bellard.org/tcc/).
Then prepare corresponding *.lib file by launching "lib /def:my.def /out:my.lib"
After that link produced library with your project as regular library.
The drawback of this method is that if DLL is absent or corrupted, your executable file won't start at all. But this is a small payment for the convenience of importing functions.

How do I redirect calls to ole32.dll to my own proxy DLL?

I'm trying to detect all calls to CoCreateInstance in some process I'm starting (ideally, I'm able to detect calls in child processes as well).
To achieve this, using Microsoft Visual Studio 2008 on Windows 7, I create a proxy DLL which forwards all but one call in the standard ole32.dll library as described in various articles, e.g.
Intercepted: Windows Hacking via DLL Redirection. The resulting DLL looks fine, but I just can't make existing programs (I'm using the standard ActiveX Control Test Container (tstcon32.exe) as a test application) pick up my proxy DLL. No matter what I do, the programs always seem to pick up C:\Windows\SysWow64\ole32.dll according to Process Explorer. I tried a few things so far:
Prepend the directory which contains my proxy DLL to the PATH and then invoke the program; didn't seem to have any effect.
Copy my proxy DLL into the same directory as the invoked program; no luck.
Create a .local file in the same directory as the invoked program as described in the Dynamic-Link Library Redirection article and put my proxy DLL into the same directory - didn't work either. But then, I read that this stopped working on more recent Windows versions. Additionally, ole32.dll is a "known DLL" according to the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs registry setting, so .local-based redirection is probably not going to work anyway.
Use manifest-based redirection as described e.g. in the DLL redirection using manifests question, but that didn't seem to have any effect either. However, this approach seems to be non-trivial, so chances are I did something wrong.
Does anybody have experience with redirecting calls to standard DLLs such as ole32.dll using a stub DLL? How did you force the applications to pick up your stub DLL?
I realise this is a little late by about 6 months, but I was trying the same thing and have some additional notes:
You can take ownership of and remove ole32.dll from HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs. This allows you to get around the fact Windows has locked these keys.
Creating a key SafeDllSearch with the value 0 in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager is supposed to alter the search path.
Having applied both these techniques and rebooting, hooking still did not work. I went one further, booted up a VM with one of our rescue CDs (a Windows PE based environment) and overwrote the one in system32. Windows does not boot as a result - no symbol errors, but I never get as far as LogonUI.exe. It is possible my hooked functions are broken, so this may be the cause.
Anyway, that produced an actual, tangible hook effect - albeit one that screams "broken"!. Unfortunately it appears highly difficult to debug, and I may be resorting to the other method of hooking - namely IAT patching.
Edit another experiment I performed was to explicitly load the Dll myself into the target process' address space. A snippet of code that does this looks like this:
wchar_t* TargetPath = argv[1];
wchar_t DllPath[] = L"N:\\experiments\\ole32.dll";
STARTUPINFOW si;
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(STARTUPINFOW));
memset(&pi, 0, sizeof(PROCESS_INFORMATION));
// create process suspended
BOOL bResult = CreateProcess(NULL, TargetPath, NULL, NULL, FALSE,
CREATE_SUSPENDED, NULL, NULL, &si, &pi);
// write DLL name to remote process
void* RemoteAddr = VirtualAllocEx(pi.hProcess, NULL, sizeof(DllPath)+1,
MEM_RESERVE | MEM_COMMIT, PAGE_READONLY);
WriteProcessMemory(pi.hProcess, RemoteAddr, DllPath, sizeof(DllPath), &BytesWritten);
// get handle to LoadLibraryW
PTHREAD_START_ROUTINE pfLoadLibrary = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
// create remote thread calling LoadLibraryW
HANDLE hThread = CreateRemoteThread(pi.hProcess, NULL,
0, pfLoadLibrary, RemoteAddr, 0, NULL);
// start remote process
ResumeThread(pi.hThread);
Error handling removed for brevity.
Basically, the objective was to force load my ole32.dll into the target's address space before it had chance to load ole32.dll from system32. In my case, ole32.dll was being loaded later on in the application's load routine, so this in theory should have worked. In practice, it did not. I am not sure why.
Update My original code failed because the DLL had unresolved symbol warnings at runtime. This technique does work So apparently, it loads both my ole32.dll AND the one from system32. To ensure the library was loading successfully, I added a LoadLibrary(DllPath) call to the code above.
Perhaps winapioverride can help you. It can log all win api calls without programming anything. It therefore injects dlls to the process that do the logging. If I recall it correctly it is also possible to inject own custom dlls - even before the process actually executes any code. The documentation has some information about spying com objects.

WTL way of forcing resources to load from a dll in a non mfc app? (we are using WTL/ATL, not straight win32)

I posted this question previously and now have the localized strings loaded (the ones we get with LoadString()) but I also need to load all the other resources from the satellite DLL.
MFC has the AfxSetResourceHandle () call, but I need something equivalent for a non-mfc app? I suspect I have to set that in the initialization code somewhere so all my resources are loaded from another DLL. How do I do that in a WTL (windows template library) context?
EDIT:
This summarizes our problem.
We are not using straight win32, but ATL and WTL for windows stuff. So we can't rely on the MFC stuff and we don't have low level control of the loading of menus and dialog resources.
EDIT:
Hmmm...
This seems to have an answer, but I was hoping for something better than that. For example - a SetResourceInstance() method analog to GetResourceInstance() in a CAppModule object.
The resource functions (FindResource, LoadResource) take a handle to a module as one of the parameters.
Use GetModuleHandleEx to get the module handle for the DLL.
Edit: Additional info for ATL/WTL.
WTL uses ATL::_AtlBaseModule.GetResourceInstance() for the module handle in its Win32 calls. There's a SetResourceInstance function that you can call to change the module that's used. Something like this should work at the beginning of your program:
HMODULE hmod;
::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN, myDllFuncPtr, &hmod);
ATL::_AtlBaseModule.SetResourceInstance(hmod);
Occasionally the above method is not usable, such as when you still have to support Windows 2000 for some reason. In such case it's good to have the following trick handy.
We declare a static variable, which means that its address will be inside the module into which it was linked. We then use the address to that variable to query for the base address of that allocated area, which is what the HMODULE is.
HMODULE GetCurrentModuleHandle()
{
MEMORY_BASIC_INFORMATION mbi;
static int iDummy;
VirtualQuery(&iDummy, &mbi, sizeof(mbi));
return (HMODULE)mbi.AllocationBase;
}
This does by no means invalidate Mark's answer! Just keep it in mind as a fallback option if you need your programs to run on ancient systems.

How to get the filename of a DLL?

I have a C++ Windows application myapp.exe which loads several plug-ins.
Plug-ins need to find the path to their DLLs. I can use GetModuleFileName for this, but it need the handle for the plug-in DLL. I don't know where to get this handle. GetModuleHandle(NULL) returns the handle to the executable.
One option is to use GetModuleHandle (GetModuleHandle("myplugin.dll") ) , but this requires the name of the plugin to be hardcoded which I want to avoid.
Any help is appreciated.
Paul
I don't know where to get this handle
It's passed as a parameter to your DLLMain() entry function.
If the plugin can't access its DLLMain() entry function, it can use the VirtualQuery function on a piece of its own memory and use the AllocationBase field of the filled-in MEMORY_BASIC_INFORMATION structure as its HMODULE.