fancycode/MemoryModule — pull request #9 by Juntalis (2012-12-19 08:06:21+00:00)
Title: Implement functionality for multiple inter-dependent modules

**Note:** This pull request is actually incomplete as is. In its present state, it functions and uses the same API as the current implementation, but without the "module set" functionality, it's pretty much just adding a bit of extra code without any significant increase in functionality.

Anyways, I wanted to do see if you were interested in adding this functionality,and I was also interested in getting your take on the best way to implement this:

The idea is to implement a way for the developer to load multiple DLLs into memory, using exported functions from previously loaded modules as imports when necessary. To do this, a developer would need to specify the file name of the DLLs he intends to load into memory. Most of it would be pretty easy to implement:

* Typedef a struct to act as a map, linking the various MEMORYMODULE's to their original file names.
* Write a proxy function for LoadLibraryA that searches the aforementioned map structure for the library name specified, and if it is unable to find it, falls back on the system's implementation. If, however, the library is found, check whether it's already been initialized, and if so, increment the initialized field. (which I've modified slightly to act as a ref count, rather than as a simple boolean flag) If not, MemoryLoadLibrary the data.
* Write proxy functions for GetProcAddress and FreeLibrary that check whether the module specified is a MEMORYMODULE or an actual HMODULE, and pass the argument along to the appropriate function.
* Write the necessary functions for managing the map struct. (Initialization, adding modules, removing modules, etc)

I'm trying to do this with minimal changes to the existing code, so modifying the original MEMORYMODULE structure for the sake of the proxy GetProcAddress and FreeLibrary functions isn't an option at this point. Instead, I figured I'd do something like:

FARPROC WINAPI ModuleSetGetProcAddress(HMODULE module, LPCSTR procName)
{
PWORD lpe_magic = (PWORD)data;
if(*lpe_magic != IMAGE_DOS_SIGNATURE) {
return MemoryGetProcAddress((HMEMORYMODULE)module, procName);
} else {
return GetProcAddress(module, procName);
}
}

I don't think the system LoadLibraryA will load a dll without the proper signatures, so in theory, this should work.

The part I'm having trouble on, however, is keeping the code modular to allow for utilizing multiple module sets in a single process. Without a global variable to reference (And without changing the signature of the LoadLibrary call), I can't think of a way for the LoadLibrary proxy to figure out what map it should search for the dllname. The only thing I could think of thus far is adding a new function to the main MemoryModule.c to replace the existing LoadLibrary call in BuildImportTable. Essentially, it would be something simple like:

static HMODULE LoadImportLibrary(HMEMORYMODULE module, LPCSTR importLib)
{
return LoadLibraryA(modName);
}

Seems like a bit of a waste, but it would allow me to do the necessary pointer math in the module set implementation to find the address of the map structure.

Anyways, sorry for the short essay.

_Also, I realized in looking back over the code that I didn't need to change the calling convention for MemoryGetProcAddress, so expect that to be reverted in the next commit._