How to get the filename of a DLL? - c++

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.

Related

Modify dll function call in compiled exe

I have an exe file that I had written a while back and cannot find the source code for it (it was written in C++).
It calls the MessageBoxA function in user32.dll and passes necessary parameters to it. I want to modify the flags parameter to include the MB_ICONERROR (0x10) flag.
How do I go about finding which bytes in the exe file need to be modified to accomplish this?
You need a disassembler like ICE or IDA. https://www.hex-rays.com/products/ida/support/download.shtml.
Load the executable. Find the Win32 API call on Names Window, to find it, just type the function name. Then double click CODE XREF to go to referenced caller.
Then you get what you want:
Just select the line and click on Hex-View to get the address.

why load the module at runtime?

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.

MFC: How to get DLL file name?

I have an MFC DLL that is loaded by a 3rd party application. How can I get the DLL filename from within the code of the DLL? That is, for example, if the DLL's name is mycode.dll, in code I want to be able to retrieve the string "mycode.dll".
I should add that if the DLL file name is changed on disk then I would like to get the current name on disk (I don't mean changed during run-time but changed between invocations of the main program).
My DLL is implemented as a CWinApp class, my code has no explicit DllMain.
You can call AfxGetStaticModuleState to get a pointer to an AFX_MODULE_STATE structure, which has a member m_lpszCurrentAppName containing the module name (app or DLL depending on where it's called from).
See the Get GetModuleFileName function.
When you pass in NULL for the first parameter, it will just use the handle for the current process.
GetModuleFileName function definitely returns the EXE THAT LOADED THE DLL... not the DLL itself. I would have posted this as a comment above but I don't have enough points yet, meh.

COM & CoGetClassObject()

I have a little problem with CoGetClassObject().
I have an application which must use some DLLs of a specific version,
but they are also present in the system, in a more recent version.
So I start hooking the CoCreateInstance() and loadLibrary(), which I guess are good.
The problem is that the DLLs in the two versions are loaded.
So I think that CoGetClassObject() is the problem/solution because it provides a pointer to an interface of an object associated with a CLSID containing a DLL that the application must use in an older version.
But I don't know what this function "does", so how can I "override" this function ?
thanks.
PS : I'm new in the COM programming.
CoGetClassObject() simply does half the job that CoCreateInstance() does. It returns a class factory. CoCreateInstance() then call IClassFactory::CreateInstance() and releases the IClassFactory. You would only use it if you have a need to create many objects of a certain coclass and want to optimize that. It avoids the cost of creating and releasing the factory over and over again.
You are possibly overlooking a far simpler solution to this problem. You can simply copy the new version of the COM server DLL into the same directory as the client EXE. And create a zero byte file with the name "app.exe.local" where "app" is the name of the EXE. That's enough to force that copied DLL to be loaded instead of the one that the registry points to. The MSDN Library article about DLL redirection is here.
The very simple explanation is CoGetClassObject() opens HKCR\CLSID\{ClassId} and looks at InProcServer32 or LocalServer32 depending on what CLSCTX_* value is passed - that is the COM server path.
Once it find a COM server file path is loads (LoadLibraryEx() with LOAD_WITH_ALTERED_SEARCH_PATH flag in case of in-proc or CreateProcess() in case of out-proc) the COM server. Then it locates and calls DllGetClassObject() for in-proc servers or waits until a class factory is registered for out-proc servers.
This of course ignores stuff like DCOM etc. You can get a better idea of how it traverses the registry using Process Monitor utility.
If you want to load a specific COM DLL regardless of whether there is a newer version installed, and regardless of where the older DLL is located, then simply ignore CoCreateInstance() and CoGetClassObject() altogether. Load the older DLL yourself via LoadLibrary(), then call its exported DllGetClassObject() function directly to get the DLL's IClassFactory interface, then call IClassFactory::CreateInstance() as needed. This is all CoCreateInstance() and CoGetClassObject() do internally anyway, but this bypasses the Registry lookups they perform to determine the DLL path to load.

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.