我有一个旧的32位安装程序,它将一些32位依赖项DLL安装到Windows系统文件夹中。我发现它无法在64位系统上安装一些32位DLL,因为SysWOW重定向正在做一些我不理解的事情。
安装程序依赖于Windows API函数GetFileVersionInfo来指示DLL是否已经具有较新的版本号。但是,我现在看到的情况是,文件MSVCR100.DLL已经存在于System32文件夹中,但不在SysWOW64文件夹中。当使用GetFileVersionInfo测试C:\Windows\ System32 \MSVCR100.DLL时,我希望它重定向到C:\Windows\ SysWOW64 \MSVCR100.DLL.似乎如果该文件在SysWOW64中不存在,那么它会在System32中作为备用文件。因此,安装程序认为MSVCR100.DLL已经存在,无法安装它。
我创建了一个C++ Win32控制台应用程序来测试这一点。完整的代码是:
int _tmain(int argc, _TCHAR* argv[])
{
char sysDirName[64], sysWow64DirName[64];
char fileName[256];
strcpy_s(fileName, argv[1]);
GetSystemDirectory((LPSTR)sysDirName, 256);
GetSystemWow64Directory((LPSTR)sysWow64DirName, 256);
test_file(sysDirName, fileName);
test_file(sysWow64DirName, fileName);
return 0;
}
void test_file(char *dir, char* fileName)
{
char filePath[256];
DWORD verInfoSize, tempDWORD;
BOOL found;
byte buff[8192];
PathCombine((LPSTR)filePath, (LPSTR)dir, (LPSTR)fileName);
verInfoSize = GetFileVersionInfoSize((LPSTR)filePath, &tempDWORD);
found = GetFileVersionInfo((LPSTR)filePath, 0, verInfoSize, buff);
if (found)
printf("%s --found\n", filePath);
else
printf("%s --NOT found\n", filePath);
}我在3台不同的64位计算机上测试了它,包括Win 10和Win 7,我得到了相同的结果。
如果MSVCR100.DLL在SysWOW64中,但不在System32中,那么我的测试显示重定向按预期工作:
>testSysFile msvcr100.dll
C:\WINDOWS\system32\msvcr100.dll --found
C:\WINDOWS\SysWOW64\msvcr100.dll --found如果MSVCR100.DLL既不在System32中,也不在SysWOW64中,则结果是预期的:
>testSysFile msvcr100.dll
C:\WINDOWS\system32\msvcr100.dll --NOT found
C:\WINDOWS\SysWOW64\msvcr100.dll --NOT found如果MSVCR100.DLL在System32中,但不在SysWOW64中,那么结果会显示一些意想不到的、没有帮助的东西:
>testSysFile msvcr100.dll
C:\WINDOWS\system32\msvcr100.dll --found
C:\WINDOWS\SysWOW64\msvcr100.dll --NOT found网络搜索向我展示了许多关于SysWOW重定向的信息,但我找不到任何关于此行为的文档或讨论。这真的是我应该期待的吗?我的测试还表明,如果我使用API函数GetSystemWow64Directory,我可以有一个不依赖于重定向的文件路径。只复制DLL并在该路径上注册它们是否安全?
发布于 2018-01-12 13:31:13
GetFileVersionInfo*使用LoadLibraryEx将文件加载为数据文件来完成其工作。
由于某些原因,LoadLibraryW中的KERNELBASE!BasepLoadLibraryAsDataFile调用ntdll!RtlWow64EnableFsRedirectionEx来禁用重定向,如果请求的文件在"%WinDir%\ system32“中,它会再次尝试加载该文件,这次是从”真正的“system32目录。
这显然是设计出来的,我想不出一种不是一个巨大的黑客攻击的方法。我假设他们这样做是出于兼容性的原因。
但是,您可以使用以下内容来检测它:
bool validFile = !(GetFileAttributes(filePath) & FILE_ATTRIBUTE_DIRECTORY);
bool falsePositive = gotversioninfo && !validFile;https://stackoverflow.com/questions/48218694
复制相似问题