我们有一个内部生成的DLL,并且我们有相关的存根LIB静态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 ++类。 请参阅this article。
还有其他选择吗?
答案 0 :(得分:17)
这是一个不错的替代方法:延迟加载。
构建应用程序时,将其全部链接到原始DLL名称(但将原始dll设置为延迟加载)。
然后根据客户请求部署重命名的DLL。
您的EXE将尝试使用原始名称而不是重命名的版本来定位DLL,因此会失败,但是如果加载延迟,您可以拦截此失败并自行加载重命名的版本,然后让本机Windows加载程序解析所有内容,就像没有改变。
阅读文章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;
}
答案 1 :(得分:15)
使用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时生成新的lib文件。
您可以使用dumpbin验证libfile:dumpbin /exports ws2_32.lib
。您应该获得与原始lib文件相同的输出。
答案 2 :(得分:6)
你的顾客喝醉了吗?世界上所有疯狂的要求......
作为一名梅毒疯子午夜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);
}
}
}
答案 3 :(得分:5)
我创建了一个小的python脚本来正确地重命名本机dll。它生成一个新的lib文件供您在MSVC中的项目链接中使用。
https://github.com/cmberryau/rename_dll/blob/master/rename_dll.py
当然,您需要使用开发人员命令提示符才能正常工作。
答案 4 :(得分:0)
否则,LIB没有理由携带旧的DLL名称。
答案 5 :(得分:-1)
你必须使用Assembly.Load并在app.config中保存模糊的程序集名称。
或者使用插件使用的相同方法。在程序集中有一个类实现一个接口,您可以在某个目录中的每个程序集中从您的应用程序中搜索该接口。如果发现厌恶它。你当然不得不混淆接口名称。