当前位置:  开发笔记 > 编程语言 > 正文

如何重命名DLL但仍然允许EXE找到它?

如何解决《如何重命名DLL但仍然允许EXE找到它?》经验,为你挑选了4个好方法。

我们有一个内部生成的DLL,我们有相关的存根LIB.

我们还有一个EXE,它使用这个DLL使用静态链接到DLL的LIB文件的简单方法(即,不是手动使用LoadLibrary).

当我们部署EXE时,我们希望为了混淆原因(根据客户的要求)更改DLL文件名.

我们怎么能这样做,以便我们的EXE仍然自动找到DLL?

我已经尝试重命名DLL和LIB文件(在它们构建为正常名称后),然后将EXE项目设置更改为与重命名的LIB链接.这在运行时失败,因为我猜DLL的名称被烘焙到LIB文件中,而不是简单地通过链接器猜测".lib"替换为".dll".

一般情况下,我们不希望将此混淆应用于DLL的所有用途,因此我们希望保留当前DLL项目输出文件.

我希望有一种方法可以编辑DLL的LIB文件,并用其他东西替换DLL文件的硬编码名称.在这种情况下,这可以完全在EXE项目中完成(可能作为预构建步骤).


更新:我发现延迟加载不起作用,因为我的DLL包含导出的C++类.看到这篇文章.

还有其他选择吗?



1> QAZ..:

这是一个很好的替代方法:延迟加载.

构建应用程序时,将其全部链接到原始DLL名称(但将原始dll设置为延迟加载).

然后,根据客户请求部署重命名的DLL.

您的EXE将尝试使用原始名称而不是重命名的版本来查找DLL,因此会失败,但是如果加载延迟,您可以拦截此失败并自行加载重命名的版本,然后使本机Windows加载程序解析所有内容,就像没有任何更改一样.

阅读文章Linker Support for Delay-Loaded DLLs,并查看Delay Hook示例.

您的延迟挂钩可能如下所示:

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;
}


如果它对其他人有帮助,上述方法的[本例](http://otb.manusoft.com/2013/01/using-delayload-to-specify-dependent-dll-path.htm)将在我很容易理解的方式.

2> wimh support..:

使用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文件相同的输出.



3> 小智..:

你的顾客喝醉了吗?世界上所有疯狂的要求......

回到我的辉煌岁月作为一个梅毒疯子午夜C++程序员我曾经把我的DLL添加到我的.exe文件作为资源.然后在启动时我将解压缩并将它们写入exe的目录.此程序可以决定DLL文件名.真的去找混淆的东西 - 从一个随机数字开始,连接一些爱德华李尔诗歌,并将它与你最喜欢的德国双管名词联系起来; 无论如何应该为初学者做.然后使用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);
    }
  }
}



4> Chris Berry..:

我创建了一个小的python脚本来正确地重命名本机dll.它会生成一个新的lib文件,供您在MSVC中的项目链接中使用.

https://github.com/cmberryau/rename_dll/blob/master/rename_dll.py.

您当然需要使用开发人员命令提示符才能使用它.

推荐阅读
手机用户2502852037
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有