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

сюрприз.

Кроме того, попытавшись сделать тоже самое
Листинг программы
  1. Private Declare Function PathFileExists Lib "shlwapi.dll" Alias "PathFileExistsA" _
  2. (ByVal pszPath As String) As Long
  3. Private Declare Function GetFileAttributes Lib "kernel32.dll" Alias "GetFileAttributesA" _
  4. (ByVal lpFileName As String) As Long
  5. Const FILE_ATTRIBUTE_DIRECTORY = &H10
  6. Const INVALID_HANDLE_VALUE = &HFFFFFFFF
  7. Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" _
  8. (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
  9. Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long
  10. Const MAX_PATH As Long = 260
  11. Private Type FILETIME
  12. dwLowDateTime As Long
  13. dwHighDateTime As Long
  14. End Type
  15. Private Type WIN32_FIND_DATA
  16. dwFileAttributes As Long
  17. ftCreationTime As FILETIME
  18. ftLastAccessTime As FILETIME
  19. ftLastWriteTime As FILETIME
  20. nFileSizeHigh As Long
  21. nFileSizeLow As Long
  22. dwReserved0 As Long
  23. dwReserved1 As Long
  24. cFileName As String * MAX_PATH
  25. cAlternate As String * 14
  26. End Type
  27. Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" _
  28. (ByVal lpFileName As String, _
  29. ByVal dwDesiredAccess As Long, _
  30. ByVal dwShareMode As Long, _
  31. lpSecurityAttributes As SECURITY_ATTRIBUTES, _
  32. ByVal dwCreationDisposition As Long, _
  33. ByVal dwFlagsAndAttributes As Long, _
  34. ByVal hTemplateFile As Long) As Long
  35. Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
  36. Const FILE_SHARE_READ = &H1
  37. Const FILE_SHARE_WRITE = &H2
  38. Const FILE_FLAG_SEQUENTIAL_SCAN = &H8000000
  39. Const FILE_FLAG_NO_BUFFERING = &H20000000
  40. Const OPEN_EXISTING = 3
  41. Private Type SECURITY_ATTRIBUTES
  42. nLength As Long
  43. lpSecurityDescriptor As Long
  44. bInheritHandle As Long
  45. End Type
  46. Option Explicit
  47. Private Sub Command1_Click()
  48. Dim exe As String, oFSO As Object, ret As Long
  49. exe = Environ("windir") & "\system32\msg.exe" 'C:\Windows\System32\MSG.exe
  50. 'Встроенная функция Dir
  51. If Dir$(exe, vbReadOnly Or vbSystem Or vbHidden) <> vbNullString Then MsgBox "With Dir$ - msg.exe Exists!"
  52. 'Объект WSH FilesystemObject
  53. Set oFSO = CreateObject("Scripting.FilesystemObject")
  54. If oFSO.FileExists(exe) Then MsgBox "With FSO - msg.exe Exists!"
  55. Set oFSO = Nothing
  56. 'Встроенная функция проверки атрибутов
  57. On Error Resume Next
  58. ret = GetAttr(exe)
  59. If Err.Number = 0 Then MsgBox "With Attributes Check - msg.exe Exists!"
  60. On Error GoTo 0
  61. 'API-функция PathFileExists
  62. If PathFileExists(exe) = 1 Then MsgBox "With API PathFileExists - msg.exe Exists!"
  63. 'API-функция GetFileAttributes
  64. ret = GetFileAttributes(exe)
  65. If ret <> INVALID_HANDLE_VALUE And (0 = (ret And FILE_ATTRIBUTE_DIRECTORY)) Then
  66. MsgBox "With API GetFileAttributes - msg.exe Exists!"
  67. End If
  68. 'API-функция FindFirstFile
  69. Dim WFD As WIN32_FIND_DATA, hFile As Long
  70. hFile = FindFirstFile(exe, WFD)
  71. Call FindClose(hFile)
  72. If hFile <> INVALID_HANDLE_VALUE Then MsgBox "With API FindFirstFile - msg.exe Exists!"
  73. 'API-функция CreateFile
  74. Dim Security As SECURITY_ATTRIBUTES
  75. hFile = CreateFile(exe, 0, FILE_SHARE_READ Or FILE_SHARE_WRITE, Security, OPEN_EXISTING, _
  76. FILE_FLAG_NO_BUFFERING Or FILE_FLAG_SEQUENTIAL_SCAN, 0)
  77. If hFile <> INVALID_HANDLE_VALUE Then
  78. CloseHandle (hFile)
  79. MsgBox "With API CreateFile - msg.exe Exists!"
  80. End If
  81. End Sub
мы получим также нулевой результат. На эту удочку я недавно попался при отладке Batch-сценария. Виновником оказался так называемый механизм перенаправления файловых запросов в 64-разрядной версии ОС Windows (File System Redirector), о котором рассказывает Microsoft. То есть на самом деле запросы 32-битных приложений при попытке обратится к системной директории System32 файловая система автоматически переадресовывает в папку SysWOW64. Почему так сделано, можно почитать здесь. Но как же нам обойти систему виртуализации. Вот реализация на VB принципа, указанного в статье MS:

Способ 1.

Временное отключение механизма перенаправления файловых запросов.
Листинг программы
  1. Private Declare Function Wow64EnableWow64FsRedirection Lib "kernel32.dll" _
  2. (ByVal IsEnable As Boolean) As Boolean
  3. Option Explicit
  4. Sub System32file_Exists()
  5. Dim ret_redir As Boolean
  6. Dim exists As Boolean
  7. Dim exe As String
  8. exe = Environ("windir") & "\system32\msg.exe"
  9. ret_redir = Wow64EnableWow64FsRedirection(False)
  10. If Dir$(exe, vbReadOnly Or vbSystem Or vbHidden) <> vbNullString Then exists = True
  11. ret_redir = Wow64EnableWow64FsRedirection(True)
  12. If exists Then MsgBox exe & " is Exists!"
  13. End Sub

Способ 2

. Обращаемся к папке System32 через алиас "Sysnative".
Листинг программы
  1. Option Explicit
  2. Sub System32file_Exists()
  3. Dim exe As String
  4. exe = Environ("windir") & "\system32\msg.exe"
  5. exe = Replace(exe, "system32", "Sysnative", , vbTextCompare)
  6. If Dir$(exe, vbReadOnly Or vbSystem Or vbHidden) <> vbNullString Then
  7. MsgBox exe & " is Exists!"
  8. End If
  9. End Sub

Недостатки способа № 1

: 1. Относительная небезопасность: реактивацию перенаправления ФС нужно сделать как можно быстрее, чтобы не прервать работу c 64-битными библиотеками в этом потоке. 2. Еще есть информация о предупреждении UAC при попытке снять режим File System Redirection. Запуск примера на ОС Win 7 x64 Ultimate с максимальным уровнем UAC показал, что защита молчит во время этой манипуляции. 3. Также данная API-функция будет работать только на 64-разрядной версии ОС, поэтому разрядность тоже
Листинг программы
  1. Public Function Is64system() As Boolean
  2. On Error Resume Next
  3. Is64system = GetAttr(Environ("windir") & "\Sysnative") And vbDirectory
  4. End FunctionPublic Function Is64system() As Boolean
  5. On Error Resume Next 'PROCESSOR_ARCHITEW6432 on x32 is NOT DEFINED
  6. Dim WshShell As Object
  7. Set WshShell = CreateObject("WScript.Shell")
  8. If WshShell.Environment("PROCESS")("PROCESSOR_ARCHITECTURE") = "AMD64" Or _
  9. WshShell.Environment("PROCESS")("PROCESSOR_ARCHITEW6432") = "AMD64" Then
  10. Is64system = True
  11. End If
  12. Set WshShell = Nothing
  13. End Function
Стоит добавить, что подобная ситуация также касается ветки реестра HKLM\Software\Wow6432Node Для обхода этого также существует специальный алиас.

Не по теме:

Хотелось бы знать, можно ли заставить систему думать, что запрос к файловой системе исходит от 64-битного приложения?

Комментарии?

Решение задачи: «Существует ли файл в папке Windows\System32 на 64-разрядной ОС (или обход механизма File System Redirector)»

textual
Листинг программы
  1. Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" _
  2.         (ByVal hKey As Long, ByVal lpSubKey As String, _
  3.          ByVal ulOptions As Long, _
  4.          ByVal samDesired As Long, _
  5.          phkResult As Long) As Long
  6.          
  7. Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
  8.  
  9. Private Declare Function RegEnumKeyEx Lib "advapi32.dll" Alias "RegEnumKeyExA" _
  10.         (ByVal hKey As Long, _
  11.          ByVal dwIndex As Long, _
  12.          ByVal lpName As String, _
  13.          lpcbName As Long, _
  14.          ByVal lpReserved As Long, _
  15.          ByVal lpClass As String, _
  16.          lpcbClass As Long, _
  17.          lpftLastWriteTime As FILETIME) As Long
  18.          
  19. Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" _
  20.         (ByVal hKey As Long, _
  21.          ByVal lpValueName As String, _
  22.          ByVal lpReserved As Long, _
  23.          lpType As Long, _
  24.          lpData As Any, _
  25.          lpcbData As Long) As Long
  26.  
  27. Private Declare Function RegSetValueEx Lib "advapi32" Alias "RegSetValueExA" _
  28.         (ByVal hKey As Long, _
  29.         ByVal lpValueName As String, _
  30.         ByVal Reserved As Long, _
  31.         ByVal dwType As Long, _
  32.         ByVal szData As String, _
  33.         ByVal cbData As Long) As Long
  34.  
  35. Public Enum RegTypes
  36.       RegNonee = 0
  37.       RegSZ = 1
  38.       RegExpandSz = 2
  39.       RegBinary = 3
  40.       RegDword = 4
  41.       RegDwordLittleEndian = 4
  42.       RegDwordBigEndian = 5
  43.       RegLink = 6
  44.       RegMultiSz = 7
  45.       RegResourceList = 8
  46.       RegFulResourceDesc = 9
  47. End Enum
  48.  
  49. Private Const HKEY_CLASSES_ROOT = &H80000000
  50. Private Const HKEY_CURRENT_USER = &H80000001
  51. Private Const HKEY_LOCAL_MACHINE = &H80000002
  52. Private Const HKEY_USERS = &H80000003
  53. Private Const HKEY_PERFORMANCE_DATA = &H80000004
  54. Private Const HKEY_CURRENT_CONFIG = &H80000005
  55. Private Const HKEY_DYN_DATA = &H80000006
  56.  
  57. Private Const KEY_ALL_ACCESS = &HF003F
  58. Private Const KEY_WRITE = &H20006
  59. Private Const KEY_READ = &H20019
  60. Private Const KEY_QUERY_VALUE = &H1
  61. Private Const KEY_ENUMERATE_SUB_KEYS = &H8
  62. Private Const KEY_CREATE_SUB_KEY = &H4
  63.  
  64. 'Registry Redirector Subsystem
  65. 'http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129(v=vs.85).aspx
  66. Private Const KEY_WOW64_64KEY = &H100 'Access a 64-bit key from either a 32-bit or 64-bit application.
  67. Private Const KEY_WOW64_32KEY = &H200 'Access a 32-bit key from either a 32-bit or 64-bit application.
  68. 'Can be used by:
  69. ' - RegCreateKeyEx
  70. ' - RegDeleteKeyEx
  71. ' - RegOpenKeyEx
  72.  
  73. Private Sub Command1_Click()
  74.  
  75.         'Записываем новый ...
  76.        
  77.         Dim badRoot$, Ret_1&, Ret_2&
  78.        
  79.         badRoot = "HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\" & badCLSID & "\TypeLib"
  80.        
  81.         'Записываем ключ в 32-битных ветвях
  82.        
  83.         Ret_1 = WriteKey(badRoot, "", Key2099, False)
  84.        
  85.         'Записываем ключ в 64-битных ветвях
  86.        
  87.         Ret_2 = WriteKey(badRoot, "", Key2099, True)
  88.        
  89.         MsgBox "32-битная ветка - " & IIf(Ret_1, "Успех.", "Ошибка.") & vbCrLf & _
  90.                "64-битная ветка - " & IIf(Ret_2, "Успех.", "Ошибка.")
  91. end sub
  92.  
  93.  
  94. 'Самоэлевация прав программы
  95.  
  96. Private Sub Form_Initialize()
  97.     'Exit Sub 'Временно, пока не скомпилирую проект
  98.    With CreateObject("WScript.Shell")
  99.         On Error Resume Next
  100.         .RegWrite "HKLM\isElevated", "", "REG_SZ"
  101.         If Err <> 0 Then
  102.             CreateObject("Shell.Application").ShellExecute App.Path & "\" & App.EXEName & ".exe", "1", "", "runas", 1
  103.             End
  104.           Else
  105.             .RegDelete "HKLM\isElevated"
  106.         End If
  107.     End With
  108. End Sub
  109.  
  110.  
  111.  
  112. Private Function GetMainKeyHandle(MainKeyName As String) As Long 'Получить хендл главного улья
  113.    On Error Resume Next
  114.     Select Case MainKeyName
  115.            Case "HKEY_CLASSES_ROOT"
  116.                 GetMainKeyHandle = HKEY_CLASSES_ROOT
  117.            Case "HKEY_CURRENT_USER"
  118.                 GetMainKeyHandle = HKEY_CURRENT_USER
  119.            Case "HKEY_LOCAL_MACHINE"
  120.                 GetMainKeyHandle = HKEY_LOCAL_MACHINE
  121.            Case "HKEY_USERS"
  122.                 GetMainKeyHandle = HKEY_USERS
  123.            Case "HKEY_PERFORMANCE_DATA"
  124.                 GetMainKeyHandle = HKEY_PERFORMANCE_DATA
  125.            Case "HKEY_CURRENT_CONFIG"
  126.                 GetMainKeyHandle = HKEY_CURRENT_CONFIG
  127.            Case "HKEY_DYN_DATA"
  128.                 GetMainKeyHandle = HKEY_DYN_DATA
  129.     End Select
  130. End Function
  131.  
  132.  
  133. Private Function WriteKey(rPath$, ParamName, ParamValue, Optional is64Node As Boolean = False)
  134.  
  135.         'Функция записывает значение в реестр.
  136.        'Возвращает результат выполнения API-функции RegSetValueEx
  137.        'Умеет использовать Registry Redirector SybSystem (в 64 или 32-битную ветку записывать данные)
  138.  
  139.         Dim Ret_1&, Ret_2&, sSubKey$, Hive$, hSubKey&, regAccess&
  140.        
  141.         Hive = Split(rPath, "\")(0)
  142.         sSubKey = IIf(Len(Hive) = Len(rPath), "", Replace(rPath, Hive & "\", ""))
  143.        
  144.         If is64Node Then
  145.             regAccess = KEY_QUERY_VALUE Or KEY_WRITE Or KEY_WOW64_64KEY
  146.         Else
  147.             regAccess = KEY_QUERY_VALUE Or KEY_WRITE Or KEY_WOW64_32KEY
  148.         End If
  149.        
  150.         Ret_1 = RegOpenKeyEx(GetMainKeyHandle(Hive), sSubKey, 0&, regAccess, hSubKey)
  151.  
  152.         Ret_2 = RegSetValueEx(hSubKey, ParamName, 0, RegTypes.RegSZ, ParamValue, Len(ParamValue) + 1)
  153.        
  154.         RegCloseKey hSubKey
  155.    
  156.         WriteKey = Ret_2
  157.  
  158. End Function

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

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

8   голосов , оценка 3.875 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы