October 4, 2006

Writing to the registry under WOW64

Writing into the registry under WOW64 (a x86 program which is running on an x64 OS) has some tricks.
Not only the registry redirector will be in charge, also some values you want to write will be changed to other values.
One of this value is ”%ProgramFiles%” if it is written with the type REG_EXPAND_SZ. This string will be replaced with ”%ProgramFiles(x86)%”. This is also a documented feature.

But there seems to be a bug (all) x64 OSes: The comparsion is case-sensitive! If you write ”%programFiles%”, this string will not be replaced!

Some details:
The “rewriting” is done in Wow64NtSetValueKey. Here you can see that the OS is using wcsstr instead of wcsistr.
Also you can see that the value ”%commonprogramfiles%” will also be replaced by ”%commonprogramfiles(x86)%”. And this comparsion is also case-sensitive…

Here is some code, you can test on your own x64 machine:

#include <windows.h>

#include <tchar.h> int _tmain() { HKEY hKey; RegCreateKeyEx(HKEY_CURRENT_USER, _T("SOFTWARE\\TEST"), 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL); LPCTSTR szTest1 = _T("%<span>ProgramFiles</span>%\\Test"); RegSetValueEx(hKey, _T("Test1"), 0, REG_EXPAND_SZ, (LPBYTE) szTest1, (DWORD) (_tcslen(szTest1)+1)*sizeof(TCHAR)); LPCTSTR szTest2 = _T("%<span>programFiles</span>%\\Test"); RegSetValueEx(hKey, _T("Test2"), 0, REG_EXPAND_SZ, (LPBYTE) szTest2, (DWORD) (_tcslen(szTest2)+1)*sizeof(TCHAR)); LPCTSTR szTest3 = _T("%<span>commonprogramfiles</span>%\\Test"); RegSetValueEx(hKey, _T("Test3"), 0, REG_EXPAND_SZ, (LPBYTE) szTest3, (DWORD) (_tcslen(szTest3)+1)*sizeof(TCHAR)); LPCTSTR szTest4 = _T("%<span>Commonprogramfiles</span>%\\Test"); RegSetValueEx(hKey, _T("Test4"), 0, REG_EXPAND_SZ, (LPBYTE) szTest4, (DWORD) (_tcslen(szTest4)+1)*sizeof(TCHAR)); RegCloseKey(hKey); return 0; }

Posted 1 year, 2 months ago on October 4, 2006
The trackback url for this post is http://blog.kalmbachnet.de/bblog/trackback.php/89/

Comments have now been turned off for this post