注册表重定向

什么是重定向

       无论是Windows XP Professional X64 Edition、Windows Server 2003X64 Edition、Windows Vista X64 Edition 还是Windows 7 x64(以下把均统称为X64系统),都引入了一项技术:文件和注册表的重定向。

       之所以有这个技术,是为了将32位程序和64位程序分离开。这种在64位平台上运行32位程序的模拟器被称为WOW64。WOW64是"Windows 32 on Windows 64"的简称,它在系统层中另提供了一层,以支持老式的32位程序。


文件重定向:

对于64位应用程序,其文件通常被放在%windir%\system32和%ProgramFiles%,      即:C:\Windows\system32  和 C:\program files。

对于32位应用程序,其文件通常被放在%windir%\syswow64和%ProgramFiles(x86),即:C:\Windows\syswow64 和 C:\program files (x86)。


注意:

上面说明的只是windows对32位程序和64位程序的分开存放机制,但在重定向方面,只是存在system32和systemWOW64的重定向,而不存在program files和ProgramFiles(x86)的重定向一说,直接访问死路径即可。


针对%windir%\system32, 如果我们用32位程序去访问%windir%\system32,不管我们用硬编码还是其它的方式,系统都会自动地给我们转向 到%windir%\syswow64下面。这种转向对于每个32位应用程序默认都是打开的。但是这种转向对于我们来说并不总是需要的。那么我们可以调用相关的API来关闭和打开这种转向。常用的函数有3个,Wow64DisableWow64FsRedirection(关闭系统转向),Wow64RevertWow64FsRedirection(打开系统转向),Wow64EnableWow64FsRedirection(打开系统转向)。但是Wow64EnableWow64FsRedirection在嵌套使用的时候不可靠,所以通常用上面的 Wow64RevertWow64FsRedirection来打开文件系统转向功能。


但是,针对ProgramFiles和program files (x86),则不受这两个API的影响,而只跟应用程序本身是否是32还是64位有关,

(1). 当你使用ExpandEnvironmentStrings或GetEnvironmentVariable来展开环境变量“ProgramFiles”时,

 如果是32位程序则返回的路径总是C:\Program Files (x86),而如果是64位程序,则返回总是C:\Program Files。

详细说明(前提是在64位系统上):

32位程序: GetEnvironmentVariable("ProgramFiles", buf, MAX_PATH);            //返回C:\program files (x86)--这不算重定向,这是32位的真实目录

64位程序: GetEnvironmentVariable("ProgramFiles", buf, MAX_PATH);            //返回C:\program files

32位程序: GetEnvironmentVariable("ProgramFiles(x86)", buf, MAX_PATH);    //返回C:\program files (x86)

64位程序: GetEnvironmentVariable("ProgramFiles(x86)", buf, MAX_PATH);    //返回C:\program files (x86)--因为64位程序可以直接访问32位目录

(2). 即使先关闭重定向,再获取环境变量,展开结果32位程依然是C:\Program Files (x86),而64位程序也依然是C:\Program Files。

理解:系统重定向只是重定向用户的访问(读/写/执行),而不关心变量的获取,所以重定向相关API对获取变量是无效的。

(3). 不管是32位程序,还是64位程序,在64位系统上,如果要访问ProgramFiles或ProgramFiles(x86)目录,例如,判断文件是否存在,生成文件到此目录等等,只要写死路径即可,不需要使用变量。


注意:针对文件重定向,只有32位程序访问64位目录时才会被重定向,例如32位程序访问64位目录C:\Windows\system32

而64位程序则可以直接访问32位目录,不存在重定向,例如64位程序可以直接访问C:\Windows\syswow64


注册表重定向:

        为了防止注册表键冲突,注册表在某些键也分成了两个部分:一部分是专门给64位系统访问的;另一部分是专门给32位系统访问的,放在Wow6432Node下面。当32位程序去访问某些键值的时候,和文件转向类似,系统也会自动地把程序的访问转向到Wow6432Node下面。Wow6432Node这个节 点存在于HKEY_LOCAL_MACHINE和HKEY_CURRENT_USER下面。如果我们希望关闭这个转向的话,可以通过上面的Wow64DisableWow64FsRedirection。



在X64系统里面,一些特殊的目录特殊的注册表键均被分为2个独立的部分:

      (1)对于文件系统来说,%systemroot%/system32 目录被保留给64位文件使用,而32位文件会被重定向到%systemroot%/SysWOW64目录。换句话说,所有的32位程序一般情况下只会出现在%systemroot%/SysWOW64目录里面。任何32位程序试图访问%systemroot%/system32 目录的企图都会被重定向到%systemroot%/SysWOW64目录。这个是一个默认的行为,除非程序的线程明确的指名需要关闭这种重定向机制。

      (2)对于注册表来说,也有类似的内容。WOW64子系统也提供了对注册表访问的重定向。如果是32位程序,对注册表的操作不论是读还是写, WOW64都将会截取对HKLM/Software访问,并重定向到HKLM/Software/Wow6432Node(即32位应用程序的注册信息被写在HKLM/Software/Wow6432Node中,而不是预期的HKLM/Software中);如果是64位程序,就直接到 HKLM/Software。


需要重定向的注册表项

注册表重定向,其实质就是维护两套不同的注册表键,一套用于64位,一套用于32位。受影响的键不只是上面提及的HKLM/Software,还包括:
        HKEY_CLASSES_ROOT 
        HKEY_CURRENT_USER/Software/Classes 
        HKEY_LOCAL_MACHINE/Software 
        HKEY_USERS/*/Software/Classes 
        HKEY_USERS/*_Classes
        其中,64位程序的注册信息存储在上面的健中,32位程序的注册信息重定向存储在下列健中:

        HKEY_CLASSES_ROOT/WOW6432node 
        HKEY_CURRENT_USER/Software/Classes/WOW6432node 
        HKEY_LOCAL_MACHINE/Software/WOW6432node 
        HKEY_USERS/*/Software/Classes/WOW6432node 
        HKEY_USERS/*_Classes/WOW6432node

 当运行32位程序,wow64会截取程序对注册表HKLM/Software的访问,并重定向于HKLM/Software/Wow6432Node。

 

如前面所述,以上这些键会被维护2套,但是这2套键是如何维护的呢?其维护的方法是采用一种被称为注册表反射的机制完成的。

注册表反射

注册表反射是在64 位注册表视图和 32 位注册表视图之间复制某些特定的注册表项和项值。

如在X64系统中,我们在安装64位Microsoft Office后, 64位的winword.exe将注册.doc这个扩展名并把这个扩展名关联到winword.exe程序,根据X64的运行机制,64位程序修改的是64位的注册表键值,但是WOW64会自动的把这个修改会同步到32位的注册表键下面,这样32位和64位的应用程序都可以使用64位winword.exe打开.doc文件。

 

但是,并不是所有的键值都会受到注册表反射机制的影响。实验证明,如果我们使用32位的注册表编辑器在HKEY_LOCAL_MACHINE/Software下新建一个项,然后使用64位的注册表编辑器查看,会发现这个项只会出现在HKEY_LOCAL_MACHINE/Software/Wow6432Node键下而不会出现在HKEY_LOCAL_MACHINE/Software键下,因为HKEY_LOCAL_MACHINE/Software键是专门用于存放64位程序所使用的注册表数据的,而HKEY_LOCAL_MACHINE/Software/Wow6432Node键是专门用于存放32位程序所使用的注册表数据的。

 

注册表中受到反射机制影响的有:

HKEY_LOCAL_MACHINE/Software/Classes(32位XP下读写HKEY_CLASSES_ROOT/Rising.Rav.20会同时出现HKEY_LOCAL_MACHINE/Software/Classe/Rising.Rav.20,两者的值永远相同,似乎有一个是镜像,64位XP下读写HKEY_CLASSES_ROOT/Rising.Rav.20则会被重定向到HKEY_LOCAL_MACHINE/Software/Classe/Rising.Rav.20,并且由于注册表反射的原因,同时也会修改HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/Classes/Rising.Rav.20,两者的值同样是永远相同的。)

HKEY_LOCAL_MACHINE/Software/COM3

HKEY_LOCAL_MACHINE/Software/EventSystem

HKEY_LOCAL_MACHINE/Software/Ole

HKEY_LOCAL_MACHINE/Software/Rpc

HKEY_USERS/*/Software/Classes

HKEY_USERS/*_Classes

 

注册表重定向机制对系统的影响

       由于注册表重定向机制存在,下列程序调用没有问题:

Ø         32位应用程序a调用32位应用程序b并访问b的注册表信息。由于注册表重定向机制,32位应用程序b的注册信息在HKLM/Software/Wow6432Node中,而32位应用程序a访问注册表也会被重定向到HKLM/Software/Wow6432Node中,所以访问正常;

Ø         64位应用程序a调用64位应用程序b并访问b的注册表信息。64位应用程序b的注册信息在HKLM/Software,64位应用程序a访问注册表时直接访问HKLM/Software,所以访问正常;

 

但是在下列情况时会出现问题:

Ø         64位应用程序调用32位应用程序并访问其注册表信息。

如瑞星杀软有U盘病毒查杀功能,在插入U盘后弹出的提示框中有瑞星杀毒的标志;但是在64位系统中,此项功能失效。这是因为32位瑞星将此项功能的注册信息写到了HKLM/Software/Wow6432Node下;而调用该功能的应用程序是64位的操作系统,由于64位操作系统访问注册表时直接访问HKLM/Software,所以没有读取到该功能的注册数据,该功能因而失效。

解决方法:在此功能写注册表时,32位瑞星应用程序要将该注册信息写到64位程序的注册表项中,即HKLM/Software下。

 

Ø         32位应用程序调用64位应用程序并访问其注册表信息。解决方法可以参上。

应用程序如何访问注册表

上文提到32位与64位应用程序分别访问注册表问题,下面总结一下:

64位程序如何访问64位的注册表(HKLM/Software)

Ø         64位程序访问64位的注册表,直接到 HKLM/Software。

 

32位程序如何访问32位的注册表(HKLM/Software/Wow6432Node)

Ø         32位程序访问32位的注册表, WOW64将会截取对HKLM/Software访问,并重定向到HKLM/Software/Wow6432Node。

 

32位程序如何访问64位的注册表(HKLM/Software)

Ø         在调用函数RegCreateKeyEx创建注册表项时,对其第六个参数REGSAM  samDesired设置中添加参数KEY_WOW64_64KEY,这样可以实现

64位注册表的访问;

Ø         在调用函数RegOpenKeyEx打开注册表项时,要对其第四个参数REGSAM  samDesired设置中添加参数KEY_WOW64_64KEY,这样可以实现对64位注册表的访问;

 

64位程序如何访问32位的注册表(HKLM/Software/Wow6432Node)

Ø         在调用函数RegCreateKeyEx创建注册表项时,对其第六个参数REGSAM  samDesired设置中添加参数KEY_WOW32_64KEY,这样可以实现对32位注册表的访问;

Ø         在调用函数RegOpenKeyEx打开注册表项时,要对其第四个参数REGSAM  samDesired设置中添加参数KEY_WOW32_64KEY,这样可以实现对32位注册表的访问;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值