Существует ли файл в папке 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