2008-11-11 31 views
19

我們有一個在內部生成的DLL,並且我們有關聯的靜態LIB的存根。如何重命名DLL但仍允許EXE找到它?

我們也有一個EXE,它使用這個DLL使用靜態鏈接到DLL的LIB文件(即,不是手動使用LoadLibrary)的簡單方法。

當我們部署EXE時,我們希望將DLL文件名稱更改爲混淆原因(根據客戶要求)。

我們如何做到這一點,以便我們的EXE能夠自動找到DLL?

我試圖重命名DLL和LIB文件(在它們被構建爲它們的正常名稱之後),然後將EXE項目設置更改爲與重命名的LIB鏈接。這在運行時失敗了,因爲我猜這個DLL的名字被燒入了LIB文件,而不是簡單地被鏈接器用「.dll」替換「.lib」來猜測。

一般來說,我們不希望將這個混淆應用到DLL的所有用途,所以我們想保留當前的DLL項目輸出文件。

我希望能有一種方法,我們可以編輯DLL的LIB文件,並用別的東西替換DLL文件的硬編碼名稱。在這種情況下,這可以完全在EXE項目中完成(可能作爲預構建步驟)。


更新:我發現延遲加載不工作,因爲我的DLL包含導出的C++類。 見this article

有沒有其他的選擇?

回答

-1

您必須使用Assembly.Load並將模糊程序集名稱保存在app.config中。

要麼使用插件使用相同的方法。在你的程序集中有一個類實現一個接口,你可以在你的應用程序中搜索某個目錄中的每個程序集。如果發現它討厭。你當然不得不混淆接口名稱。

+0

正如標籤所示,這是針對本地項目的,因此程序集不適用。 – 2008-11-11 10:26:56

+0

哦對...我的壞。 – 2008-11-11 11:09:51

14

使用LIB工具(包含在Visual Studio中),您可以從def文件生成一個lib文件。假設你的dll源文件不包含def文件,你必須先創建一個。你可以使用dumpbin來幫助你。例如:dumpbin /exports ws2_32.dll

在輸出中,您會看到導出函數的名稱。現在創建一個這樣的DEF文件:

LIBRARY WS2_32 
EXPORTS 
    accept  @1 
    bind  @2 
    closesocket @3 
    connect  @4 

的@number是在DUMPBIN輸出

使用LIB /MACHINE:x86 /def:ws2_32.def序到generete的lib文件。

現在您可以輕鬆修改def文件,並且每次重命名dll時生成一個新的libfile。

您可以使用dumpbin驗證libfile:dumpbin /exports ws2_32.lib。你應該得到與原始lib文件相同的輸出。

+0

這似乎是由Microsoft自己在這裏記錄: http://support.microsoft.com/kb/131313 – pauldoo 2008-11-11 14:06:54

15

這是一個很好的替代方法:延遲加載

在構建應用程序時,將它與原始DLL名稱一樣鏈接(但將原始dll設置爲延遲加載)。

然後,您將根據您的客戶請求部署重命名的DLL。

您的EXE將嘗試使用原始名稱而不是重命名的版本來查找DLL,因此會失敗,但是如果延遲加載,您可以截獲該失敗並自己加載重命名的版本,然後讓本地Windows加載程序將所有內容解析爲如果沒有改變。

閱讀文章Linker Support for Delay-Loaded DLLs並查看Delay Hook example

你延遲鉤可能類似於下面:

FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo pdli) 
{ 
    switch(dliNotify) 
    { 
     case dliNotePreLoadLibrary: 
      if(strcmp(pdli->szDll, "origional.dll") == 0) 
       return (FARPROC)LoadLibrary("renamed.dll"); 
      break; 
     default: 
      return NULL; 
    } 

    return NULL; 
} 
7

是您的客戶喝醉了嗎?在全世界所有瘋狂的要求...

回到我輝煌的日子,作爲一個梅毒狂人午夜C++程序員,我用我的DLL作爲資源添加到我的.exe文件。然後在開始時我會解壓縮它們並將它們寫入到exe目錄中。您的程序可以決定此時的DLL文件名。真的去混淆的事情 - 從一個隨機數開始,連接一些愛德華李爾詩歌和XOR它與你最喜歡的德國雙管名詞;無論如何應該爲首發做。然後使用LoadLibrary()加載DLL。

enum ukOverwrite {dontOverwriteAnything = 0, overwriteWhateverPresent = 1}; 
void unpackResource (ukOverwrite param1, int resourceID, const char* basePath, 
const char* endFilename) 
{ 
    char* lpName = 0; 
    lpName += resourceID; 
    HRSRC MrResource = FindResource (0, lpName, "file"); 

    if (MrResource) 
    { 
    HGLOBAL loadedResource = LoadResource (0, MrResource); 
    if (loadedResource) 
    { 
     void* lockedResource = LockResource (loadedResource); 
     if (lockedResource) 
     { 
     DWORD size = SizeofResource (0, MrResource); 
     if (size) 
     { 
      unsigned long creationDisposition = CREATE_NEW; 
      if (param1 == overwriteWhateverPresent) 
      creationDisposition = CREATE_ALWAYS; 

      char filepath [MAX_PATH]; 
      strcpy (filepath, basePath); 
      strcat (filepath, endFilename); 
      HANDLE rabbit = CreateFile (filepath, GENERIC_WRITE, 0, 0, 
creationDisposition, 0, 0); 
      if (rabbit != INVALID_HANDLE_VALUE) 
      { 
      DWORD numBytesWritten = 0; 
      int wf = WriteFile (rabbit, lockedResource, size, &numBytesWritten, 
0); 
      CloseHandle (rabbit); 
      } 
     } 
     } 
     FreeResource (loadedResource); 
    } 
    } 
} 
0
  1. 使用調用LoadLibrary(從註冊表讀取新的名字)是一個選項。
  2. 您可以將您的visual studio項目重命名爲具有通用名稱(您的客戶沒有異議)。
  3. DLL本身需要重新命名。但是這個lib仍然帶有舊名字?你使用DUMPBIN/ALL * .lib>文件進行了交叉驗證嗎? grep爲舊的DLL名稱。它還在嗎? 檢查項目中的* .def文件。你有沒有重命名圖書館「OLDNAME」

否則,沒有理由讓LIB攜帶舊的DLL名稱。

相關問題