2012-05-03 38 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的例子。