当执行“调用”指令来调用 DLL 导出函数时,它会将 EIP 设置为存储在 DLL 中的函数的地址。如果同时执行的另一个程序,调用属于同一个DLL的同一个函数,跳转地址是否相同?
问问题
183 次
2 回答
4
简短的回答是视情况而定。
DLL 是按部分组织的,每个部分可以由许多进程共享。通常只有共享代码段(当 DLL 在相同的基地址加载时)并且每个进程都有其私有数据段。
DLL 的优点之一是您可以在许多进程之间共享它们的代码(然后您可以节省系统内存,因为系统不会加载它们的许多实例)。当然,数据不能(通常)共享,因此必须为每个实例复制数据。
这意味着通常DLL 代码的内存在不同的进程之间共享,那么它可能具有相同的地址。我说“可能”是因为Virtual Address Space,即使内存是共享的,也不能保证它在每个进程上都具有相同的地址。为了快速测试使用GetProcAddress
并多次运行该过程以比较函数地址,您可以使用MSDN中的这个简单程序:
#include <windows.h>
#include <iostream>
void _tmain()
{
typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
SYSTEM_INFO si;
ZeroMemory(&si, sizeof(SYSTEM_INFO));
PGNSI fnGetNativeSystemInfo = reinterpret_cast<PGNSI>(GetProcAddress(
GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"));
std::cout << fnGetNativeSystemInfo << std::endl;
}
您应该(通常)看到每个导出函数的相同地址,但您可能看不到。依赖这种行为从来都不是一个好主意。好的,这就是故事,但由于 ASLR,过去几年发生了一些变化,也请看一下这篇文章。
如果您必须使用相同的 DLL 在进程之间共享数据,则最好使用一些共享内存,请查看MSDN 上的这篇文章作为示例。
于 2012-05-03T08:36:57.293 回答
1
由于其他程序/进程被映射到它们自己单独的地址空间,我怀疑地址是否相同。
于 2012-05-03T08:34:41.647 回答