天天看點

延遲加載庫的應用:Dll嵌入可執行檔案中

    搜尋到一篇英文文章:​​Packing Dlls into your exe​​ 文章大意是把dll檔案嵌入到可執行檔案的資源表中,用延遲加載方式編譯連結可執行檔案。由于所依賴的dll在正式調用時才被加載,是以能順利的通過連結階段。Exe正式運作時,先搜尋檔案資源表,獲得嵌入到資源區中dll并儲存到磁盤,然後調用。調用完解除安裝和删除該Dll。我也順着這個思路做了一遍,記錄于此。

    要嵌入dll,首先要生成一個測試用的dll,導出接口如下:

延遲加載庫的應用:Dll嵌入可執行檔案中

    然後生成調用該Dll的工程,因為用到延遲加載方式,是以,工程屬性要做一些設定:

延遲加載庫的應用:Dll嵌入可執行檔案中

編譯通過了,但是運作會出錯,因為工程目錄下并沒有resourceDll.dll這個檔案,同時,代碼中也并沒有顯示的處理加載失敗時的異常。

    接下來是嵌入Dll到資源節中,其實吧,嵌入一個dll然後加載運作有點屈才了。完全可以嵌入一個sys檔案然後調用LoadDriver。

    在工程檔案中:添加資源-導入-所有類型檔案-選擇資源檔案->命名資源類型

延遲加載庫的應用:Dll嵌入可執行檔案中

最後是搜尋資源并寫入到磁盤:

#include "stdafx.h"
#include "resourceDll.h"
#include "resource.h"
#include <windows.h>
#include <winuser.h>

int _tmain(int argc, _TCHAR* argv[])
{
    HMODULE hThis =  GetModuleHandle(NULL);  
    HRSRC   hRes  =  FindResource(hThis, MAKEINTRESOURCE(IDR_DLL1), _T("dll"));
    HGLOBAL hGres =  LoadResource(hThis, hRes); 
 
    // 建立一個臨時的dll檔案,檔案路徑與exe運作目錄一緻。
    HANDLE  hFile = CreateFile(_T("resourceDll.dll"), GENERIC_WRITE, NULL, NULL, 
                               CREATE_NEW, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE, NULL); 
 
    // 将dll資源檔案寫入臨時建立的dll檔案中。
    PVOID   pRes  =  LockResource(hGres);
    DWORD  dwSize =  SizeofResource(NULL, hRes); 
    DWORD dwSizeWritten = 0;  
    WriteFile(hFile, pRes, dwSize, &dwSizeWritten, NULL);  
    CloseHandle(hFile); 
    
    resourceDll();
    return 0;
}