Win32 / Dll:调用DLL函数时跳转到的地址?

时间:2012-05-03 08:28:52

标签: windows winapi dll assembly x86

当执行“调用”指令以调用DLL导出函数时,它将EIP设置为DLL中存储的函数的地址。如果另一个同时执行的程序调用属于同一个DLL的同一个函数,那么跳转地址是否相同?

2 个答案:

答案 0 :(得分: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,过去几年发生了一些变化,请看this post

如果您必须在使用相同DLL的进程之间共享数据,最好使用一些共享内存,请查看this article on MSDN作为示例。

答案 1 :(得分:1)

由于其他程序/进程被映射到它们自己的独立地址空间,我怀疑地址是否相同。