windows - Win32/DLL : The address that is jumped to when a DLL function is called?

标签 windows winapi dll assembly x86

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

最佳答案

简短的回答是这取决于

DLL 按部分组织,每个部分可以由许多进程共享。通常只有共享代码段(当 DLL 在同一基地址加载时),并且每个进程都有其私有(private)数据段

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举个例子。

关于windows - Win32/DLL : The address that is jumped to when a DLL function is called?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10427717/

相关文章:

c++ - Visual C++ 上 NOMINMAX 的可能问题

c++ - 使用 log4cplus 运行代码时出现 bad_alloc 错误

c# - 标题栏与菜单合并 - WINFORMS

dll - 控件 controlName 的类 MSComctlLib.[ListView|TextBox|ect] 不是加载的控件类

windows - Windows 服务项目中的 AppData\Roaming 文件夹

windows - 在 Windows 中使用 cygwin Perl.exe 运行 genhtml

c++ - 在远程进程中隐藏控制台窗口

c++ - TCP IOCP 在 acceptex 之后收不到

DLL 自行卸载

c++ - 程序将无法在 Visual Studio 之外正常运行