代码之家  ›  专栏  ›  技术社区  ›  pauldoo

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

  •  19
  • pauldoo  · 技术社区  · 16 年前

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

    当我们部署EXE时,我们希望由于混淆原因(应客户要求)更改DLL文件名。

    我们如何才能做到这一点,使我们的EXE仍然自动找到DLL?

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

    一般来说,我们不想将此混淆应用于DLL的所有用途,所以我们希望保留当前的DLL项目输出文件。

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


    更新 我发现Delay Loading不起作用,因为我的DLL包含导出的C++类。 见 this article

    有其他选择吗?

    6 回复  |  直到 16 年前
        1
  •  18
  •   vladr    5 年前

    下面是一个不错的替代方法: 延迟加载 .

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

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

    读这篇文章 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;
    }
    
        2
  •  16
  •   wimh    16 年前

    使用LIB工具(包括在visual studio中)可以从def文件生成LIB文件。测量dll源不包括def文件,必须先创建一个。你可以用垃圾箱来帮助你。例如: 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 将lib文件泛化。

    现在您可以轻松地修改def文件,并在每次重命名dll时生成一个新的libfile。

    可以使用dumpbin验证libfile: dumpbin /exports ws2_32.lib . 您应该得到与原始lib文件相同的输出。

        3
  •  7
  •   Philip Morant Philip Morant    16 年前

    你的顾客喝醉了吗?世界上所有疯狂的需求中。。。

    回到我的荣耀时代,作为一个梅毒疯子,午夜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
  •  5
  •   Chris Berry    7 年前

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

    当然,您需要使用developer命令提示符才能正常工作。

        5
  •  0
  •   Ignacio Correia    12 年前
    1. 您可以将您的visual studio项目重命名为通用名称(您的客户对此没有异议)。
    2. 需要重命名DLL本身。但是lib仍然有老名字?是否使用DUMPBIN/ALL*.lib>文件交叉验证。旧DLL名称的grep。它还在吗? 检查项目中的*.def文件。你把图书馆改名为“OLDNAME”了吗

    否则,库没有理由携带旧的DLL名称。

        6
  •  -1
  •   Mladen Prajdic    16 年前

    或者使用插件使用的相同方法。在程序集中有一个类实现一个接口,您可以在某个目录中的每个程序集中从应用程序中搜索该接口。如果找到了就把它扔了。当然,您不必混淆接口名称。