关于windows注册表重定向和虚拟化分析
轉載源地址?https://www.cnblogs.com/xenophon/p/4956218.html
在 64 位系統上,32 位程序讀寫部分注冊表路徑時會被系統重定向,這有些類似于讀寫 System32 文件夾的處理方式。比如,寫入 HKLM\Software\KeyName,卻發現實際寫入到 HKLM\Software\Wow6432Node\KeyName,讀取亦是如此。現實中發現,很多的程序員在檢測一個程序在 HKLM 鍵下面的注冊表信息,通常會針對 HKLM\Software 和 HKLM\Software\Wow6432Node 分別檢查,實際上這樣檢查毫無效果。對于 32 位程序而言,訪問 HKLM\Software 時,系統底層會重定向到 HKLM\Software\Wow6432Node,并不能得到真正的 HKLM\Software 下面的信息,即便再訪問一次 HKLM\Software\Wow6432Node,經測試也是訪問 Wow6432Node 下面的值,和直接訪問 HKLM\Software 并沒有任何區別。如果你仔細閱讀 MSDN 上關于注冊表重定向和訪問權限等資料,會發現微軟提供了兩個特殊的注冊表權限位:KEY_WOW64_32KEY、KEY_WOW64_64KEY,來控制訪問權限。所以,當使用 RegOpenKeyEx 或 RegCreateKeyEx 訪問注冊表的 HKCR 或 HKLM\Software 下的路徑,不需要顯式指定 Wow6432Node,而是應當通過其權限位,如 KEY_READ,和上述二者之一進行組合來控制具體的訪問位置。如果開發者顯示指定 HKLM\Software\Wow6432Node,則程序在任何情況下都是訪問這個路徑。但是在 32 位系統中,這個路徑默認并不存在,如果強行創建,依然沒有任何意義。為了保持統一以及遵循 API 的規范,我們應該做到不顯式指定 Wow6432Node 子鍵。如果不通過權限位進行訪問視圖控制,可能會造成代碼邏輯混亂,如訪問不同的注冊表路徑實際上底層邏輯相同,或者同樣的代碼編譯為 32 位或 64 位后邏輯不一致等等。所以,如果要檢測 32 位和 64 位注冊表 HKLM\SOFTWARE\KeyName 下是否存在 ValueName,規范的代碼如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | BOOL?WINAPI RegCheckValueTest(void) { ????DWORD?dwWowFlags[] = { KEY_WOW64_32KEY, KEY_WOW64_64KEY }; ????DWORD?dwWowCount = ARRAYSIZE(dwWowFlags); ????for?(size_t?i = 0; i < dwWowCount; i++) ????{ ????????HKEY?hKey = NULL; ????????DWORD?dwAccess = KEY_READ | dwWowFlags[i]; ????????DWORD?dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\KeyName"), dwAccess, &hKey); ????????if?(dwError == NO_ERROR) ????????{ ????????????dwError = RegQueryValueEx(hkeySub, _T("ValueName"), NULL, NULL, NULL, NULL); ????????????RegCloseKey(hKey); ????????????if?(dwError == NO_ERROR) ????????????{ ????????????????return?TRUE; ????????????} ????????} ????} ????return?FALSE; } |
在不同 CPU 位數的系統上,32 位和 64 位程序分別使用不同的權限位組合訪問 HKLM\Software 時,系統底層實際訪問的注冊表位置如下表所示:
| 系統架構 | 程序架構 | 顯式訪問路徑 | 實際訪問路徑 | 備注 | ||
| 權限位不含 KEY_WOW64_* | 權限位包含 KEY_WOW64_32KEY | 權限位包含 KEY_WOW64_64KEY | ||||
| 32 位系統 | 32 位程序 | HKLM\Software | HKLM\Software | 原因:在 32 位系統上不存在不同訪問視圖 影響:參數 KEY_WOW64_* 被系統忽略 | ||
| 64 位系統 | 32 位程序 | HKLM\Software | HKLM\Software\Wow6432Node | HKLM\Software\Wow6432Node | HKLM\Software | ? |
| 64 位程序 | HKLM\Software | HKLM\Software | ||||
| 32 位程序 | HKLM\Software\Wow6432Node | HKLM\Software\Wow6432Node | 原因:在路徑中顯式指定了 Wow6432Node 節點 影響:參數 KEY_WOW64_* 被系統忽略 | |||
| 64 位程序 | ||||||
備注:注意RegOpenKeyEx第四個形參,KEY_QUERY_VALUE或者KEY_READ、KEY_ALL_ACCESS等,權限是有區別的,不要越權操作,否側會被返回為空。
KEY_QUERY_VALUE顯然權限低于KEY_ALL_ACCESS。
可見,32 位程序訪問注冊表 HKLM\Software 路徑時,默認會被重定向到 HKLM\Software\Wow6432Node,如果權限位指定 KEY_WOW64_64KEY 時則訪問 HKLM\Software。64 位程序訪問注冊表 HKLM\Software 路徑時,默認會訪問 HKLM\Software,如果權限位指定 KEY_WOW64_32KEY 時則訪問 HKLM\Software\Wow6432Node。當然,前提是程序并沒有受到注冊表虛擬化影響,否則會被寫入到以下注冊表位置:
| 1 2 | HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE\Wow6432Node |
實際觀察發現 HKCU\SOFTWARE\Wow6432Node 下面只有極少量的數據,因此 HKCU\SOFTWARE\Wow6432Node 下面(包括其他從此處映射的鍵)的注冊表鍵通常可以忽略。這可以說明,注冊表針對 32 和 64 位的重定向僅針對 HKLM(包括其他從此處映射的鍵)有效,如果要訪問 HKCU 下面的節點,通常無需考慮重定向的問題。而在 32 位系統上,不存在注冊表重定向的問題。
關于注冊表重定向的更多信息,請訪問:
https://msdn.microsoft.com/en-us/library/aa384253.aspx
https://msdn.microsoft.com/en-us/library/aa384129.aspx
總結
以上是生活随笔為你收集整理的关于windows注册表重定向和虚拟化分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win10 远程桌面无法连接报错
- 下一篇: windows11图文安装流程