2012-05-03 37 views
2

当执行“呼叫”指令调用的DLL导出函数,它设置EIP存储在DLL中的函数的地址。如果另一个同时执行的程序调用属于同一个DLL的同一个函数,跳转地址是否相同?Win32/Dll:调用DLL函数时跳转到的地址?

+0

它为什么重要?你想解决什么问题? –

+0

为什么问这个?这些知识如何使您受益?在虚拟地址空间中,答案是“也许,但你不应该依靠它”。 – tenfour

+0

因为我想知道一个DLL的实例是属于进程还是其他东西。如果一个DLL被许多程序同时使用,是否意味着这个DLL会有很多实例? – user1091856

回答

1

作为其它(多个)程序/进程被映射到自己的单独的地址空间,我怀疑的地址将是相同的。

4

简短的回答是这取决于

动态链接库按部分组织,每个部分可以通过许多进程共享。通常只为共用唯一代码段(当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的例子。