我们有一个内部生成的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++类.看到这篇文章.
还有其他选择吗?
这是一个很好的替代方法:延迟加载.
构建应用程序时,将其全部链接到原始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; }
使用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文件相同的输出.
你的顾客喝醉了吗?世界上所有疯狂的要求......
回到我的辉煌岁月作为一个梅毒疯子午夜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); } } }
我创建了一个小的python脚本来正确地重命名本机dll.它会生成一个新的lib文件,供您在MSVC中的项目链接中使用.
https://github.com/cmberryau/rename_dll/blob/master/rename_dll.py.
您当然需要使用开发人员命令提示符才能使用它.