WEB开发网
开发学院软件开发VC 合并 DLL 阅读

合并 DLL

 2006-07-20 11:39:58 来源:WEB开发网   
核心提示:本文示例源代码或素材下载 前言你可能不希望在发布程序时附带上一个外部的 DLL,因为可能会有些用户在无意中把 DLL 删除了而造成 EXE 不能正确运行,合并 DLL,也有可能该 DLL 会被别人拿去使用,也有可能,它将手动地用 DLL_PROCESS_ATTACH 参数调用 DLL 的入口函数 DllMain

本文示例源代码或素材下载

前言

你可能不希望在发布程序时附带上一个外部的 DLL,因为可能会有些用户在无意中把 DLL 删除了而造成 EXE 不能正确运行,也有可能该 DLL 会被别人拿去使用,也有可能,此 DLL 会成为破解者破解你的程序的突破口。无论出于何种原因,如果你想把一个 DLL 合并到一个 EXE 中的话,本文向你介绍这种方法。

Win32 程序调用 DLL 的机制

Win32 EXE 在调用一个外部 DLL 中的函数时,首先要调用 LoadLibary 函数来载入此 DLL 到程序的进程地址空间。 如果 LoadLibary 载入此 DLL 成功,将返回一个该 DLL 的句柄。 这个句柄实际上就是该 DLL 在内存中的起始地址。 在载入 DLL 成功后,还必须调用 GetProcAddress 函数来获取要调用的函数的地址。然后再根据该地址来调用这个函数。

根据上述原理,我们可以把一个 DLL 作为资源文件放到 EXE 文件中,在程序运行时,分配一块内存,然后将此资源复制到该分配的内存中,并根据该内存地址计算得到相关的导出函数地址,然后,当我们需要调用某一函数时,可以用该函数在内存中的地址来调用它。

程序实现。

首先,把要合并的 DLL 作为资源加入到项目的资源文件中,然后在程序运行时,从资源中载入该资源,以得到该 DLL 在内存中的位置:

LPVOID sRawDll; // 资源文件在内存中的地址
HRSRC hRes;
HMODULE hLibrary;
HGLOBAL hResourceLoaded;
char lib_name[MAX_PATH];
GetModuleFileName(hInstance, lib_name, MAX_PATH ); // 得到运行程序的名字
hLibrary = LoadLibrary(lib_name);         // 就象载入一个 DLL 一样载入运行程序到内存中
if (NULL != hLibrary)
{
  // 得到指定的资源文件在内存中的位置
  hRes = FindResource(hLibrary, MAKEINTRESOURCE(IDR_DATA1), RT_RCDATA);
  if (NULL != hRes)
  {
    // 将资源文件载入内存
    hResourceLoaded = LoadResource(hLibrary, hRes);
    if (NULL != hResourceLoaded) 
    {
      // 得到资源文件大小
      SizeofResource(hLibrary, hRes);
      // 锁定资源以得到它在内存中的地址
      sRawDll = (LPVOID)LockResource(hResourceLoaded);
    }
  }
  else return 1;
  FreeLibrary(hLibrary);
}
else return 1;

然后,从资源中载入 DLL 到内存函数 LoadPbDllFromMemory 将载入 DLL 到内存中, 该函数有两个参数,第一个参数是指向 DLL 资源在内存中的地址的指针,也就是前面代码中的 LockResource 函数的返回值。第二个参数是一个空的指针,如果函数 LoadPbDllFromMemory 运行成功,该指针将指向重新组合后的内存中的 DLL 的起始地址。该函数还有一个功能就是如果运行成功,它将手动地用 DLL_PROCESS_ATTACH 参数调用 DLL 的入口函数 DllMain 来初始化该 DLL。除此之外,它还会手动地载入合并的 DLL 的入口表中导入的 DLL 并调整它们在内存中的相对地址。以下是该函数代码:

1 2 3 4  下一页

Tags:合并 DLL

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接