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

Оцени полезность:

8   голосов , оценка 3.875 из 5
Похожие ответы