关于文件系统重定位导致的调用命令行失败

1. 问题现象

  1. 环境
    Windows 10专业版,64位操作系统,基于x64的处理器。
  2. 在命令行窗口中查询当前用户,正常显示。
    在这里插入图片描述
  3. 在32Bit应用调用相应的命令行
    Python代码:
    cmd = r"cmd /c query user"
    os.system(cmd)
    
    结果:
    在这里插入图片描述

2. 分析问题

  1. 定位query模块
    通过everything来搜索query,结果如下图:
    在这里插入图片描述
  2. 区分
    System32目录中存放的是32Bit版本,后面存放的是64Bit版本吗?不是这样的。

3. Windows系统简介

Windows是一个多子系统的操作系统,Win32也是其子系统之一。在这里插入图片描述
那么Windows 64位操作系统是如何兼容32位应用程序的呢?

  • x64的处理有两套指令,分别支持32操作和64位操作。
  • 32位代码编译时,自动转换成相应的32位操作指令;64位代码则转成64位操作指令。
  • Windows 64位系统下有64位系统目录,存放64位应用程序所需要的相关库文件,为了保持操作系统默认向前兼容,64位系统默认的系统路径和32位操作系统一样,均为:C:\Windows\System32。
  • Windows 64位系统中,新增加了C:\Windows\SysWOW64目录,存放32位子系统,也被称为WoW64(Windows-on-Windows 64-bit)子系统的相关库文件。

4. Windows 64位系统调用32位应用程序

应用程序运行时,系统会检测PE文件头,了解这个应用程序是32位还是64位,然后将相应的32位系统库文件加载到exe进程中。Windows32位程序,针对不同硬件架构(ARM、x86),有部分涉及硬件的库有差别,所以有部分库文件存放在C:\Windows\WinSxS中的amd64xxx和wow64xxx两个类目录中。

  • 32位应用程序,在32位操作系统中,默认是加载C:\Windows\System32下的相关库文件。
  • 32位应用程序,在64位操作系统中,默认依然是去加载C:\Windows\System32下的相关库文件。但是64位系统中,C:\Windows\System32目录下存放的是64位库文件,不相匹配。Windows 64位操作系统为了解决了这个问题,在文件系统驱动层,增加一个文件重定位的功能。即32位程序在64位系统下,访问C:\Windows\System32目录,会被重定位到C:\Windows\SysWOW64目录。
  • Python 32位程序,调用默认的系统模块时,代码层面会去打开即会去C:\Windows\System32打开相应的模块,但是因为文件系统定位的关系,其实际是打开的C:\Windows\SysWOW64目录中的模块。
  • 像32位的query.exe不在此目录,而是在C:\Windows\WinSxS中的amd64xxx和wow64xxx目录中。此时怎么办呢?Windwos操作系统提供了一个虚拟的路径C:\Windows\Sysnative(并没有这个真实路径),操作系统针对32位的进程访问此路径时,会进行一个重定位操作。默认是重定位到C:\Windows\SysWOW64目录中。但是针对一些因为内核架构不同的模块,如query,会定位到C:\Windows\WinSxS中的amd64xxx或wow64xxx目录中。

5. 解决方案

  1. 直接指定模块的路径
    在这里插入图片描述

  2. 指定cmd的路径
    指定cmd路径之后,CMD会自动地根据内核框架去找相应的模块
    在这里插入图片描述

  3. 使用64位程序
    在这里插入图片描述

6. 注意

  1. 64位系统不能使用sysnative虚拟目录。
  2. C++等其他语言在Windows上开发的程序均符合此规则。
  3. 受影响的模块很多,主要有 change.exe、chglogon.exe、chgport.exe、chgusr.exe、logoff.exe、qappsrv.exe、qprocess.exe、query.exe、reset.exe、rwinsta.exe、tscon.exe、tsdiscon.exe、tskill.exe等。

7. 引用

  1. File System Redirector
  2. The ‘Sysnative’ folder in 64-bit Windows explained
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值