Форум программистов, компьютерный форум, киберфорум
Dragokas
Войти
Регистрация
Восстановить пароль
Рейтинг: 4.50. Голосов: 2.

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

Запись от Dragokas размещена 12.08.2012 в 05:56
Обновил(-а) Dragokas 21.08.2012 в 21:46

Проведем эксперимент, если Вы владелец 64-разрядной версии ОС Windows:

1. Откройте стандартный поиск, или проводник (если ver. OS > XP).
Пишем в строке поиска MSG.exe
Результат: найден в папке windows\system32
2. Запускаем любой 32-битный файловый менеджер (например, Total Commander)
Можем просто пролистать файлы в папке System32,
а можем указать во встроенном поиске (ALT+F7) MSG.exe
Результат: найдено 0 файлов. Вот так сюрприз.

Кроме того, попытавшись сделать тоже самое
средствами любимого Visual Basic,

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

мы получим также нулевой результат.

На эту удочку я недавно попался при отладке Batch-сценария.
Виновником оказался так называемый механизм перенаправления файловых запросов в 64-разрядной версии ОС Windows (File System Redirector), о котором рассказывает Microsoft.

То есть на самом деле запросы 32-битных приложений при попытке обратится к системной директории System32
файловая система автоматически переадресовывает в папку SysWOW64.
Почему так сделано, можно почитать здесь.

Но как же нам обойти систему виртуализации.
Вот реализация на VB принципа, указанного в статье MS:

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

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
Option Explicit
 
Sub System32file_Exists()
Dim exe As String
 
exe = Environ("windir") & "\system32\msg.exe"
exe = Replace(exe, "system32", "Sysnative", , vbTextCompare)
 
If Dir$(exe, vbReadOnly Or vbSystem Or vbHidden) <> vbNullString Then
    MsgBox exe & " is Exists!"
End If
End Sub
Недостатки способа № 1:
1. Относительная небезопасность: реактивацию перенаправления ФС нужно сделать как можно быстрее,
чтобы не прервать работу c 64-битными библиотеками в этом потоке.
2. Еще есть информация о предупреждении UAC при попытке снять режим File System Redirection.
Запуск примера на ОС Win 7 x64 Ultimate с максимальным уровнем UAC показал, что защита молчит во время этой манипуляции.
3. Также данная API-функция будет работать только на 64-разрядной версии ОС,
поэтому разрядность тоже
нужно проверять.

Проверка разрядности ОС. Вот пару вариантов от меня:

1. Проверяем наличие системной папки с использованием переадресации через тот самый алиас "Sysnative".
Visual Basic
1
2
3
4
Public Function Is64system() As Boolean
On Error Resume Next
Is64system = GetAttr(Environ("windir") & "\Sysnative") And vbDirectory
End Function
2. Через WSH читаем переменные среды окружения.
Visual Basic
1
2
3
4
5
6
7
8
9
10
Public Function Is64system() As Boolean
On Error Resume Next 'PROCESSOR_ARCHITEW6432 on x32 is NOT DEFINED
Dim WshShell As Object
Set WshShell = CreateObject("WScript.Shell")
If WshShell.Environment("PROCESS")("PROCESSOR_ARCHITECTURE") = "AMD64" Or _
   WshShell.Environment("PROCESS")("PROCESSOR_ARCHITEW6432") = "AMD64" Then
    Is64system = True
End If
Set WshShell = Nothing
End Function


Стоит добавить, что подобная ситуация также касается ветки реестра HKLM\Software\Wow6432Node
Для обхода этого также существует специальный алиас.

Не по теме:

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


Комментарии?
Вложения
Тип файла: xls File_system_Redirector_bypass.XLS.xls (44.5 Кб, 607 просмотров)
Тип файла: zip FSRedirector_bypass_VB.zip (2.6 Кб, 466 просмотров)
Размещено в Без категории
Показов 15821 Комментарии 4
Всего комментариев 4
Комментарии
  1. Старый комментарий
    Аватар для Dragokas

    Обсуждение

    Тема обсуждается здесь:
    https://www.cyberforum.ru/visu... 36329.html
    Запись от Dragokas размещена 12.08.2012 в 06:01 Dragokas вне форума
  2. Старый комментарий
    Аватар для alex_x_x
    в майкрософт изобрели симлинки? я просто не пойму отличий (и да, знаю, что в ntfs они также есть)
    Запись от alex_x_x размещена 15.08.2012 в 02:46 alex_x_x вне форума
  3. Старый комментарий
    Аватар для Dragokas
    Да, именно в NTFS.
    Симлинки - это папки, которые сами по себе не содержат файлов или папок,
    а (в отличие от темы данной статьи - безусловно) переадресовуют запросы в другую папку.
    Смысл их в том, чтобы обеспечить совместимость программ, написанных под старые версии ОС, с новым расположением системных директорий (переменных среды).
    Более подробно о:
    • симлинках и точках повторной обработки
    • способах их создания
    • исходниках С++ для работы с ними
    можете почитать здесь: http://hex.pp.ua/ntfs.php
    Запись от Dragokas размещена 16.08.2012 в 15:44 Dragokas вне форума
  4. Старый комментарий
    Аватар для alex_x_x
    Цитата:
    Сообщение от Dragokas Просмотреть комментарий
    Да, именно в NTFS.
    Симлинки - это папки, которые сами по себе не содержат файлов или папок,
    а (в отличие от темы данной статьи - безусловно) переадресовуют запросы в другую папку.
    Смысл их в том, чтобы обеспечить совместимость программ, написанных под старые версии ОС, с новым расположением системных директорий (переменных среды).
    Более подробно о:
    • симлинках и точках повторной обработки
    • способах их создания
    • исходниках С++ для работы с ними
    можете почитать здесь: http://hex.pp.ua/ntfs.php
    вообще - симлинки могут быть и на файлы (может быть в ntfs есть ограничение только на директории)

    Но я понял мотивацию - адресация условная и не зависит от поддержки файловой системой линков
    Запись от alex_x_x размещена 16.08.2012 в 22:56 alex_x_x вне форума
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru