搬砖过程中遇到一个很奇怪的现象。写了一个程序利用命令regedit来读取注册表的某项值,出现了一个奇怪的现象:在某些电脑上能读到值,在另一些电脑上无法读取。
在无法读取的机器上手动查看,注册表确实是有这个值的。百思不得其解,猜测可能是权限的问题。
试了以上两种方法还是不行。
思考是否为进程权限太低?于是使用Processexp看一下进程的权限。当看到进程路径时,看出了一点端倪。 在x86的机器上,我们程序调用的regedit的路径是C:\windows\regedit.exe;而在x86_64上,程序调用的regedit的路径是C:\windows\SysWOW64\regedit.exe。
用实例程序分别编译为32bit和64bit演示一下,不同的程序运行的系统命令所在的路径。
#include<stdio.h>#include<stdlib.h>int main(){ system("cmd"); return 0;} |
---|
其中SysWOW64(System Windows on Windows64)是windows的一个兼容层,用来在x86_64的机器上运行x86程序。说白了就是在64bit操作系统上运行32bit程序。因为我们的程序是32bit的,所以在32bit程序中调用的系统程序也是32bit的。
正巧程序读取的注册表键值在64bit版的regedit上可以读取,而在32bit版本的regedit上无法读取,这就造成了开头的问题。
解决方法有两种:
第一种方法当然简单粗暴,但是在x86的系统上却无法运行,只能寻求第二种方法。
#include<stdio.h>#include<stdlib.h>#include<windows.h>int main(){ PVOID OldVal = NULL; if (Wow64DisableWow64FsRedirection(&OldVal)) { system("cmd"); } if (FALSE == Wow64RevertWow64FsRedirection(OldVal)) { return 1; } return 0;} |
---|
可以看到启动的cmd已经是64bit的了。
注意,关闭重定向后完成相关操作一定要恢复重定向,一定要恢复重定向,一定要恢复重定向,重要的事情说三遍,若不恢复的话会导致一些dll等调用失败。
wow64其实相当于64bit系统的一个子系统,用来兼容32bit的程序。32bit程序运行时会收到重定向的影响,这个重定向主要分为:
当32bit程序运行时,会存在以下的重定向规则。
访问 | 重定向 |
---|---|
%systemroot%/system32 | %systemroot%/SysWOW64 |
比如,当32bit程序访问calc.exe时,本应访问
C:\windows\system32\calc.exe |
---|
但是由于重定向机制,会被重定向到
C:\windwos\SysWOW64\calc.exe |
---|
不多说,想了解的话看看微软的文章。 https://msdn.microsoft.com/en-us/library/windows/desktop/aa384253(v=vs.85).aspx
http://blog.csdn.net/magictong/article/details/5892209 http://www.cnblogs.com/lhglihuagang/p/3930874.html http://www.tuicool.com/articles/Ibui6bZ