Глубины ввода-вывода Windows (часть 6, финал) — фильтры и минифильтры: почему Procmon и антивирус могут перехватывать I/O
· Го Комура · Windows, Win32, I/O, Минифильтр, Ядро, Драйвер устройства, Безопасность, Расследование ошибок
Финал серии «Глубины ввода-вывода Windows».
С тех пор как в части 1 на схеме стека устройств появился ящик «фильтры файловой системы (антивирус, шифрование, Procmon и т. п.)», те, кто встаёт посередине, не раз выходили на сцену: почему Procmon записывает каждый I/O (часть 1); «доступ к файлам медленный только в этой среде» (часть 2); точка повторного разбора, из-за которой OneDrive начинает скачивание в момент открытия файла (часть 5). В этой части наконец прямо берём сам механизм вставки — драйверы фильтра файловой системы и минифильтры — и закрываем все нити, которые серия оставляла висеть.
1. Сначала вывод
- «Встать в I/O» — официальная точка расширения ОС. Фильтр файловой системы может видеть, переписывать, отклонять и обрабатывать вместо файловой системы запросы к файловой системе (глава 2).1
- Нынешний стандарт — минифильтр. Чтобы закрыть проблемы устаревшего способа прямой вставки в стек устройств (неопределённый порядок, нельзя выгрузить), поколение сменилось на регистрацию обратных вызовов в диспетчере фильтров (FltMgr), который поставляется с Windows (глава 2).23
- Движение — обратные вызовы pre/post. До и после каждой операции их зовут в порядке регистрации = порядке высот. Пропустить, завершить, отклонить, переписать — «выбор драйвера» из части 1 работает как есть (глава 3).2
- Высота (altitude) задаёт порядок. По типам назначения выделены диапазоны номеров (Activity Monitor 360000–389999, Anti-Virus 320000–329999 и т. п.), у каждого экземпляра, присоединённого к тому, уникальный номер (глава 4).45
- Жителей своего ПК видно через
fltmc. Procmon (только пока запущен), антивирус, облачный фильтр OneDrive — все стоят здесь (глава 5). - Исключение антивируса — «пропуск сканирования самого этого продукта», на другие минифильтры не влияет. Исключение — обмен: защита слабеет; для томов разработки есть более безопасный выбор — Dev Drive (асинхронное сканирование) (глава 6).67
- Расследование «медленно только в этой среде» начинается со столбца Duration в Procmon и сравнения конфигурации
fltmc(глава 7).
Карта знаний этой статьи
Нынешний стандарт фильтра файловой системы — минифильтр: в отличие от устаревшего фильтра, который напрямую кладёт объект устройства на стек устройств, он регистрирует обратные вызовы pre/post в диспетчере фильтров (FltMgr), который поставляется с Windows. Порядок вызова однозначно задаёт высота, которую назначает и ведёт Microsoft; фактическую конфигурацию наблюдают командой fltmc. Антивирус, Procmon и облачная синхронизация OneDrive — жители того же механизма; исключение пропускает только сканирование самого этого продукта и несёт обмен — защита слабеет; для томов разработки есть более безопасная альтернатива — Dev Drive.
flowchart LR
accTitle: Карта знаний фильтров и минифильтров
accDescr: Рисунок, показывающий связи драйвера фильтра файловой системы, смены поколения с устаревшего фильтра на минифильтр, диспетчера фильтров (FltMgr), обратных вызовов pre/post, высоты и группы порядка загрузки, наблюдения через fltmc, антивирусного минифильтра и исключений / Dev Drive, механизма, которым Procmon как минифильтр записывает весь I/O
minifilter["минифильтр"]
filter_manager["диспетчер фильтров (FltMgr)"]
legacy_filter_driver["устаревший фильтр"]
filesystem_filter_driver["драйвер фильтра файловой системы"]
device_stack["стек устройств"]
load_order_instability["нестабильность порядка загрузки"]
minifilter_callback["обратные вызовы pre/post"]
altitude["высота (altitude)"]
load_order_group["группа порядка загрузки"]
fltmc["fltmc"]
altitude_request["заявка на высоту"]
procmon["Process Monitor (procmon.exe)"]
antivirus_minifilter["антивирусный минифильтр"]
cloud_filter["фильтр облачных файлов (cldflt)"]
onedrive_files_on_demand["Files On-Demand OneDrive"]
fast_io["Fast I/O"]
scan_performance_cost["стоимость производительности из-за сканирования"]
exclusion_setting["исключение (исключение папки)"]
reduced_protection["снижение уровня защиты"]
dev_drive["Dev Drive"]
frame["кадр FltMgr"]
driver_object["объект драйвера"]
legacy_filter_driver -->|"реализует"| filesystem_filter_driver
minifilter -->|"реализует"| filesystem_filter_driver
minifilter -->|"преемник"| legacy_filter_driver
legacy_filter_driver -->|"требует"| device_stack
legacy_filter_driver -->|"может вызвать"| load_order_instability
minifilter -.->|"предотвращает"| load_order_instability
minifilter -->|"требует"| filter_manager
filter_manager -->|"использует"| minifilter_callback
minifilter -->|"использует"| minifilter_callback
minifilter -->|"настраивается"| altitude
altitude -->|"настраивается"| load_order_group
altitude -->|"проверяется"| fltmc
altitude -.->|"требует"| altitude_request
altitude_request -->|"должен предшествовать"| minifilter
minifilter -->|"проверяется"| fltmc
legacy_filter_driver -->|"проверяется"| fltmc
procmon -->|"использует"| minifilter
procmon -->|"использует"| minifilter_callback
antivirus_minifilter -->|"использует"| minifilter_callback
antivirus_minifilter -->|"настраивается"| altitude
cloud_filter -->|"автоматизирует"| onedrive_files_on_demand
minifilter -.->|"использует"| fast_io
antivirus_minifilter -.->|"может вызвать"| scan_performance_cost
exclusion_setting -->|"снижает"| scan_performance_cost
exclusion_setting -->|"может вызвать"| reduced_protection
antivirus_minifilter -->|"настраивается"| exclusion_setting
dev_drive -->|"снижает"| scan_performance_cost
dev_drive -->|"снижает"| reduced_protection
antivirus_minifilter -->|"рекомендуется для"| dev_drive
filter_manager -->|"использует"| frame
frame -->|"проверяется"| fltmc
legacy_filter_driver -->|"использует"| driver_object
minifilter -->|"использует"| driver_object
filter_manager -->|"требует"| device_stack
filter_manager -->|"использует"| driver_object
На схеме сплошная линия обозначает отношение, которое выполняется всегда, а пунктирная — условное отношение (условия указаны в пояснении к каждому отношению на странице сведений). Полный список отношений (всего 35, с доказательствами и степенью уверенности) и определения основных понятий собраны на странице сведений карты знаний (на японском). Данные: JSON-LD / Turtle
2. История тех, кто встаёт посередине — от устаревшего фильтра к FltMgr
Драйвер фильтра файловой системы — драйвер, который может перехватить запросы, идущие к файловой системе (или к тому под ней). Записывать, наблюдать, менять содержимое, вплоть до отклонения и подмены обработки — основание антивируса, шифрования, резервного копирования, иерархической памяти.1
Старый способ реализации (устаревший фильтр) напрямую клал свой объект устройства на стек устройств из части 1. По устройству прямолинейно, на практике проблем полно: порядок наложения зависит от порядка загрузки и его трудно гарантировать; снялся раз — безопасно не выйти (нельзя выгрузить); питательная среда взаимных сбоев фильтров.
Поэтому Windows ввела диспетчер фильтров (FltMgr). Сам FltMgr как штатный фильтр ОС стоит на стеке, а отдельные функции фильтра как минифильтры регистрируют обратные вызовы в FltMgr.2
flowchart TB
subgraph OLD["Устаревший способ"]
L1["Устаревший фильтр A"]
L2["Устаревший фильтр B"]
LFS1["Файловая система"]
L1 --> L2
L2 --> LFS1
NOTE1["Порядок — как загрузились<br/>безопасной выгрузки нет"]
end
subgraph NEW["Способ минифильтра (нынешний стандарт)"]
FM["Диспетчер фильтров (FltMgr)<br/>поставляется с ОС. На стеке стоит только он"]
M1["Минифильтр A (высота больше)"]
M2["Минифильтр B (высота меньше)"]
LFS2["Файловая система"]
FM -. "регистрация обратного вызова" .- M1
FM -. "регистрация обратного вызова" .- M2
FM --> LFS2
NOTE2["Порядок однозначно задаёт высота<br/>загрузка в любой момент<br/>(поддерживающие фильтры можно и выгрузить)"]
end
Рис. 1: Смена поколения. Не «класть» на стек, а «регистрировать» в FltMgr.
Плюсы способа минифильтра официально перечислены: загружать когда угодно, управлять порядком, а фильтр с обратным вызовом выгрузки можно снять и на ходу (не реализовавший / отказавший — снять нельзя).3 Для сосуществования с устаревшими фильтрами FltMgr может стоять в нескольких местах стека как несколько «кадров» (frames); минифильтр после выгрузки и повторной загрузки возвращается на то же место (ту же высоту).2 Современные антивирус, наблюдение, синхронизация — почти все такие минифильтры.
3. Движение минифильтра — обратные вызовы pre/post
Минифильтр объявляет FltMgr, «какими операциями интересуется». Например, только IRP_MJ_CREATE (открыть) и IRP_MJ_WRITE (писать). Тогда при каждом таком потоке зовут до операции (обратный вызов pre) и после операции (обратный вызов post).
sequenceDiagram
participant IOM as Диспетчер I/O
participant FM as FltMgr
participant A as Минифильтр A<br/>(высота больше)
participant B as Минифильтр B<br/>(высота меньше)
participant FS as NTFS
IOM->>FM: Запрос (IRP_MJ_CREATE и т. п. Мир части 1)
FM->>A: Обратный вызов pre
FM->>B: Обратный вызов pre
FM->>FS: К файловой системе
FS-->>FM: Результат обработки
FM-->>B: Обратный вызов post
FM-->>A: Обратный вызов post
FM-->>IOM: Завершение (к потоку завершения части 1)
Рис. 2: Обратные вызовы pre/post. Туда — по убыванию высоты, обратно — в обратном порядке.
Что можно в каждом обратном вызове. Та же конструкция, что «три выбора драйвера» в п. 4.3 части 1, только более безопасным API.
flowchart TB
PRE["Вызван обратный вызов pre"]
Q{"Что делать с этой операцией"}
PASS["Пропустить<br/>(если post не нужен — объявить и это)"]
DENY["Отклонить<br/>сразу вернуть отказ в доступе и т. п.<br/>пример: вирус найден, запись запрещена"]
DONE["Завершить самому<br/>пример: облачный фильтр<br/>достаёт содержимое и подставляет"]
MOD["Поправить параметры или содержимое и пустить дальше<br/>пример: фильтр шифрования"]
PRE --> Q
Q --> PASS
Q --> DENY
Q --> DONE
Q --> MOD
Рис. 3: Выбор в обратном вызове pre. «Смотреть, остановить, взять на себя, переписать» — всё официально.
И здесь закрывается домашнее задание части 4: минифильтр присутствует и на Fast I/O (короткий путь без IRP). FltMgr проводит механизм обратных вызовов и по пути Fast I/O, поэтому «ушли коротким путём — и не видно», как в эпоху устаревших фильтров, не бывает. Строки FASTIO_ в журнале Procmon — следствие этой позиции.
4. Высота — «отметка» задаёт порядок
Когда нескольким фильтрам интересна одна операция, кто смотрит первым — серьёзный вопрос. Если антивирус смотрит после шифрования, придётся сканировать шифротекст; средство наблюдения должно быть выше всех, иначе целое не увидит.
Этот порядок задаёт высота (altitude). По типу фильтра определены группы порядка загрузки и диапазоны номеров. Точнее, единица, которой дают высоту, — не драйвер целиком, а «экземпляр» минифильтра, присоединяемый к тому. Номер уникален; чем больше, тем выше на стеке (ближе к приложению).4 Один драйвер может иметь несколько определений экземпляров и появляться на разных высотах — поэтому список fltmc instances идёт по экземплярам.
flowchart TB
APP["Ближе к приложению (число больше)"]
G1["FSFilter Activity Monitor: 360000–389999<br/>наблюдение и запись I/O (Procmon здесь)"]
G2["FSFilter Undelete: 340000–349999<br/>восстановление удалённых файлов"]
G3["FSFilter Anti-Virus: 320000–329999<br/>обнаружение и удаление вирусов"]
G4["FSFilter Replication: 300000–309999<br/>репликация на удалённую сторону"]
G5["FSFilter Continuous Backup: 280000–289999<br/>непрерывное резервное копирование"]
G6["Ещё ниже: Content Screener /<br/>Quota Management / System Recovery /<br/>полосы шифрования, сжатия и др."]
FS["Ближе к файловой системе (число меньше)"]
APP --> G1 --> G2 --> G3 --> G4 --> G5 --> G6 --> FS
Рис. 4: Диапазоны высот (выдержка). У каждого назначения своя «отметка, на которой стоять».
Важно: эти номера назначает и ведёт Microsoft.5 Вендор не называет себя сам — подаёт заявку и получает. Поэтому на любом ПК держится порядок «наблюдение выше антивируса, антивирус выше шифрования». Это и был ответ на «лотерею порядка загрузки» эпохи устаревших фильтров.
Куда подавать заявку, если минифильтр делаете сами. Для разработчика — только следующий шаг. Высоту запрашивают по процедуре Request a Filter Altitude Identifier: письмо ASCII на английском на fsfcomm@microsoft.com с темой «Filter altitude request». Нужно заполнить всё: название компании, контакт (не личный, а долгоживущий корпоративный псевдоним), имя продукта, URL продукта, описание фильтра, имя файла драйвера, тип фильтра, тип запуска, желаемую группу порядка загрузки и желаемую высоту. Явно сказано: закладывать 30 рабочих дней, отдельного «срочного» окна нет, назначенный номер может отличаться от желаемого.8 Если у компании уже есть целочисленная высота в той же группе порядка загрузки, дробное значение от этого номера (например 325000.3) можно выбрать самим и достаточно сообщить письмом после факта.8
5. Представление жителей — свой ПК глазами fltmc
Теории хватит, смотрим живое. В командной строке с правами администратора:
:: Список зарегистрированных минифильтров (с высотой)
fltmc
:: Какой фильтр на каком томе
fltmc instances
:: Со стороны томов
fltmc volumes
fltmc без аргументов даёт тот же список, что fltmc filters. Вывод — четыре столбца; тот же формат есть в документации Microsoft.9
C:\Windows\system32>fltmc
Filter Name Num Instances Altitude Frame
------------------------------ ------------- ------------ -----
bindflt 1 409800 0
cldflt 1 409500 0
WdFilter 4 328010 0
luafv 1 135000 0
FileInfo 4 45000 0
Выше — выдержка для объяснения. Состав лиц и число экземпляров зависят от среды, но числа высот — фиксированные значения, назначенные Microsoft, их можно сверить с открытым списком из главы 4.
Смысл столбцов.
| Столбец | Смысл |
|---|---|
| Filter Name | Имя фильтра (драйвера) |
| Num Instances | К скольким томам присоединён (число экземпляров главы 4) |
| Altitude | Высота. Чем больше, тем ближе к приложению |
| Frame | Номер кадра FltMgr. Если здесь <Legacy> — живёт устаревший фильтр, который FltMgr не использует.9 |
Уже по этим пяти строкам видно: bindflt и cldflt в самой верхней полосе FSFilter Top (400000–409999), WdFilter в Anti-Virus (320000–329999), FileInfo в самой нижней FSFilter Bottom (40000–49999). Картина главы 4 «у каждого назначения своя отметка» читается прямо по числам. И если запустить Procmon и снова выполнить fltmc, в полосе Activity Monitor (360000–389999) появится ещё одна строка, начинающаяся с PROCMON.
Состав лиц зависит от среды, но типичные жители — постоянные герои этой серии.
WdFilter— минифильтр Microsoft Defender. Стоит в полосе Anti-Virus. На многих ПК — застава, через которую проходит каждый файловый I/O.cldflt— фильтр облачных файлов. Исполнительная часть Files On-Demand OneDrive: когда открывают точку повторного разбора (заполнитель) из части 5, готовит содержимое.10PROCMON24(и т. п.) — временный минифильтр полосы Activity Monitor, который появляется только пока запущен Process Monitor. Вот разгадка, почему Procmon видит весь I/O.11 Сравнитеfltmcдо и после запуска.- Прочее: ПО резервного копирования, продукты шифрования (защита от утечек), EDR, виртуализованное хранилище — чем «боевее» ПК, тем жителей больше.
Инструмент Procmon, которым пользовались с части 1, в финале видно снаружи ящика: «наблюдатель тоже житель того же механизма, что объект наблюдения» — аккуратный круг.
6. Где антивирус тратит время
Самое большое практическое влияние фильтров — стоимость антивирусного сканирования. Где возникает время — на схеме (детали зависят от продукта; ниже типичная форма).
sequenceDiagram
participant App as Приложение
participant AV as Минифильтр AV
participant FS as NTFS
App->>AV: Открыть файл
Note over AV: pre-create: предварительное решение по пути и политике
AV->>FS: Пропустить (выполнить открытие)
FS-->>AV: Открытие удалось (post-create)
Note over AV: Если файл ещё не сканировали,<br/>здесь сканируют содержимое<br/>и при проблеме отзывают открытие<br/>── главная причина медленного открытия
AV-->>App: Если проблем нет — возвращается дескриптор
App->>AV: Запись / закрытие
Note over AV: Изменённый файл снова<br/>идёт в сканирование, например при закрытии
Note over App,FS: На массе мелких файлов (промежуточные продукты сборки и т. п.)<br/>этот кругооборот складывается на число файлов
Рис. 5: Где возникает стоимость сканирования. На один файл мало, на десятки тысяч — становится доминирующим.
Отсюда точно понимаются две практические темы.
Технический смысл исключения. На I/O по пути из списка исключений сканирование фильтра пропускается. Фильтр со стека не исчезает; ближе к правде: решение «не проверять» принимается раньше. И ещё одно важное ограничение: исключение действует только на фильтр того продукта, у которого эта настройка. Исключение Microsoft Defender меняет сканирование WdFilter и никак не влияет на соседние минифильтры (чужой антивирус, EDR, резервное копирование, шифрование). «Поставил исключение — всё равно медленно» — подозревайте, что время ест другой житель (сравнение fltmc главы 7). Эффект большой, но исключение гарантированно ослабляет защиту в этом месте. Документация Microsoft многократно предупреждает: исключение снижает защиту, определять минимально и вместе с оценкой риска.6 Практика ложных срабатываний и влияния на производительность — в «Если ваше Windows-приложение приняли за вирус».
Новый ответ — Dev Drive. Том, спроектированный под нагрузку разработки (масса мелких файлов); Microsoft Defender работает в режиме производительности (асинхронное сканирование). Позиционируется как более безопасная альтернатива исключению папки: по умолчанию дополнительные фильтры не присоединяются, но есть и жёсткое предупреждение не эксплуатировать том совсем без фильтров.7 Нынешняя рекомендация Microsoft на «хочу быстрее собирать, но исключение страшно».
7. Порядок расследования «медленно только в этой среде»
Инструменты, накопленные серией, в конце складываем в одну процедуру.
flowchart TB
S["Симптом: то же приложение,<br/>файловый доступ медленный только в одной среде"]
P1["Смотреть столбец Duration в Procmon<br/>на какую операцию (IRP_MJ_CREATE? WRITE?)<br/>уходит время"]
Q1{"Одна операция равномерно медленная?"}
F1["Сравнить fltmc instances с быстрой средой<br/>разница конфигурации фильтров"]
Q2{"Виноват фильтр из разницы?"}
A1["Исключение (с оценкой риска),<br/>Dev Drive, разговор с вендором"]
A2["Подозревать не фильтры:<br/>кэш (часть 4), фрагментация и MFT (часть 5),<br/>сетевая цель (UNC), само устройство"]
S --> P1 --> Q1
Q1 -->|"да"| F1 --> Q2
Q2 -->|"да"| A1
Q2 -->|"нет"| A2
Q1 -->|"нет (спорадически)"| A2
Рис. 6: Отделение медленности из-за фильтров. Ключ — «время на операцию» и «разница конфигурации фильтров между средами».
Два пункта. Первое: у Procmon есть длительность каждой операции (Duration). Разложить «медленно» на «какая операция медленная» — половина поиска виновного. Второе: разница сред часто есть разница конфигурации фильтров. Машина разработки и боевая, свой ПК и ПК заказчика — положить рядом вывод fltmc, и кандидаты уже видны.
Первые три хода, если Procmon ещё не трогали. Столбец Duration по умолчанию не показан — чтобы здесь не остановиться, только операции.
- Запустить
Procmon.exeот имени администратора. - Options > Select Columns…, в списке столбцов отметить Duration.
- Filter > Filter… (Ctrl+L):
Process Name/is/ имя целевого exe /Include, нажать Add и затем OK (без Add условие не попадёт).
После этого щелчок по Duration сортирует, операции, которые едят время, собираются сверху. Для сводки по процессу и файлу есть ещё Tools > File Summary. Операции ProcMon в целом — в «Практическое руководство по Process Monitor (ProcMon)».
8. Финал серии — карта шести частей
Все ящики карты части 1 открыты. Целое — на одном листе.
flowchart TB
APP["Приложение<br/>ReadFile / WriteFile / async-await"]
API["Часть 2: синхронный и асинхронный I/O<br/>режим дескриптора и OVERLAPPED"]
IOCP["Часть 3: IOCP и пул потоков .NET<br/>приём завершения и выполнение продолжения"]
IOM["Часть 1: диспетчер I/O и IRP<br/>разрешение имён, три объекта, стек устройств"]
FLT["Часть 6: фильтры и минифильтры<br/>FltMgr, высота, pre/post"]
CACHE["Часть 4: диспетчер кэша<br/>представление 256 КБ, lazy writer, Fast I/O<br/>(работает в связке с NTFS)"]
NTFS["Часть 5: NTFS<br/>MFT, потоки, связи, два журнала"]
HW["Стек хранилища и устройство"]
APP --> API
API --> IOM
IOCP -. "завершение возвращается сюда" .-> APP
IOM --> FLT
FLT --> NTFS
NTFS -. "I/O с кэшем — связка<br/>(файловая система вызывает функции кэша)" .- CACHE
NTFS --> HW
HW -. "прерывание → завершение (часть 1)" .-> IOCP
Рис. 7: Карта всей серии. Диспетчер кэша — не «слой, через который проходят», а напарник файловой системы; при промахе кэша NTFS шлёт запрос в хранилище.
- Часть 1: общая картина — каждый обмен становится IRP
- Часть 2: синхронный / асинхронный — настоящий смысл OVERLAPPED
- Часть 3: IOCP — подвал async/await
- Часть 4: кэш — когда ваш WriteFile доходит до диска
- Часть 5: NTFS — файловая система через MFT
- Часть 6: фильтры и минифильтры (эта статья) — почему Procmon и антивирус могут перехватывать I/O
9. Итог — к финалу серии
Итог последней части.
- Вставка в I/O — официальная точка расширения ОС, нынешний стандарт — регистрация обратных вызовов в FltMgr (минифильтр). Порядок однозначно задаёт высота, номера назначает и ведёт Microsoft.245
- Движение — обратные вызовы pre/post. Можно пропустить, отклонить, взять на себя, переписать; присутствуют и на Fast I/O. Procmon, Defender, OneDrive — жители того же механизма.11110
- Исключение = пропуск сканирования, обмен с защитой. Для томов разработки есть более безопасный выбор — Dev Drive (асинхронное сканирование).67
- «Медленно только в этой среде» отделяют Duration в Procmon и разницей конфигурации
fltmc— инструменты серии сами становятся процедурой расследования.
А вывод всей серии одной строкой такой: I/O Windows устроен единообразно — назначение выбирается в пространстве имён, запрос становится пакетом (IRP) и течёт между слоями, каждый слой может «смотреть, принять на хранение, взять на себя». Под одной строкой File.ReadAllText каждый раз движется эта конструкция шести частей. Вместо заучивания поведения API — выводить «так и должно быть» из этой карты. Это сила, которую хотелось отдать серией. Спасибо, что прошли длинный путь.
Похожие статьи
- Глубины ввода-вывода Windows (часть 1) — каждый обмен становится IRP: общая картина системы I/O
- Глубины ввода-вывода Windows (часть 4) — диспетчер кэша: когда ваш WriteFile доходит до диска
- Глубины ввода-вывода Windows (часть 5) — внутреннее устройство NTFS: файловая система через MFT
- Практическое руководство по Process Monitor (ProcMon) — как за 10 минут выяснить, почему «настройки не читаются» или возникает ACCESS DENIED
- Если ваше Windows-приложение приняли за вирус — как реагировать на ложные срабатывания Microsoft Defender и жить с влиянием на производительность
- Практика Process Explorer / Handle / VMMap — зависание, утечка и «файл занят» по состоянию прямо сейчас
- Минимальный чек-лист безопасности при разработке Windows-приложений
Смежные области консультирования
KomuraSoft LLC занимается расследованием проблем производительности и сбоев Windows-бизнес-приложений, в которые впутаны фильтры: «медленно только в одной среде», «средство безопасности мешает своему приложению».
- Разработка приложений для Windows
- Расследование ошибок и причин
- Технические консультации и ревью дизайна
- Связаться с нами
Справочные ссылки
-
Microsoft Learn, About file system filter drivers. О том, что драйвер фильтра файловой системы — необязательный драйвер, который может перехватывать (intercept) запросы к файловой системе или другому фильтру; о том, что перехват позволяет расширить или подменить функцию до передачи исходному адресату и даёт запись, наблюдение, изменение данных, предотвращение поведения; о том, что примеры фильтров — утилиты антивируса, программы шифрования, системы иерархической памяти. ↩ ↩2 ↩3
-
Microsoft Learn, Filter Manager Concepts. О том, что диспетчер фильтров (FltMgr) — драйвер режима ядра в составе Windows, который открывает функции, упрощающие разработку минифильтров; о том, что минифильтр может зарегистрировать обработку до и после операций I/O (обратные вызовы pre/post); о том, что ради сосуществования с устаревшими фильтрами FltMgr присоединяется в нескольких местах стека I/O как кадры; о том, что после выгрузки и повторной загрузки минифильтр возвращается на ту же высоту того же кадра. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Advantages of the Filter Manager Model. О преимуществах модели минифильтра относительно модели устаревшего фильтра: лучший контроль порядка загрузки фильтров; в отличие от устаревшего фильтра минифильтр можно загрузить в любой момент; возможность выгрузки; подключение к томам DAX и др. ↩ ↩2
-
Microsoft Learn, Load order groups and altitudes for minifilter drivers. О том, что для фильтров файловой системы определены группы порядка загрузки по назначению и каждой группе выделен диапазон высот; о том, что у каждого драйвера фильтра уникальный идентификатор высоты, задающий положение относительно других фильтров в стеке I/O; о примерах групп: FSFilter Activity Monitor (360000–389999, наблюдение и отчёт об I/O), FSFilter Undelete (340000–349999), FSFilter Anti-Virus (320000–329999, обнаружение и удаление вирусов во время файлового I/O), FSFilter Replication (300000–309999), FSFilter Continuous Backup (280000–289999). ↩ ↩2 ↩3
-
Microsoft Learn, Allocated altitudes. О том, что высоты минифильтров назначает и ведёт Microsoft и поддерживается открытый список уже назначенных высот; о том, что в списке WdFilter.sys указан как 328010 группы FSFilter Anti-Virus, cldflt.sys — как 409500 группы FSFilter Top. ↩ ↩2 ↩3
-
Microsoft Learn, Configure and validate exclusions for Microsoft Defender Antivirus. О том, что исключение Microsoft Defender выводит целевые файлы, папки и процессы из сканирования; о многократном предупреждении, что исключение снижает уровень защиты и его следует определять осторожно после оценки необходимости. ↩ ↩2 ↩3
-
Microsoft Learn, Set up a Dev Drive on Windows 11. О том, что Dev Drive — том, спроектированный под нагрузку разработки, и Microsoft Defender работает в режиме производительности (асинхронное сканирование); о позиционировании как безопасной альтернативы исключениям папок (secure alternative to folder exclusions) с учётом скорости и производительности; о том, что дополнительные фильтры по умолчанию к Dev Drive не присоединяются; о предупреждении, что эксплуатация без антивирусного фильтра — серьёзный риск безопасности. ↩ ↩2 ↩3
-
Microsoft Learn, Request a Filter Altitude Identifier. О том, что заявку на новую высоту фильтра подают письмом ASCII с темой «Filter altitude request» на fsfcomm@microsoft.com; о необходимости заполнить все поля: название компании, контактная почта (не личная, а долгоживущий корпоративный псевдоним), имя продукта, URL продукта, описание фильтра, имя файла фильтра, тип фильтра, тип запуска, желаемая группа порядка загрузки, желаемая высота; о том, что закладывать 30 рабочих дней и иного окна заявки нет; о том, что Microsoft может назначить высоту, отличную от желаемой; о том, что при уже имеющейся целочисленной высоте можно самим сделать дробную в той же группе и достаточно сообщить после факта. ↩ ↩2
-
Microsoft Learn, Blocking legacy file system filter drivers. О том, что
fltmc filtersиз командной строки с правами администратора выводит фильтры четырьмя столбцами «Filter Name / Num Instances / Altitude / Frame»; о том, что Frame<Legacy>— устаревший драйвер фильтра файловой системы без FltMgr, а у минифильтра в Frame стоит число (0 и т. п.). ↩ ↩2 -
Microsoft Learn, Cloud Files API. О том, что Cloud Files API (облачный фильтр) — основание движка синхронизации, который показывает облачные файлы локально как заполнители и при доступе достаёт содержимое (Files On-Demand OneDrive и т. п.). ↩ ↩2
-
Microsoft Learn, Process Monitor - Sysinternals. О том, что Process Monitor — продвинутый инструмент наблюдения, который в реальном времени показывает активность файловой системы, реестра и процессов/потоков (как в тексте, во время работы он наблюдается в списке fltmc как минифильтр). ↩ ↩2
Похожие статьи
Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.
Глубины ввода-вывода Windows (часть 5) — внутреннее устройство NTFS: файловая система через MFT
Часть 5 серии со схемами внутреннего устройства NTFS. MFT и записи файлов, несколько потоков данных (Zone.Identifier), жёсткие ссылки и и...
Глубины ввода-вывода Windows (часть 4) — диспетчер кэша: когда ваш WriteFile доходит до диска
Часть 4 серии со схемами диспетчера кэша Windows. Кэш как проекция файла, упреждающее чтение и отложенная запись, выбор между FlushFileBu...
Как правильно работать с токенами олицетворения в Windows — заимствование прав на уровне потока и безопасный откат
Разбираем токены олицетворения в Windows — токены доступа, первичные и потоковые токены, уровни олицетворения, RevertToSelf и WindowsIden...
Почему Windows стала такой, какая она есть: эволюция Windows глазами разработчика
Разбираем изменения от Windows 95 до Windows 11 не как визуальную хронологию, а с точки зрения разработчика Windows-приложений: совместим...
Глубины виртуализации Windows (часть 2) — память, которую не видит даже ядро: как работают VBS, HVCI и Credential Guard
На чистой установке на совместимом оборудовании VBS включена по умолчанию и с помощью гипервизора и SLAT создаёт изоляцию сильнее ядра. С...
Связанные темы
Эти страницы показывают тему статьи в более широком контексте услуг и решений.
Технические темы Windows
Раздел о разработке Windows, расследовании сбоев и использовании существующих активов.
Услуги по этой теме
Статья напрямую связана со следующими услугами.
Разработка приложений для Windows
Бизнес-приложения, интеграция оборудования и средства связи — от требований до разработки.
Частые вопросы
Вопросы, которые часто возникают при консультациях по теме статьи.
- Чем драйвер фильтра файловой системы отличается от минифильтра?
- Оба — «драйверы, которые перехватывают запросы I/O к файловой системе», но поколение способа перехвата разное. Старый способ — устаревший фильтр — напрямую клал свой объект устройства на стек устройств файловой системы: положение зависело от порядка загрузки и его трудно гарантировать, плюс после загрузки нельзя было безопасно выгрузить. Нынешний стандарт, минифильтр, регистрирует в диспетчере фильтров (FltMgr), который поставляется с Windows, обратные вызовы вида «вызови меня до и после этой операции». Положение однозначно задаётся числом — высотой (altitude), загружать можно в любой момент, а фильтр с обратным вызовом выгрузки можно снять и на ходу. Почти все современные фильтры — антивирус, шифрование, средства наблюдения, облачная синхронизация — реализованы как минифильтры.
- Почему антивирус может проверять каждое обращение к файлу?
- Потому что ОС официально даёт точку расширения именно для этого. Минифильтр регистрирует в диспетчере фильтров код, который вызывают до (обратный вызов pre) и после (обратный вызов post) операций вроде открытия, чтения или записи файла. Антивирусный фильтр стоит в диапазоне высот, отведённом под Anti-Virus (320000–329999), и может, например, сразу после успешного открытия (post-create) просканировать содержимое и при проблеме отозвать это открытие, чтобы доступ не удался. Как в части 1 этой серии, каждый файловый I/O идёт по стеку устройств, поэтому логика такая: встать в фиксированной точке на этом пути — и можно проверить каждое обращение. Это не хак, а механизм, встроенный в устройство ОС.
- Что технически делает исключение антивируса (исключение папки)?
- Для I/O по пути, совпавшему со списком исключений, фильтр этого продукта пропускает сканирование, которое иначе выполнил бы. Сам фильтр со стека не исчезает; ближе к правде: решение «этот путь не проверять» принимается раньше. Важное ограничение: исключение действует только для продукта, у которого эта настройка. Например, исключение Microsoft Defender меняет сканирование фильтра Defender (WdFilter) и не влияет на поведение соседних минифильтров — чужой антивирус, EDR, резервное копирование и т. п. Каждому продукту нужно своё исключение, и когда «добавил исключение, а всё равно медленно», причиной может быть другой фильтр. И как многократно предупреждает документация Microsoft, исключение ослабляет защиту в этом месте, поэтому его держат минимальным вместе с оценкой риска. Для разработки стоит рассмотреть и Dev Drive (режим производительности, то есть асинхронное сканирование) — безопасную альтернативу исключениям папок.
- Как Process Monitor записывает каждый I/O?
- Потому что сам Procmon при запуске регистрируется в диспетчере фильтров как минифильтр диапазона высот Activity Monitor. Если из командной строки с правами администратора выполнить fltmc, пока Procmon запущен, в списке появится фильтр с именем, начинающимся с PROCMON. Как минифильтр он присутствует на pre и post операций I/O всех томов и без пропусков записывает, какой процесс какую операцию над каким файлом сделал. Термины IRP и Fast I/O, которые шли через всю серию, прямо видны в отображении Procmon именно потому, что он наблюдает с позиции на самом пути I/O.
- Когда сборка на машине разработки медленная, стоит ли подозревать фильтры?
- Подозревать очень стоит. Сборка — масса создания, чтения, записи и удаления огромного числа мелких файлов, и каждый становится целью проверки фильтров (особенно антивирусного сканирования) — это нагрузка, на которой стоимость фильтров проявляется сильнее всего. Базовый порядок расследования: по столбцу Duration в Procmon понять, на какую операцию уходит время, и сравнить разницу конфигурации фильтров между средами через fltmc instances. Как мера — исключение после оценки риска, плюс Dev Drive, спроектированный специально для томов разработки. На Dev Drive антивирус работает в режиме производительности (асинхронное сканирование), и Microsoft ставит это как более безопасную альтернативу исключению.
Об авторе
Страница с профилем автора статьи.
Го Комура
Представитель KomuraSoft LLC
Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.