C++/CLI: Use LoadLibrary + GetProcAddress with an

2019-02-18 08:56发布

问题:

Up until now, I had some sort of plugin mechanism in which I loaded dlls using LoadLibrary and GetProcAddress to create a concrete object and return a common interface. This worked fine until I decided that one of the dlls should be an exe.

LoadLibrary's documentation says that it can be used for exe's as well, so I gave it a shot. The exe gets loaded without errors, as GetProcAddress. But when I try to call my concrete object's constructor, I get an access violation.

I thought this would happen because loading an exe does not load all the dlls it uses. So I tried loading them using LoadLibrary, but I got the same error. Any advice on this?

Here's my code (mixed C++/CLI):

Interface* MCFactory::LoadInstanceFromAssembly( String ^ concreteAssemblyName, String ^ param ){
    string fullPathToAssembly = "";
    fullPathToAssembly += FileSystem::GetPathToProgramDirectory();
    fullPathToAssembly += "\\" + marshal_as<string>(concreteAssemblyName);

    MODULE hDLL = AssemblyLoader::GetInstance().LoadAssembly( fullPathToAssembly ); 

    Interface* pObject = NULL;
    if (hDLL != NULL){
        t_pCreateInstanceFunction pCreateInstanceFunction =
            (t_pCreateInstanceFunction) ::GetProcAddress (hDLL, CREATE_INSTANCE_FUNCTION_NAME.c_str());

        if ( pCreateInstanceFunction != NULL ){
            //Yes, this assembly exposes the function we need
            //Invoke the function to create the object
            pObject = (*pCreateInstanceFunction)( marshal_as<string>(param) );              
        }
    }           
    return pObject;
}

(AssemblyLoader::GetInstance().LoadAssembly is just a wrapper for ::LoadLibrary)

回答1:

It is possible.

http://www.codeproject.com/Articles/1045674/Load-EXE-as-DLL-Mission-Possible

The idea is to patch the IAT, then call the CRT. Of course, the EXE must be relocatable, and by default (ASLR) it is.



回答2:

You can use LoadLibrary and GetProcAddress on the main executable for your process, this allows dynamic exports in the reverse direction (.exe to .dll).

You cannot load a second .exe into your process memory space, except for access to resources/data, because .exe code is not relocatable. (Pure MSIL .exe files are an exception, because there is no code in the file, it's all generated by the JIT.)

Basically, LoadLibrary on a .exe is useful only when

  • The .exe is the main process exe, in which case you might as well use GetModuleHandle

    or

  • The LOAD_LIBRARY_AS_DATAFILE flag is used



回答3:

Whilst Ben's answer covers most cases this article http://sandsprite.com/CodeStuff/Using_an_exe_as_a_dll.html may be useful in some circumstances