• 64位系统下System32文件系统重定向


    前言

          因为一次偶然的机会,需要访问系统目录“C:/Windows/System32“文件夹下的内容,使用的测试机器上预装了win7 64系统。在程序运行中竟然发生了该文件路径不存在的问题!!通过查看网上相关的资料,了解到64位系统下,System32(同时也包括Program Files)这两个文件夹被动态地重定向了。为了可以直观的反映这个问题,这里将编写一个小的测试程序进行验证。

    实例验证

          首先随机选择一个文件,并将其拷贝到系统目录的System32文件夹下。本文选择QQ启动程序进行验证(主要是QQ自带企鹅图标易于辨认,哈哈),如图1所示

    QQ拷贝到System32下

    图1 手动将QQ拷贝到系统System32文件夹下

        编写实际测试程序,直接上代码(调用了windows系统API PathFileExists来判断文件是否存在)

    复制代码
    /************************************************************************/
    /* file   : 验证在64位机器上system32以及Program Files的exe不能用API直接找到
     * author : Huagang Li
     * date   : 2014-8-23 01:22:55
     * tips   : 64位系统下system32 文件夹重定向机制
     *
     */
    /************************************************************************/
    #include <Windows.h>
    #include <string>
    #include <tchar.h>
    #include <Shlwapi.h>
    
    #pragma comment(lib,"Shlwapi.lib")  // PathFileExists链接时需要
    
    int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
    {
        std::wstring strFile = L"C:\Windows\System32\QQProtect.exe";
    
        if (::PathFileExists(strFile.c_str()))
        {
            ::MessageBox(NULL, _T("文件存在"), _T("Good"), MB_OK);
        }
        else
        {
            ::MessageBox(NULL, _T("文件不存在"), _T("Opps"), MB_OK);
        }
    
        return EXIT_SUCCESS;
    }
    复制代码

          运行的结果如图2所示:

    Opps

    图2 文件不存在??

          从上面的结果可以看出,在调用windows API检测QQ文件是否存在时,系统给出了一个令人匪夷所思的结论:文件不存在!!但这个文件确实被拷贝进了该目录下啊。要解释这个奇怪的现象,就得从windows 64位系统中的文件系统重定向说起。当微软开发了64位系统时,为了做到向前兼容,需要重新实现32为系统中需要的相关文件(system32文件夹下的dll以及exe)。然而,这些新的实现版本是基于64位系统开发的,因此如果继续存放于System32文件夹下,显得名不副实。可是为了做到向前兼容,又需要将这些依赖文件存放于这个目录下,为了解决上述冲突,微软采用了一种文件系统重定向机制:在64位系统下,System32文件夹下的文件实际重定向到SysNative这个文件夹(注意,这个文件夹不能直接找到)。这样,就可以将64位系统下64位的库和应用程序存放于System32文件夹下(因为已经重定向到SysNative了),而32位的库和应用程序则被存放在另一个叫做SysWOW64的文件夹中。具体的对应关系为:

    WindowsSysWOW64  文件夹下存放32位的库和应用程序 (WOW64 == Windows on Windows 64 bit )

    WindowsSystem32  文件夹下存放64位的库和应用程序

          为了验证文件系统重定向,将前文中的测试路径改为:

    std::wstring strFile = L"C:\Windows\SysNative\QQProtect.exe";

         测试结果如图3所示:

    Good

    图3 改为Sysnative结果

          上述结果显示了,64位系统下如果需要访问System32目录下的文件,一个可行的方法是将访问路径改为SysNative。但是由于sysnative文件夹不能通过windows资源管理器访问到(如图4所示),因此对于一般人来讲,这样的改名其实很困惑。

    sysnative不存在

    图4 资源管理器访问不到Sysnative文件夹

          既然微软开发了文件系统重定向机制机制,那就可以通过一定的方式操作这种机制。通过查看msdn可以发现,http://msdn.microsoft.com/en-us/library/aa365743.aspx 提供的方式可以禁用文件系统重定向问题。因此,本文尝试调用这个API接口进行验证:

    复制代码
    /************************************************************************/
    /* file   : 验证在64位机器上system32以及Program Files的exe不能用API直接找到
     * author : Huagang Li
     * date   : 2014-8-23 01:22:55
     * tips   : 64位系统下system32 文件夹重定向机制
     *
     */
    /************************************************************************/
    #include <Windows.h>
    #include <string>
    #include <tchar.h>
    #include <Shlwapi.h>
    
    #pragma comment(lib,"Shlwapi.lib")  // PathFileExists链接时需要
    
    int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
    {
        std::wstring strFile = L"C:\Windows\System32\QQProtect.exe";
        // 64位系统下 system32 文件系统重定向
    
        PVOID OldValue = NULL;
        Wow64DisableWow64FsRedirection(&OldValue);
        if (::PathFileExists(strFile.c_str()))
        {
            ::MessageBox(NULL, _T("文件存在"), _T("Good"), MB_OK);
        }
        else
        {
            ::MessageBox(NULL, _T("文件不存在"), _T("Opps"), MB_OK);
        }
        Wow64RevertWow64FsRedirection(OldValue);
    
        return EXIT_SUCCESS;
    }
    复制代码

    运行后得到的结果和上文中Sysnative一样,如图5所示:

    Good

    图5 禁用文件系统重定向机制后的结果

          注意,由于禁用文件系统重定向后可能引起其他一些问题(例如原本依赖于System32下的dll文件加载失败),因此在禁用并完成需要的操作后,要回复原来的禁用状态(如程序中Wow64RevertWow64FsRedirection(OldValue);)。这样,在调用PathFileExists后,恢复了文件系统重定向机制,不会影响后续操作。

         另外,64位系统下Program Files与Program Files(x86)的关系就与上面的System32和S也是WOW64一致,也存在文件系统重定向。

     

    结论

          1. 64位系统下存在文件系统重定向机制(File System Redirector)

          2. System32文件夹动态被定向到SysNative文件夹

          3. 可以通过windows API Wow64DisableWow64FsRedirection禁用这种定向机制

    参考链接

    [1] http://msdn.microsoft.com/en-us/library/aa384187.aspx

    [2] http://msdn.microsoft.com/en-us/library/aa365743.aspx

    [3] http://blog.sina.com.cn/s/blog_792da39c01013bzh.html

    转载自:https://www.cnblogs.com/lhglihuagang/p/3930874.html

  • 相关阅读:
    MySQL实战 | 01-当执行一条 select 语句时,MySQL 到底做了啥?
    人人都能看懂的云计算知识科普
    教你用 Python 实现抖音热门表白软件
    Docker中“TERM environment variable not set.”问题
    centos 6.5安装docker
    centos6安装docker,先升级系统内核
    MySQL中一个sql语句包含in优化问题
    阿里云提示ECS服务器存在漏洞处理方法
    yum安装 指定安装目录
    nginx重启报错:nginx: [error] invalid PID number "" in "/run/nginx.pid"
  • 原文地址:https://www.cnblogs.com/csstudy/p/13662292.html
Copyright © 2020-2023  润新知