Dynamically Load 2 different DLL's with the same API in c++ - c++

I have a C++ application that implements external user written "Apps" as DLLs. My plan to implement this is by loading dlls in a specific directory and starting a new thread for each DLL. Each DLL has its own "main" that is just an exported function __dllspec(dllexport).
I basically treat DLLs that use this API as a poormans executable (no virtual address space, less secure, its just a thread instead of a seperate process etc)
The main loader code basically calls the "main" function in the DLL while maintaining the list of loaded DLL handles.
Also I'd like these Apps to draw to a dedicated space provided by the main loader. I would provide this ability via a UI API provided by the loader exposed by requiring Apps to dllimport the required functionality.
My question is, is there another way to implement this app like functionality where "Apps" can be removed or added during runtime?

Related

Hooking dll into running process using loadappinit_dlls registry key

Currently I am working on a application in which I need to hook dll into running application. In order to achieve this goal, I have updated the LoadAppInit_DLLs registry key to 1 and AppInit_DLLs has been set to the location of the dll.
This approach works fine as the application get opens the dll get injected into the process of that application.
However, this injection process not only inject the dll into the application that I am interested, but it injects it for all the applications that I am starting in windows operating system. How could I specify this inject to happen only for the application that I need it to inject and not for all the application. I am looking for a way to know from the dll that which application it is calling and then to decide whether to load it or ignore loading it.
How could I specify this inject to happen only for the application that I need it to inject and not for all the application.
Using AppInit_DLLs, you can't.
Working with the AppInit_DLLs registry value
All the DLLs that are specified in this value are loaded by each Microsoft Windows-based application that is running in the current log on session.
I am looking for a way to know from the dll that which application it is calling
A DLL is loaded into the address space of a process. A DLL can call GetModuleFileName(NULL) to get the
full path and filename of the process it has been loaded into.
and then to decide whether to load it or ignore loading it.
Normally, a DLL's DllMain() entry point allows the DLL to selectively abort loading by returning FALSE to the DLL_PROCESS_ATTACH notification. However, AppInit_DLLs specifies additional DLLs that are deemed required for successful app initialization, similar to static-linked DLLs, so it does not allow DLLs the luxury of selective loading. If an AppInit DLL returns FALSE, the whole process is aborted.
You will have to manually hook the DLL into the target app yourself. You can do that by either:
Using CreateRemoteThread() to call LoadLibrary() from inside a specific process to load the DLL into that same process. The DLL's entry point does not need to validate the loaded process, since the loading app has already done so when deciding which process to load the DLL into.
This approach takes some setup, though. You have to use VirtualAllocEx() and WriteProcessMemory() to copy the DLL's full path string into the target process before you can then have the remote thread call LoadLibrary() with that path string as input.
Using SetWindowsHookEx() to install a global system-wide hook that is implemented inside the DLL, so the DLL gets loaded into every running process.
The difference between this approach and using AppInit_DLLs is that this approach is handled dynamically after each process is running, and thus allows the DLL the luxury of selectively aborting its own loading without terminating each process it rejects.
Configuring the Application Compatibility Toolkit to load your DLL into the specific app(s) you are interested in.
All DLLs, listed in the LoadAppInit_DLLs registry key will be loaded to the all processes, linked against user32.dll. If for some reason your dll is unable to load (for example - you had returned FALSE from the DllMain on DLL_PROCESS_ATTACH) the process will be terminated. Using LoadAppInit_DLLs even for the debugging purposes is messy and pretty dangerous. Perhaps you should choose another hooking mechanism, for example using SetWindowsHookEx

Loading custom DLLs instead of original DLLs

The question below is for educational purposes only and the discussed featured are not meant to alter registered DLLs or develop a malware but for learning and experiencing.
Recently I've been exploring few methods to load my own custom DLLs instead of an application's original DLLs.
One of the methods that came up was the <exe>.local method.
After experiencing with this method a little bit and after I removed the KnownDlls entry from the registry I managed to replace some system DLLs with my patched DLLs successfully.
These are the DLLs:
However, the DLLs are IN the local folder:
However, there are still some DLLs that insist loading from the system32 directory, although they are present in the local folder.
Is there any way I can force the DLL's to load from the local folder instead of the system32 folder?
This is not an answer so much as a rambling, unsourced, brain dump.
It does serve to explain why I am not surprised at your result. This boils down, for me, to the crucial difference between CreateProcess and LoadLibrary, and how Win32 processes work.
Normally, when using LoadLibrary, you are using it from within the process you want the dll to be loaded into. As such, it can take advantage of a whole bunch of in-process context information about activation contexts, dll search paths etc. including knowledge of things like the app.local flag.
All these values are specific to the current process and it is not the job of any other process (or even the Kernel) to track stuff like this.
But, if we look at CreateProcess we can see some problems. When it is initially called, it is called in the context of the launching, not destination, process, so it knows nothing of the destination processes activation context. In fact, the destination process does not exist yet.
The CreateProcess implementation needs to create a NT process, and execute some code in it asap to perform the process load as it doesn't make any sense to instantiate all that per process context stuff in the current process.
But, to do that, there needs to be at least some code in the destination process: The kernel code responsible for parsing the EXE files header, extracting the headers and building the activation contexts that will be used to load the remaining dlls.
This means that, unfortunately for you, kernel32.dll and some dependencies need to be mapped into a process long before that process is capable of building a dll search context, noticing the app.local flag etc.
You should look at how the Windows loader works. This is OS version dependent, but some of those DLLs load before your program and the loader always looks for them on a path provided by the system. Look at the sequence by starting your program with WinDbg.

load DLL from archive

I am currently writing an application and I want to make it as extensive as possible for me -> every component should be considered as an extension except core functionality.
Basically I provide abstract class which needs to be implemented (header file) and a static library. Also I provide .py file with abstract class and example of .component file which is basically .ini file - there user should declare what's the class_name, python_class_name and etc.
So in the end user need to create DLL, python script, .ini file. Then zip into an archive with extension package. Well that's the plan.
My application is supposed to look for .package file, unzip it, get from there .component file, read it, load class from DLL by name, create object and store it in global object register inside application. Then I create c++ and python bridge (knowing what interface is implemented by python class helps a lot) which allows to invoke python methods by name. That python script should be store into zip too.
I've got basically two questions:
1. Is it possible to load DLL from `.zip` in runtime? I believe its hardly possible without creating temporary unzipped file and then deleting it.
2. Is there other to load DLL except basic approach with `windows.h` header? I use `boost` library there and there, maybe there is some way to do it?
For zipping as far as I know there no better solution then using zlib so I am planning to use that.
It is possible to load DLL from zip/memory. Actually many exe packers/virus do load the dll manually.
It is actually the same question of the first question.
What LoadLibrary does?
Mapping or loading the DLL into memory.
Relocating offsets in the DLL using the relocating table of the DLL (if present).
Resolving the dependencies of the DLL, loading other DLLs needed by this DLL and resolving the offset of the needed functions.
Calling its entrypoint (if present) with the DLL_PROCESS_ATTACH parameter.
You could write your own code to load the library manually. However, if you do not load the dll the same way as LoadLibrary does, there could be some limitations.
refer: http://www.codeproject.com/Tips/430684/Loading-Win-DLLs-manually-without-LoadLibrary
You can load .dll library from memory, at least with trivial .dll without more dependency.
What you do is to emulate what LoadLibrary do. Parse the PE executable yourself, call VirtualAlloc, setup proper page attributes, copy the payload, do relocations, and lookup the symbols.
A quick search reveal a detail yet simple tutorial here.
Note that this may also upset certain virus scanner.

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.

How to load a DLL as a local server

I really need help...
I have implemented a COM component (i.e A.dll) with IDL, also coded a wrapper DLL (B.dll) for that component. I have implemented required export functions for DLL "A" and registered it with "regsvr32.exe".
Problem is that I have 3 EXE files that uses B.dll to access methods of A.dll. But, I could not manage to create a local server for A.dll, therefore every EXE loads a new A.dll and B.dll. I want to load A.dll only once, and need to realize this functionality in B.dll. Last statement is open for discussion also.
However, I could not manage to find any useful example or resource regarding this problem. Any help will be appreciated, thanks in advance.
A DLL mediated by COM is known as an in-process server. Which suggests your problem: it will always be mapped into the memory space of its clients, just like any other DLL. Similarly any DLLs it loads will be mapped into the original process. It is not clear from your question why you don't want to use a DLL. If it is to save resources then consider that only data will be duplicated; the code will only be loaded once. If it is because you want them to share data, then consider using shared memory. If you really want all three .exe's to be served by an instance then what you need is a COM local server, which will be implemented by an .exe, not a .dll.
There's no such thing as "create a local server". In-proc server has to be loaded into each consumer process, there's no way around that - each consumer is a separate process, so it has its own copy of code and data.
In order to have a single process executing COM server code for all of the consumers you have to create an out-proc server. To do the latter you can either reengineer your COM server or try to use COM+ server application. This way you can have a separate process running the COM server code several consumers can connect to.