如何重命名一个DLL,但仍然允许EXEfind它?

我们有一个在内部生成的DLL,并且我们有关联的静态LIB的存根。

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

当我们部署EXE的时候,我们希望DLL文件的名字因混淆原因而改变(根据客户的要求)。

我们如何做到这一点,使我们的EXE仍然自动findDLL?

我试图重命名DLL和LIB文件(在它们被构build为正常名称之后),然后将EXE项目设置更改为与重命名的LIB链接。 这在运行时失败,因为我猜DLL的名字被烘焙到了LIB文件中,而不是简单地被链接器用“.dll”replace“.lib”来猜测。

一般来说,我们不希望将这个混淆应用到DLL的所有用途,所以我们希望保持当前的DLL项目输出文件是它们。

我希望有一种方法可以编辑DLL的LIB文件,并用别的东西replaceDLL文件的硬编码名称。 在这种情况下,这可以完全在EXE项目中完成(也许作为预先构build步骤)。


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

有没有其他的select?

Solutions Collecting From Web of "如何重命名一个DLL,但仍然允许EXEfind它?"

使用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生成lib文件。

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

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

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

当建立你的应用程序,链接所有的原始DLL名称(但设置原始dll被延迟加载)。

然后,您可以根据您的客户请求部署已重命名的DLL。

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

阅读文章链接器支持延迟加载的DLL,并看到延迟钩子的例子 。

你的延迟钩子可能如下所示:

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

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

回到我辉煌的日子,作为梅毒狂人午夜C ++程序员,我用我的DLL作为资源添加到我的.exe文件。 然后在启动时我将它们解压缩并将它们写入到exe目录中。 您的程序可以决定此时的DLL文件名。 真的去混淆的事情 – 从一个随机数开始,连接一些爱德华李尔诗歌和XOR它与您最喜爱的德国双筒名词; 无论如何应该为首发做。 然后使用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); } } } 
  1. 使用LoadLibrary(从注册表中读取新名称)是一个选项。
  2. 您可以重命名您的视觉工作室项目有一个广义的名称(您的客户没有异议)。
  3. DLL本身需要重命名。 但是lib仍然带有旧的名字? 你有使用DUMPBIN / ALL * .lib>文件进行交叉验证吗? grep为旧的DLL名称。 它还在吗? 检查项目中的* .def文件。 你有没有重新命名图书馆“OLDNAME”

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

您将不得不使用Assembly.Load,并将模糊程序集名称保存在app.config中。

或者使用插件使用的相同方法。 在你的程序集中有一个类实现一个接口,你可以在你的应用程序中搜索某个目录中的每个程序集。 如果发现憎恶它。 你当然不得不混淆接口名称。