首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windows API SysWOW重定向意外行为

Windows API SysWOW重定向意外行为
EN

Stack Overflow用户
提问于 2018-01-12 10:23:54
回答 1查看 373关注 0票数 2

我有一个旧的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控制台应用程序来测试这一点。完整的代码是:

代码语言:javascript
复制
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中,那么我的测试显示重定向按预期工作:

代码语言:javascript
复制
>testSysFile msvcr100.dll
C:\WINDOWS\system32\msvcr100.dll   --found
C:\WINDOWS\SysWOW64\msvcr100.dll   --found

如果MSVCR100.DLL既不在System32中,也不在SysWOW64中,则结果是预期的:

代码语言:javascript
复制
>testSysFile msvcr100.dll
C:\WINDOWS\system32\msvcr100.dll   --NOT found
C:\WINDOWS\SysWOW64\msvcr100.dll   --NOT found

如果MSVCR100.DLL在System32中,但不在SysWOW64中,那么结果会显示一些意想不到的、没有帮助的东西:

代码语言:javascript
复制
>testSysFile msvcr100.dll
C:\WINDOWS\system32\msvcr100.dll   --found
C:\WINDOWS\SysWOW64\msvcr100.dll   --NOT found

网络搜索向我展示了许多关于SysWOW重定向的信息,但我找不到任何关于此行为的文档或讨论。这真的是我应该期待的吗?我的测试还表明,如果我使用API函数GetSystemWow64Directory,我可以有一个不依赖于重定向的文件路径。只复制DLL并在该路径上注册它们是否安全?

EN

回答 1

Stack Overflow用户

发布于 2018-01-12 13:31:13

GetFileVersionInfo*使用LoadLibraryEx将文件加载为数据文件来完成其工作。

由于某些原因,LoadLibraryW中的KERNELBASE!BasepLoadLibraryAsDataFile调用ntdll!RtlWow64EnableFsRedirectionEx来禁用重定向,如果请求的文件在"%WinDir%\ system32“中,它会再次尝试加载该文件,这次是从”真正的“system32目录。

这显然是设计出来的,我想不出一种不是一个巨大的黑客攻击的方法。我假设他们这样做是出于兼容性的原因。

但是,您可以使用以下内容来检测它:

代码语言:javascript
复制
bool validFile = !(GetFileAttributes(filePath) & FILE_ATTRIBUTE_DIRECTORY);
bool falsePositive = gotversioninfo && !validFile;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48218694

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档