天天看点

延迟加载库的应用: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;
}