4

到目前为止,我有某种插件机制,其中我使用 LoadLibrary 和 GetProcAddress 加载 dll 以创建一个具体对象并返回一个公共接口。在我决定其中一个 dll 应该是 exe 之前,这一直很好。

LoadLibrary 的文档说它也可以用于 exe,所以我试了一下。exe 加载时没有错误,如 GetProcAddress。但是当我尝试调用我的具体对象的构造函数时,我遇到了访问冲突。

我认为这会发生,因为加载 exe 不会加载它使用的所有 dll。所以我尝试使用 LoadLibrary 加载它们,但我得到了同样的错误。对此有何建议?

这是我的代码(混合 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 只是 ::LoadLibrary 的包装器)

4

3 回答 3

6

您可以在您的进程的主要可执行文件上使用LoadLibraryGetProcAddress,这允许反向动态导出(.exe 到 .dll)。

您不能将第二个 .exe 加载到您的进程内存空间中,除非访问资源/数据,因为 .exe 代码不可重定位。(纯 MSIL .exe 文件除外,因为文件中没有代码,都是 JIT 生成的。)

基本上,LoadLibrary在 .exe 上仅在以下情况下才有用

  • .exe是主进程exe,在这种情况下你不妨使用GetModuleHandle

    或者

  • LOAD_LIBRARY_AS_DATAFILE标志被使用

于 2011-06-08T22:46:10.783 回答
3

有可能的。

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

这个想法是修补 IAT,然后调用 CRT。当然,EXE 必须是可重定位的,默认情况下 (ASLR) 是可重定位的。

于 2015-11-11T20:45:24.650 回答
2

虽然本的回答涵盖了大多数情况,但这篇文章http://sandsprite.com/CodeStuff/Using_an_exe_as_a_dll.html在某些情况下可能很有用

于 2011-09-16T08:32:27.723 回答