将EXE作为DLL加载,本地vftable [英] Loading an EXE as a DLL, local vftable

查看:111
本文介绍了将EXE作为DLL加载,本地vftable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 test.exe 的exe,它通常用作独立应用程序。我想将此exe用作另一个应用程序app.exe中的模块(一个dll)。



test.exe中的代码确实非常简单,例如:

  void doTest()
{
MyClass * inst = new MyClass();
inst-> someMethod();
}

其中 someMethod()是虚拟的,而MyClass具有虚拟的d.tor。

doTest()从test.exe导出,因此一个名为test.lib的库是创建的

app.exe与此库链接,以在启动时静态加载test.exe。



当我运行test.exe时单独运行就可以了,但是当我从app.exe中加载它时,它崩溃了。

使用调试器进入代码后,发现崩溃是在对虚拟方法的调用中。事实证明,vftable以某种方式变坏了。



经过一些调查,结果发现,当运行MyClass的构造函数中的代码时,vftable是一回事,但是调用 new 返回,它将被其他称为本地vftable的内容替换。我发现关于这是为什么的模糊讨论



经过大约一天的调试,我发现在两种情况下,当test.exe独立运行时,本地vftable中的指针都是相同的作为模块加载。这是不对的,因为将test.exe加载到其他地址中...

为了测试这一理论,我将链接器选项中的加载地址更改为在加载时将test.exe加载的地址。在app.exe中,现在,瞧,一切正常。



很明显,这不是永久解决方案,因为下次该随机选择的地址可能会被占用,并且同样的问题将再次发生。



所以我的问题:为什么这个本地vftable绑定到exe的静态加载地址?将exe作为模块加载是一件坏事吗?为什么该exe假定它已加载到其静态地址?



仅出于上下文考虑:这全部是使用MSVC 2008,Windows XP x64完成的。

解决方案

我最终使用的解决方法是简单地添加一个编译配置并将exe编译为真实的dll,而不是强制它像一个一样运行。 / p>

使用 / fixed:no 由于某种原因不能解决问题。



exe和dll之间的另一个区别是入口点不同。 DLL的入口点是DllMain,其中exe在CRT中具有其入口点,最终会调用main()或WinMain()。


I have an exe named test.exe which is usually used as a stand-alone application. I want to use this exe as a module (a dll) inside another application, app.exe.

The code in test.exe does something really simple like:

void doTest()
{
    MyClass *inst = new MyClass();
    inst->someMethod();
}

Where someMethod() is virtual and MyClass has a virtual d'tor.
doTest() is exported from test.exe and thus a lib called test.lib is created
app.exe is linked with this lib to statically load test.exe when it starts.

When I'm running test.exe stand-alone it runs just fine but when I'm running it loaded from within app.exe it crashes.
Stepping into the code with the debugger revealed that the crash is in the call to the virtual method. It turns out that the vftable somehow goes bad.

After some investigations it turns out that when the code inside the constructor of MyClass is running , the vftable is one thing but when the call to new returns it is replace with something else called a "local vftable". I found this obscure discussion about why this is.

After about a day of debugging it occurred to me that the pointers in this "local vftable" are the same in both cases, when test.exe is stand alone and whenit is loaded as a module. This can't be right because test.exe is loaded into a different address...
To test this theory I changed the loading address in the linker options to the one where test.exe is loaded when it is in app.exe and now, lo and behold, everything works.

Obviously, this is not a permanent solution because next time this randomly selected address may be occupied and the same problem will occur again.

So my question: Why is this "local vftable" tied to the static loading address of the exe? is loading an exe as a module a bad thing? why does the exe assume it is loaded to its static address?

Just for context: this is all done with MSVC 2008, Windows XP x64.

解决方案

The workaround I ended up using is to simply add a compile configuration and compile the exe as a real dll instead of forcing it to act like one.

using /fixed:no didn't solve the problem for some reason.

Another difference I between exes and DLLs is that the entry point is different. a DLL's entry point is DllMain where as an exe has its entry point in the CRT which eventually calls main() or WinMain().

这篇关于将EXE作为DLL加载,本地vftable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆