Проверка ключей реестра на подверженность перенаправлению Wow6432 (redirected, shared, reflected)
Привет!
Для тех, кому все это в новинку поясню, что для 64-разрядных ОС некоторые ключи в реестре существуют в двух представлениях:
— для х64 битных приложений.
— для х32 битных приложений.
1. Ключ HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID (и все его подразделы) — является 64-битным
2. Ключ HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node\CLSID (и все его подразделы) — 32-битным.
Если вы попытаетесь в 64-битной ОС с помощью 32-разрядного приложения прочитать/записать/удалить и.т.п. ключ № 1, произойдет перенаправление, и действие выполнится с ключем № 2.
Это пример обычного перенаправления (redirected).
Виды перенаправлений
В плане переадресации существуют такие виды ключей реестра:
1. Перенаправляемые (redirected)
2. Общие (shared)
3. Отраженные (reflected)
4. Также выделю отдельной группой симлинки (symlink), связанные с механизмом registry redirector.
1. Перенаправляемые (redirected).
Пример таких ключей описан выше (см. Введение).
Возьмем для примера такие ключи:
а) HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Policies (32-битное представление)
б) HKLM\Software\Microsoft\Windows\CurrentVersion\Policies (64-битное представление)
В виду особой важности, некоторые ключи в обеих представлениях (64 и 32) физически ссылаются на один и тот же ключ. Это означает, что если Вы измените ключ под Wow6432Node (ключ а.), то изменения будут видны и в ключе б. И наоборот.
Такие ключи использовались в ОС Windows Server 2008 / Vista / Server 2003 / XP.
Начиная с Windows 7 они были заменены на Shared (общие ключи, см. выше).
Отличием от Shared ключей является то, что физически — это 2 разных ключа. Но, как только программа завершает запись в любой из этих ключей, он автоматически копируется в другое представление. Таким образом, их состояние синхронизируется между собой.
4. Симлинки, связанные с переадресацией под Wow64.
Microsoft не рекомендует использовать для доступа к 32-разрядным ключам жестко закодированные строки, проходящие через имя Wow6432Node. Вместо этого есть цивилизованные способы.
Однако, некоторые программисты все же используют такие пути. И это могло бы плохо закончится, потому что, начиная с Windows 7 (?) путь к Wow6432Node для некоторых ключей изменился, а для других было вообще отключено 32-битное представление.
- HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes указывает на HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node
- HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node\AppId указывает на HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppId
- HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node\PROTOCOLS указывает на HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PROTOCOLS
- HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node\Typelib указывает на HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Typelib
- HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes указывает на HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node (для ОС Windows Server 2008 / Vista / Server 2003 / XP)
Возьмем замечательную утилиту ListRegistryLinks от Helge Klein, и выполним в командной строке, например, такое для улья HKLM:
Перечень ключей реестра, подверженных переадресации
Такой перечень присутствует на сайте Microsoft, но он давно не обновлялся.
Я написал скрипт (батник), который позволяет проверить индивидуальный (введенный вами) ключ на предмет его перенаправления таких видов:
1) Shared
2) Redirected
Если ключ обычный — батник ничего не выведет.
Рекомендуется пользоваться батником на виртуальной машине , т.к. он оставляет мусор в виде пустых ключей в 32-битном представлении. Они специально не удаляются в целях безопасности (чтобы ничего лишнего не наудалять).
Также он не особо хорошо тестировался. Я на 100% не гарантирую, что он все правильно определит.
Тем не менее, по моим ручным тестам (с подтверждением) уже нашлись расхождения даже с официальной информацией, например, на Windows 7 ключ
Вы используете «Wow6432Node» в своем коде? Немедленно прекратите!
Я уже упоминал несколько раз, что 64-х разрядные версии Windows используют два раздельных представления реестра – одно для 32-х разрядных приложений, а другое для 64-х разрядных. Как-то, я даже писал о том, как это делается. Ключевых моментов там всего ничего:
Разделён не весь реестр, а лишь некоторые из ключей;
Физически 32-х разрядные ключи помещаются в ветки с именем «Wow6432Node»;
Приложения могут выбирать представление реестра с которым они хотят работать с помощью флагов KEY_WOW64_32KEY и KEY_WOW64_64KEY (см. Accessing an Alternate Registry View).
Проблема, однако, заключается в том, что многие приложения имею тенденцию явно использовать «Wow6432Node», чтобы получить доступ к 32-х битным ключам реестра. Похоже, что всё происходит по такому сценарию:
Разработчики пробуют перевести приложение на 64-х битную платформу и натыкаются на проблему с реестром;
В процессе решения они узнают о разделении реестра и о том, что 32-х разрядные ключи расположены под «Wow6432Node»;
На коленке разрабатывается заплатка, которая, да, просто добавляет в путь «Wow6432Node», если программа выполняется под Wow64;
Ура! Всё работает, проблема решена, программисты идут пить пиво…
Что не тут так? «Wow6432Node» не документирована, как способ доступа к 32-х битному представлению реестра. Если поискать «Wow6432Node» на msdn.microoft.com, то в результате будет найдено довольно много статей упоминающих «Wow6432Node», однако все они либо описывают особенности организации реестра на 64-х разрядных версиях системы, либо описывают временные решения для проблем, возникающих с 32-х разрядными приложениями на 64-х битных системах. Поиск по KEY_WOW64_32KEY возвращает гораздо меньше статей, но первые же четыре ссылки ведут на статьи, описывающие рекомендованный способ работы реестром на 64-х разрядных OS.
Впрочем, я прекрасно понимаю, почему так происходит. Дизайн Wow64 – не самая прозрачная часть системы. Это скорее проэволюционировавший хак, чем хорошо продуманный компонент системы. В частности разделение реестра на два виртуальных представления – не самое очевидное архитектурное решения для разработчиков приложений. Тем не менее, код, использующий «Wow6432Node», — это очень плохое решение. По нескольким причинам:
Структура реестра может поменяться с выходом следующей версией операционной системы либо даже с выходом нового сервис пака. Иными словами время жизни такого решения (фактически — заплатки) — пара лет;
Как правило, используя подобную заплатку разработчики не понимают, что стоит за разделением реестра. В такой ситуации высока вероятность того, что в другие местах продукта имеется аналогичная или похожая проблема, связанная с особенностями 64-х разрядного реестра. В результате рождаются уродцы вроде принудительной синхронизации синхронизация 32-х и 64-х битных версий ключа (AKA закат солнца вручную). Частенько 32-х и 64-х разрядные компоненты приложения ведут себя по-разному;
Такая заплатка создаёт иллюзию правильности – ведь работает же! Она имеет все шансы попасть в финальную версию продукта и разойтись по тысячам пользователей. Соответственно, распространение исправленной версии встанет в копеечку;
Высокая стоимость исправления подобной заплатки может стать причиной того, что оно будет отложено до выхода следующей версии продукта, а пользователям будет рекомендовано не обновлять операционную систему. Фактически, повториться история с выходом Vista – относительно много приложений не будет совместимо со следующей версией системы. А на кого посыпятся все шишки? Именно!
В общем, вы всё еще используете «Wow6432Node» в своем коде? Немедленно прекратите!
What's the Wow6432Node under the HKEY_LOCAL_MACHINE\SOFTWARE registry subkey?
A. The Wow6432 registry entry indicates that you're running a 64-bit version of Windows. The OS uses this key to present a separate view of HKEY_LOCAL_MACHINE\SOFTWARE for 32-bit applications that run on a 64-bit version of Windows. When a 32-bit application queries a value under the HKEY_LOCAL_MACHINE\SOFTWARE\<company>\<product> subkey, the application reads from the HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\<company>\<product> subkey.
Разница в реестре 64 битной версии Windows
64-битное программное обеспечение с трудом удается совместить с 32-битным; это вызывает необходимость существования двух реестров, чтобы эти биты находились подальше друг от друга. Поскольку иметь два независимых реестра непрактично, разделяются лишь некоторые разделы и ветви.
Сопоставления типов файлов, например, общие для обоих слоев поэтому вы можете один раз связать .txt-документы с любимым текстовым редактором, и эти связи будут работать и в 32-битной, и в 64-битной версиях Windows.
Но в то же время 64-битная программа не может обратиться к 32-битной DLL. Часть реестра, управляющая DLL и другими компонентами, будет для каждого слоя Windows отдельной. Таким образом, например, 64-битные версии Проводника и Internet Explorer недоступны для 32-битных DLL, и наоборот.
Как правило, такой раздвоенный дизайн не требует от вас дополнительных усилий. Каждое из 32-битных приложений видит только те разделы реестра, которые оно должно видеть, а все 64-битные приложения видят только 64-битный реестр.
Дополнительные усилия понадобятся только в тех случаях, когда двойственность реестра становится помехой для ежедневного неавторизованного доступа или вас начинают раздражать надоедливые предупреждения.
Редактор реестра включает специальную ветвь Wow6432Node, позволяющую получить доступ к 32-битным записям из того же окна, что и к 64-битным. В Windows 7 по умолчанию существует три таких «узла»: