Существует ли файл в папке Windows\System32 на 64-разрядной ОС (или обход механизма File System Redirector) - VB
Формулировка задачи:
Проведем эксперимент, если Вы владелец 64-разрядной версии ОС Windows:
1. Откройте стандартный поиск, или проводник (если ver. OS > XP).
Пишем в строке поиска MSG.exe
Комментарии?
Результат:
найден в папке windows\system32 2. Запускаем любой 32-битный файловый менеджер (например, Total Commander) Можем просто пролистать файлы в папке System32, а можем указать во встроенном поиске (ALT+F7) MSG.exeРезультат:
найдено 0 файлов. Вот таксюрприз.
Кроме того, попытавшись сделать тоже самое
мы получим также нулевой результат.
На эту удочку я недавно попался при отладке Batch-сценария.
Виновником оказался так называемый механизм перенаправления файловых запросов в 64-разрядной версии ОС Windows (File System Redirector), о котором рассказывает Microsoft.
То есть на самом деле запросы 32-битных приложений при попытке обратится к системной директории System32
файловая система автоматически переадресовывает в папку SysWOW64.
Почему так сделано, можно почитать здесь.
Но как же нам обойти систему виртуализации.
Вот реализация на VB принципа, указанного в статье MS:
Способ 1.
Временное отключение механизма перенаправления файловых запросов.Способ 2
. Обращаемся к папке System32 через алиас "Sysnative".Недостатки способа № 1
: 1. Относительная небезопасность: реактивацию перенаправления ФС нужно сделать как можно быстрее, чтобы не прервать работу c 64-битными библиотеками в этом потоке. 2. Еще есть информация о предупреждении UAC при попытке снять режим File System Redirection. Запуск примера на ОС Win 7 x64 Ultimate с максимальным уровнем UAC показал, что защита молчит во время этой манипуляции. 3. Также данная API-функция будет работать только на 64-разрядной версии ОС, поэтому разрядность тоже
Стоит добавить, что подобная ситуация также касается ветки реестра HKLM\Software\Wow6432Node
Для обхода этого также существует специальный алиас.
Не по теме:
Хотелось бы знать, можно ли заставить систему думать, что запрос к файловой системе исходит от 64-битного приложения?
Решение задачи: «Существует ли файл в папке Windows\System32 на 64-разрядной ОС (или обход механизма File System Redirector)»
textual
Листинг программы
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" _ (ByVal hKey As Long, ByVal lpSubKey As String, _ ByVal ulOptions As Long, _ ByVal samDesired As Long, _ phkResult As Long) As Long Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long Private Declare Function RegEnumKeyEx Lib "advapi32.dll" Alias "RegEnumKeyExA" _ (ByVal hKey As Long, _ ByVal dwIndex As Long, _ ByVal lpName As String, _ lpcbName As Long, _ ByVal lpReserved As Long, _ ByVal lpClass As String, _ lpcbClass As Long, _ lpftLastWriteTime As FILETIME) As Long Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" _ (ByVal hKey As Long, _ ByVal lpValueName As String, _ ByVal lpReserved As Long, _ lpType As Long, _ lpData As Any, _ lpcbData As Long) As Long Private Declare Function RegSetValueEx Lib "advapi32" Alias "RegSetValueExA" _ (ByVal hKey As Long, _ ByVal lpValueName As String, _ ByVal Reserved As Long, _ ByVal dwType As Long, _ ByVal szData As String, _ ByVal cbData As Long) As Long Public Enum RegTypes RegNonee = 0 RegSZ = 1 RegExpandSz = 2 RegBinary = 3 RegDword = 4 RegDwordLittleEndian = 4 RegDwordBigEndian = 5 RegLink = 6 RegMultiSz = 7 RegResourceList = 8 RegFulResourceDesc = 9 End Enum Private Const HKEY_CLASSES_ROOT = &H80000000 Private Const HKEY_CURRENT_USER = &H80000001 Private Const HKEY_LOCAL_MACHINE = &H80000002 Private Const HKEY_USERS = &H80000003 Private Const HKEY_PERFORMANCE_DATA = &H80000004 Private Const HKEY_CURRENT_CONFIG = &H80000005 Private Const HKEY_DYN_DATA = &H80000006 Private Const KEY_ALL_ACCESS = &HF003F Private Const KEY_WRITE = &H20006 Private Const KEY_READ = &H20019 Private Const KEY_QUERY_VALUE = &H1 Private Const KEY_ENUMERATE_SUB_KEYS = &H8 Private Const KEY_CREATE_SUB_KEY = &H4 'Registry Redirector Subsystem 'http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129(v=vs.85).aspx Private Const KEY_WOW64_64KEY = &H100 'Access a 64-bit key from either a 32-bit or 64-bit application. Private Const KEY_WOW64_32KEY = &H200 'Access a 32-bit key from either a 32-bit or 64-bit application. 'Can be used by: ' - RegCreateKeyEx ' - RegDeleteKeyEx ' - RegOpenKeyEx Private Sub Command1_Click() 'Записываем новый ... Dim badRoot$, Ret_1&, Ret_2& badRoot = "HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\" & badCLSID & "\TypeLib" 'Записываем ключ в 32-битных ветвях Ret_1 = WriteKey(badRoot, "", Key2099, False) 'Записываем ключ в 64-битных ветвях Ret_2 = WriteKey(badRoot, "", Key2099, True) MsgBox "32-битная ветка - " & IIf(Ret_1, "Успех.", "Ошибка.") & vbCrLf & _ "64-битная ветка - " & IIf(Ret_2, "Успех.", "Ошибка.") end sub 'Самоэлевация прав программы Private Sub Form_Initialize() 'Exit Sub 'Временно, пока не скомпилирую проект With CreateObject("WScript.Shell") On Error Resume Next .RegWrite "HKLM\isElevated", "", "REG_SZ" If Err <> 0 Then CreateObject("Shell.Application").ShellExecute App.Path & "\" & App.EXEName & ".exe", "1", "", "runas", 1 End Else .RegDelete "HKLM\isElevated" End If End With End Sub Private Function GetMainKeyHandle(MainKeyName As String) As Long 'Получить хендл главного улья On Error Resume Next Select Case MainKeyName Case "HKEY_CLASSES_ROOT" GetMainKeyHandle = HKEY_CLASSES_ROOT Case "HKEY_CURRENT_USER" GetMainKeyHandle = HKEY_CURRENT_USER Case "HKEY_LOCAL_MACHINE" GetMainKeyHandle = HKEY_LOCAL_MACHINE Case "HKEY_USERS" GetMainKeyHandle = HKEY_USERS Case "HKEY_PERFORMANCE_DATA" GetMainKeyHandle = HKEY_PERFORMANCE_DATA Case "HKEY_CURRENT_CONFIG" GetMainKeyHandle = HKEY_CURRENT_CONFIG Case "HKEY_DYN_DATA" GetMainKeyHandle = HKEY_DYN_DATA End Select End Function Private Function WriteKey(rPath$, ParamName, ParamValue, Optional is64Node As Boolean = False) 'Функция записывает значение в реестр. 'Возвращает результат выполнения API-функции RegSetValueEx 'Умеет использовать Registry Redirector SybSystem (в 64 или 32-битную ветку записывать данные) Dim Ret_1&, Ret_2&, sSubKey$, Hive$, hSubKey&, regAccess& Hive = Split(rPath, "\")(0) sSubKey = IIf(Len(Hive) = Len(rPath), "", Replace(rPath, Hive & "\", "")) If is64Node Then regAccess = KEY_QUERY_VALUE Or KEY_WRITE Or KEY_WOW64_64KEY Else regAccess = KEY_QUERY_VALUE Or KEY_WRITE Or KEY_WOW64_32KEY End If Ret_1 = RegOpenKeyEx(GetMainKeyHandle(Hive), sSubKey, 0&, regAccess, hSubKey) Ret_2 = RegSetValueEx(hSubKey, ParamName, 0, RegTypes.RegSZ, ParamValue, Len(ParamValue) + 1) RegCloseKey hSubKey WriteKey = Ret_2 End Function
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д