Serie «Le profondità dell’I/O di Windows», puntata finale.
Da quando nel diagramma dello stack di dispositivi della 1ª puntata si è disegnato un riquadro «filtri del file system (antivirus, cifratura, Procmon ecc.)», in questa serie quelli che si mettono in mezzo sono comparsi più volte. Perché Procmon può registrare tutto l’I/O (1ª puntata). «L’accesso ai file è lento solo in quell’ambiente» (2ª puntata). Il reparse point per cui OneDrive inizia il download nell’istante in cui si apre (5ª puntata). Questa volta, finalmente, si affronta di petto quel meccanismo che si mette in mezzo — i driver filtro del file system e i minifilter — e si recuperano tutti i fili della serie.
1. Prima di tutto, la conclusione
- «Intercettare l’I/O» è un punto di estensione riconosciuto dal sistema operativo. Un filtro del file system può vedere, riscrivere, rifiutare e trattare al posto del file system una richiesta verso il file system (capitolo 2).1
- Lo standard attuale è il minifilter. Per risolvere i problemi del modo legacy che intercettava direttamente lo stack di dispositivi (ordine non determinato, impossibilità di scaricare), c’è stato un ricambio generazionale verso un modo che registra callback presso il Filter Manager (FltMgr) in dotazione a Windows (capitolo 2).23
- Il movimento è callback pre/post. Prima e dopo ciascuna operazione vengono chiamati in ordine di registrazione = ordine di altitudine. Lasciar passare, completare, rifiutare, riscrivere — le «scelte del driver» viste nella 1ª puntata si usano così com’è (capitolo 3).2
- L’altitudine (quota) decide l’ordine. A ciascun gruppo per uso è assegnata una fascia numerica (Activity Monitor 360000–389999, Anti-Virus 320000–329999 ecc.), e a ciascuna istanza attaccata a un volume è dato un numero univoco (capitolo 4).45
- Gli abitanti del proprio PC si vedono con
fltmc. Procmon (solo mentre è avviato), antivirus, filtro cloud di OneDrive — tutti sono in fila qui (capitolo 5). - Un’impostazione di esclusione antivirus è «l’omissione della scansione di quel prodotto in sé», e non ha effetto sugli altri minifilter. L’esclusione è un trade-off che indebolisce la protezione, e per i volumi di sviluppo c’è Dev Drive (scansione asincrona) come scelta più sicura (capitolo 6).67
- L’indagine di «è lento solo in quell’ambiente» parte dalla colonna Duration di Procmon e dal confronto della configurazione di
fltmc(capitolo 7).
Mappa della conoscenza di questo articolo
Lo standard attuale dei filtri del file system è il minifilter: a differenza dei filtri legacy che impilano direttamente un oggetto dispositivo sullo stack di dispositivi, si registrano callback pre/post presso il Filter Manager (FltMgr) in dotazione a Windows. L’ordine di chiamata è deciso in modo deterministico dall’altitudine assegnata e gestita da Microsoft, e con il comando fltmc si può osservare la configurazione reale. Antivirus, Procmon e la sincronizzazione cloud di OneDrive sono tutti abitanti dello stesso meccanismo; l’impostazione di esclusione omette solo la scansione del prodotto in questione e comporta il trade-off di indebolire la protezione, e per i volumi di sviluppo c’è Dev Drive come alternativa più sicura.
flowchart LR
accTitle: Mappa della conoscenza dei driver filtro e dei minifilter
accDescr: Diagramma che mostra le relazioni tra driver filtro del file system, il ricambio generazionale dai filtri legacy ai minifilter, il Filter Manager (FltMgr), i callback pre/post, altitudine e gruppi di ordine di caricamento, l'osservazione con fltmc, i minifilter antivirus e le impostazioni di esclusione e Dev Drive, e il meccanismo con cui Procmon registra tutto l'I/O come minifilter
minifilter["Minifilter"]
filter_manager["Filter Manager (FltMgr)"]
legacy_filter_driver["Filtro legacy"]
filesystem_filter_driver["Driver filtro del file system"]
device_stack["Stack di dispositivi"]
load_order_instability["Instabilità dell'ordine di caricamento"]
minifilter_callback["Callback pre/post"]
altitude["Altitudine"]
load_order_group["Gruppo di ordine di caricamento"]
fltmc["fltmc"]
altitude_request["Richiesta di altitudine"]
procmon["Process Monitor (procmon.exe)"]
antivirus_minifilter["Minifilter antivirus"]
cloud_filter["Filtro file cloud (cldflt)"]
onedrive_files_on_demand["File su richiesta di OneDrive"]
fast_io["Fast I/O"]
scan_performance_cost["Costo di prestazioni dovuto alla scansione"]
exclusion_setting["Impostazione di esclusione (esclusione di cartelle)"]
reduced_protection["Abbassamento del livello di protezione"]
dev_drive["Dev Drive"]
frame["Frame di FltMgr"]
driver_object["Oggetto driver"]
legacy_filter_driver -->|"implementa"| filesystem_filter_driver
minifilter -->|"implementa"| filesystem_filter_driver
minifilter -->|"successore di"| legacy_filter_driver
legacy_filter_driver -->|"richiede"| device_stack
legacy_filter_driver -->|"può causare"| load_order_instability
minifilter -.->|"previene"| load_order_instability
minifilter -->|"richiede"| filter_manager
filter_manager -->|"usa"| minifilter_callback
minifilter -->|"usa"| minifilter_callback
minifilter -->|"configurato da"| altitude
altitude -->|"configurato da"| load_order_group
altitude -->|"verificato da"| fltmc
altitude -.->|"richiede"| altitude_request
altitude_request -->|"deve precedere"| minifilter
minifilter -->|"verificato da"| fltmc
legacy_filter_driver -->|"verificato da"| fltmc
procmon -->|"usa"| minifilter
procmon -->|"usa"| minifilter_callback
antivirus_minifilter -->|"usa"| minifilter_callback
antivirus_minifilter -->|"configurato da"| altitude
cloud_filter -->|"automatizza"| onedrive_files_on_demand
minifilter -.->|"usa"| fast_io
antivirus_minifilter -.->|"può causare"| scan_performance_cost
exclusion_setting -->|"mitiga"| scan_performance_cost
exclusion_setting -->|"può causare"| reduced_protection
antivirus_minifilter -->|"configurato da"| exclusion_setting
dev_drive -->|"mitiga"| scan_performance_cost
dev_drive -->|"mitiga"| reduced_protection
antivirus_minifilter -->|"consigliato per"| dev_drive
filter_manager -->|"usa"| frame
frame -->|"verificato da"| fltmc
legacy_filter_driver -->|"usa"| driver_object
minifilter -->|"usa"| driver_object
filter_manager -->|"richiede"| device_stack
filter_manager -->|"usa"| driver_object
Nel diagramma, una linea continua indica una relazione che vale sempre e una linea tratteggiata indica una relazione condizionale (le condizioni sono nella spiegazione di ciascuna relazione nella pagina di dettaglio). L’elenco completo delle relazioni (in totale 35, con evidenza e livello di certezza) e le definizioni dei concetti principali sono raccolti nella pagina di dettaglio della mappa della conoscenza (in giapponese). Dati: JSON-LD / Turtle
2. La storia di quelli che si mettono in mezzo — Dai filtri legacy a FltMgr
Un driver filtro del file system è un driver che può intercettare le richieste dirette al file system (o al volume sotto di esso). Può registrare una richiesta, monitorarla, modificarne il contenuto, e persino rifiutarla o trattarla al posto — è il fondamento di software come antivirus, cifratura, backup, memoria gerarchica.1
Il modo di implementazione vecchio (filtro legacy) era impilare direttamente il proprio oggetto dispositivo sullo stack di dispositivi visto nella 1ª puntata. Come meccanismo è lineare, ma in pratica era pieno di problemi: l’ordine in cui si impilavano dipendeva dall’ordine di caricamento e era difficile da garantire, una volta impilato non si poteva uscire in sicurezza (non si poteva scaricare), e diventava un focolaio di bug di compatibilità tra filtri.
Così Windows ha introdotto il Filter Manager (FltMgr). FltMgr stesso sta sullo stack come filtro in dotazione al sistema operativo, e le singole funzioni di filtro registrano callback presso FltMgr come minifilter.2
flowchart TB
subgraph OLD["Modo legacy"]
L1["Filtro legacy A"]
L2["Filtro legacy B"]
LFS1["File system"]
L1 --> L2
L2 --> LFS1
NOTE1["L'ordine è lasciato all'ordine di caricamento<br/>unload sicuro non possibile"]
end
subgraph NEW["Modo minifilter (standard attuale)"]
FM["Filter Manager (FltMgr)<br/>In dotazione al SO. Nello stack sta solo questo"]
M1["Minifilter A (altitudine alta)"]
M2["Minifilter B (altitudine bassa)"]
LFS2["File system"]
FM -. "registrazione dei callback" .- M1
FM -. "registrazione dei callback" .- M2
FM --> LFS2
NOTE2["L'ordine è deterministico per altitudine<br/>si può caricare in qualsiasi momento<br/>(i filtri che lo supportano si possono anche scaricare)"]
end
Figura 1: Ricambio generazionale. Non «impilare» sullo stack, ma «registrare» presso FltMgr
I vantaggi del modo minifilter sono elencati in modo ufficiale — si può caricare in qualsiasi momento, si può controllare l’ordine, e un filtro che implementa un callback di unload si può anche scaricare in esecuzione (un filtro che non lo implementa o lo rifiuta non si stacca).3 Per coesistere con i filtri legacy, FltMgr può stare in più punti dello stack come più «frame», e un minifilter, anche se scaricato e ricaricato, è garantito che torni nella stessa posizione (la stessa altitudine).2 Antivirus, monitoraggio, sincronizzazione moderni sono quasi tutti questo minifilter.
3. Il movimento del minifilter — Callback pre/post
Un minifilter dichiara a FltMgr «a quali operazioni è interessato». Per esempio, è interessato solo a IRP_MJ_CREATE (aprire) e IRP_MJ_WRITE (scrivere). Allora, ogni volta che quell’operazione scorre, vengono chiamati prima dell’operazione (callback pre) e dopo l’operazione (callback post).
sequenceDiagram
participant IOM as I/O Manager
participant FM as FltMgr
participant A as Minifilter A<br/>(altitudine alta)
participant B as Minifilter B<br/>(altitudine bassa)
participant FS as NTFS
IOM->>FM: Richiesta (IRP_MJ_CREATE ecc. Il mondo della 1ª puntata)
FM->>A: callback pre
FM->>B: callback pre
FM->>FS: verso il file system
FS-->>FM: risultato del trattamento
FM-->>B: callback post
FM-->>A: callback post
FM-->>IOM: completamento (verso il flusso di completamento della 1ª puntata)
Figura 2: Callback pre/post. All’andata si chiama in ordine di altitudine alta, al ritorno in ordine inverso
Che cosa si può fare in ciascun callback. Lo stesso schema delle «tre scelte del driver» della sezione 4.3 della 1ª puntata è offerto con un’API più sicura.
flowchart TB
PRE["È stato chiamato il callback pre"]
Q{"Che fare di questa operazione"}
PASS["Lasciar passare<br/>(se non serve il post, si dichiara anche quello)"]
DENY["Rifiutare<br/>restituire subito accesso negato ecc.<br/>es.: rilevamento di virus, divieto di scrittura"]
DONE["Completare da sé<br/>es.: il filtro cloud ottiene<br/>l'entità e la porge"]
MOD["Mettere mano a parametri o contenuto e far scorrere<br/>es.: filtro di cifratura"]
PRE --> Q
Q --> PASS
Q --> DENY
Q --> DONE
Q --> MOD
Figura 3: Le scelte del callback pre. «Vedere, fermare, fare al posto, riscrivere» si possono tutte in modo ufficiale
E qui si recupera il compito della 4ª puntata — un minifilter può assistere anche al Fast I/O (la scorciatoia che non crea un IRP). È perché FltMgr fa passare il meccanismo dei callback anche sul percorso Fast I/O, quindi non succede, come nell’era legacy, che «se passa per la scorciatoia non si vede». Che nel log di Procmon siano in fila anche le righe FASTIO_ è grazie a questa posizione.
4. Altitudine — La «quota» decide l’ordine
Quando più filtri sono interessati alla stessa operazione, chi vede per primo è un problema grave. Se l’antivirus non vede prima della cifratura finisce per scansionare testo cifrato, e uno strumento di monitoraggio, se non sta sopra tutti, non può osservare l’insieme.
A decidere quest’ordine è l’altitudine (altitude: quota). Per tipo di filtro sono definiti gruppi di ordine di caricamento e fasce numeriche. Per essere precisi, l’unità a cui è attaccata l’altitudine non è il driver intero, ma l’«istanza» del minifilter attaccata a un volume. Il numero è univoco, e più è grande più sta in alto nello stack (dal lato app).4 È possibile anche una configurazione in cui un solo driver ha più definizioni di istanza e compare a quote diverse; che l’elenco di fltmc instances sia per istanza è per questo.
flowchart TB
APP["Dal lato app (il numero è grande)"]
G1["FSFilter Activity Monitor: 360000–389999<br/>Osservazione e registrazione dell'I/O (Procmon è qui)"]
G2["FSFilter Undelete: 340000–349999<br/>Ripristino dei file eliminati"]
G3["FSFilter Anti-Virus: 320000–329999<br/>Rilevamento ed eradicazione dei virus"]
G4["FSFilter Replication: 300000–309999<br/>Replica verso il remoto"]
G5["FSFilter Continuous Backup: 280000–289999<br/>Backup continuo"]
G6["Ancora più in basso: Content Screener /<br/>Quota Management / System Recovery /<br/>seguono le fasce di cifratura, compressione ecc."]
FS["Dal lato file system (il numero è piccolo)"]
APP --> G1 --> G2 --> G3 --> G4 --> G5 --> G6 --> FS
Figura 4: Fasce di altitudine (estratto). Per ciascun uso è decisa la «quota a cui stare»
L’importante è che questo numero è assegnato e gestito da Microsoft.5 Il fornitore non se lo attribuisce da solo, lo chiede e lo riceve — per questo su qualsiasi PC si mantiene l’ordine «il monitoraggio sta sopra l’antivirus, l’antivirus sta sopra la cifratura». Questa era la risposta al «gacha dell’ordine di caricamento» dell’era legacy.
Dove chiedere se si fa un minifilter in casa. Per gli sviluppatori, solo la mossa successiva. L’altitudine si chiede seguendo la procedura di Request a Filter Altitude Identifier, inviando una mail in inglese a fsfcomm@microsoft.com con oggetto «Filter altitude request». Occorre compilare tutti i campi: nome dell’azienda, contatto (non personale, un alias aziendale di uso a lungo termine), nome del prodotto, URL del prodotto, descrizione del filtro, nome file del driver, tipo di filtro, tipo di avvio, gruppo di ordine di caricamento desiderato e altitudine desiderata. È scritto anche che si deve prevedere un trattamento di 30 giorni lavorativi, che non c’è uno sportello per le urgenze, e che il numero assegnato può differire da quello desiderato.8 Inoltre, se l’azienda ha già un’altitudine intera nello stesso gruppo di ordine di caricamento, può decidere da sé un valore con un decimale su quel numero (es.: 325000.3), e in quel caso basta una comunicazione a posteriori per mail.8
5. Presentazione degli abitanti — Il proprio PC visto con fltmc
Basta con la teoria, si guarda la cosa vera. Da un prompt dei comandi con privilegi di amministratore:
:: List of registered minifilters (with altitudes)
fltmc
:: Which filter is attached to which volume
fltmc instances
:: View from the volume side
fltmc volumes
fltmc senza argomenti produce lo stesso elenco di fltmc filters. L’output è in 4 colonne, e nella documentazione Microsoft c’è un esempio nello stesso formato.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
Quanto sopra è un estratto a scopo esplicativo. I volti in fila e il numero di istanze differiscono per ambiente, ma il valore numerico dell’altitudine è un valore fisso assegnato da Microsoft, quindi si può incrociare con l’elenco pubblico toccato nel capitolo 4.
Il significato delle colonne è questo.
| Colonna | Significato |
|---|---|
| Filter Name | Nome del filtro (driver) |
| Num Instances | A quanti volumi è attaccato (numero di istanze del capitolo 4) |
| Altitude | Altitudine. Più è grande, più è dal lato app |
| Frame | Numero di frame di FltMgr. Se qui c’è <Legacy>, è il segno che è vivo un filtro legacy che non usa FltMgr.9 |
Già da queste 5 righe si legge che bindflt e cldflt stanno nella fascia più alta FSFilter Top (400000–409999), WdFilter nella fascia Anti-Virus (320000–329999), FileInfo nella fascia più bassa FSFilter Bottom (40000–49999). Lo schema visto nel capitolo 4, «per ciascun uso è decisa la quota a cui stare», si conferma così com’è in numeri. E se si avvia Procmon e si esegue di nuovo fltmc, nella fascia Activity Monitor (360000–389999) si aggiunge una riga che inizia per PROCMON.
I volti differiscono per ambiente, ma gli abitanti tipici sono tutti di casa in questa serie.
WdFilter— Il minifilter di Microsoft Defender. Sta nella fascia Anti-Virus. Su molti PC è il posto di dogana che tutto l’I/O sui file deve per forza attraversare.cldflt— Il filtro dei file cloud. È la squadra operativa dei file su richiesta di OneDrive, e quando viene aperto il reparse point (segnaposto) visto nella 5ª puntata prepara l’entità.10PROCMON24(ecc.) — Un minifilter temporaneo della fascia Activity Monitor, che compare solo mentre Process Monitor è avviato. Lo svelamento di perché Procmon può vedere tutto l’I/O è questo.11 Si provi a eseguirefltmcprima e dopo l’avvio e a confrontare.- Inoltre, software di backup, prodotti di cifratura (prevenzione della fuga di informazioni), EDR, storage di virtualizzazione — più il PC è aziendale, più gli abitanti aumentano.
Se si guarda di nuovo, dalla puntata finale, lo strumento Procmon usato dalla 1ª puntata, dal di fuori della cassetta degli attrezzi, si ha un bel ciclo: «anche l’osservatore era un abitante dello stesso meccanismo dell’oggetto osservato».
6. Dove l’antivirus spende il tempo
L’impatto pratico più grande dei filtri è il costo di scansione dell’antivirus. Dove nasce il tempo lo si mette in un diagramma (i dettagli differiscono per prodotto; sotto è la forma tipica).
sequenceDiagram
participant App as App
participant AV as Minifilter AV
participant FS as NTFS
App->>AV: Apre un file
Note over AV: pre-create: giudizio preventivo su percorso e criteri
AV->>FS: Lascia passare (esecuzione dell'apertura)
FS-->>AV: Apertura riuscita (post-create)
Note over AV: Se il file non è ancora scansionato<br/>qui si scansiona il contenuto e<br/>se c'è un problema si revoca l'apertura<br/>── causa principale per cui aprire diventa lento
AV-->>App: Se non c'è problema, torna l'handle
App->>AV: Scrittura, chiusura
Note over AV: Un file modificato diventa<br/>bersaglio di una nuova scansione alla chiusura ecc.
Note over App,FS: Con tanti file piccoli (prodotti intermedi di una build ecc.)<br/>questo andirivieni si accumula per il numero di file
Figura 5: Il punto in cui nasce il costo di scansione. Per un file è poco, ma con decine di migliaia di file diventa dominante
Su questo si capiscono con precisione due temi pratici.
Il significato tecnico dell’impostazione di esclusione. Nell’I/O di un percorso che coincide con l’elenco di esclusione, il trattamento di scansione del filtro viene omesso. Il filtro non sparisce dallo stack; la realtà è che il giudizio «non si ispeziona» viene preso prima. E c’è un altro limite importante — l’esclusione vale solo per il filtro del prodotto che ha quella impostazione. L’impostazione di esclusione di Microsoft Defender cambia la scansione di WdFilter, e non ha alcun effetto sul comportamento degli altri minifilter che coabitano (antivirus di terzi, EDR, backup, cifratura ecc.). Se «ho messo l’esclusione ma resta lento», si sospetti che un altro abitante stia spendendo il tempo (confronto di fltmc del capitolo 7). L’effetto è grande, ma l’esclusione indebolisce di certo la protezione in quel posto. Anche la documentazione Microsoft avverte ripetutamente che l’esclusione riduce la difesa, quindi al minimo dopo una valutazione del rischio.6 La pratica di risposta ai falsi positivi e dell’impatto sulle prestazioni è trattata in «Se un’app Windows sviluppata in casa viene trattata come virus».
Dev Drive come risposta nuova. Un volume dedicato, progettato per i carichi di lavoro di sviluppo (tantissimi file piccoli), in cui Microsoft Defender gira in modalità prestazioni (scansione asincrona). È posizionato come alternativa più sicura all’esclusione di cartelle, e per default non vengono attaccati filtri aggiuntivi; d’altra parte è scritto anche un avviso forte contro un’operatività che stacca tutti i filtri.7 È la soluzione attualmente raccomandata da Microsoft a «voglio una build più veloce ma l’esclusione fa paura».
7. Procedura di indagine di «è lento solo in quell’ambiente»
Gli strumenti accumulati nella serie, alla fine, si raccolgono in una sola procedura.
flowchart TB
S["Sintomo: la stessa app, ma solo in un ambiente specifico<br/>l'accesso ai file è lento"]
P1["Si guarda la colonna Duration di Procmon<br/>in quale operazione (IRP_MJ_CREATE? WRITE?)<br/>sparisce il tempo"]
Q1{"Una operazione specifica è lenta in modo uniforme?"}
F1["Si confronta fltmc instances con un ambiente veloce<br/>si guarda la differenza di configurazione dei filtri"]
Q2{"Il filtro in differenza è la causa?"}
A1["Impostazione di esclusione (con valutazione del rischio) o<br/>considerazione di Dev Drive, consulto col fornitore"]
A2["Si sospetta altro dai filtri:<br/>cache (4ª puntata), frammentazione o MFT (5ª puntata),<br/>destinazione di rete (UNC), il dispositivo in sé"]
S --> P1 --> Q1
Q1 -->|"sì"| F1 --> Q2
Q2 -->|"sì"| A1
Q2 -->|"no"| A2
Q1 -->|"no (sparso)"| A2
Figura 6: Distinzione della lentezza dovuta ai filtri. La chiave è «il tempo per operazione» e «la differenza di configurazione dei filtri tra ambienti»
I punti sono due. Primo, Procmon ha il tempo impiegato per operazione (Duration). Se si scompone «lento» in «quale operazione è lenta», la caccia al colpevole è a metà. Secondo, la differenza di ambiente è spesso una differenza di configurazione dei filtri. Macchina di sviluppo e macchina di produzione, PC interno e PC dal cliente — mettendo in fila l’output di fltmc i candidati da sospettare si vedono.
Le prime 3 mosse se non si è mai toccato Procmon. La colonna Duration per default non è visualizzata, quindi per non fermarsi qui si scrive solo l’operazione.
- Avviare
Procmon.execome amministratore. - Aprire Options > Select Columns… e, nell’elenco delle colonne, spuntare Duration.
- In Filter > Filter… (Ctrl+L) inserire
Process Name/is/ il nome exe bersaglio /Includee, dopo aver premuto il pulsante Add, OK (senza Add la condizione non entra).
Poi, facendo clic sulla colonna Duration per ordinare, le operazioni che mangiano tempo si raccolgono in alto. Per un riepilogo per processo o per file si può usare anche Tools > File Summary. L’operazione di ProcMon in generale è raccolta in «Guida pratica a Process Monitor (ProcMon)».
8. La chiusura della serie — La mappa delle 6 puntate
Con questo si sono aperti tutti i riquadri della mappa disegnata nella 1ª puntata. L’insieme in un foglio.
flowchart TB
APP["Applicazione<br/>ReadFile / WriteFile / async-await"]
API["2ª puntata: I/O sincrono e asincrono<br/>Modo dell'handle e OVERLAPPED"]
IOCP["3ª puntata: IOCP e pool di thread .NET<br/>Ricezione del completamento ed esecuzione della continuazione"]
IOM["1ª puntata: I/O Manager e IRP<br/>Risoluzione dei nomi, tre oggetti, stack di dispositivi"]
FLT["6ª puntata: Filtri e minifilter<br/>FltMgr, altitudine, pre/post"]
CACHE["4ª puntata: Cache Manager<br/>Vista da 256 KB, lazy writer, Fast I/O<br/>(lavora in coordinamento con NTFS)"]
NTFS["5ª puntata: NTFS<br/>MFT, flussi, collegamenti, due journal"]
HW["Stack di storage e dispositivo"]
APP --> API
API --> IOM
IOCP -. "il completamento torna qui" .-> APP
IOM --> FLT
FLT --> NTFS
NTFS -. "l'I/O con cache abilitata è in coordinamento<br/>(il file system chiama la funzione di cache)" .- CACHE
NTFS --> HW
HW -. "interrupt → completamento (1ª puntata)" .-> IOCP
Figura 7: La mappa dell’intera serie. Il Cache Manager non è «uno strato da attraversare» ma un compagno che coordina col file system, e in caso di cache miss da NTFS esce una richiesta verso lo storage
- 1ª puntata: il quadro d’insieme — Ogni lettura e scrittura diventa un IRP
- 2ª puntata: sincrono/asincrono — Il vero significato di OVERLAPPED
- 3ª puntata: IOCP — Lo scantinato di async/await
- 4ª puntata: cache — Quando il vostro WriteFile arriva sul disco
- 5ª puntata: NTFS — Capire il file system dall’MFT
- 6ª puntata: filtri e minifilter (questo articolo) — Perché Procmon e la scansione antivirus possono intercettare l’I/O
9. Conclusione — In chiusura della serie
La conclusione della puntata finale.
- L’intercettazione dell’I/O è un punto di estensione riconosciuto dal sistema operativo, e lo standard attuale è la registrazione di callback presso FltMgr (minifilter). L’ordine è deciso in modo deterministico dall’altitudine, e Microsoft assegna e gestisce i numeri.245
- Il movimento è callback pre/post. Si può lasciar passare, rifiutare, fare al posto, riscrivere, e si assiste anche al Fast I/O. Procmon, Defender e OneDrive sono tutti abitanti dello stesso meccanismo.11110
- Impostazione di esclusione = omissione della scansione, ed è un trade-off con la protezione. Per i volumi di sviluppo c’è Dev Drive (scansione asincrona) come scelta più sicura.67
- «È lento solo in quell’ambiente» si distingue da Duration di Procmon e dalla differenza di configurazione di
fltmc— gli strumenti della serie diventano così com’è la procedura di indagine.
E la conclusione dell’intera serie, in una riga, è questa — l’I/O di Windows è un progetto coerente, fatto per decidere la destinazione nello spazio dei nomi, far scorrere la richiesta come pacchetto (IRP) tra gli strati, e far sì che ciascun strato possa scegliere «vedere, tenere, fare al posto». Sotto una riga di File.ReadAllText, questa struttura da 6 puntate gira ogni volta. Invece di memorizzare il comportamento delle API, poter derivare da questa mappa «dovrebbe essere così» — questa è la forza che si voleva far prendere con questa serie. Grazie per aver seguito un viaggio lungo.
Articoli correlati
- Le profondità dell’I/O di Windows (1ª puntata) — Ogni lettura e scrittura diventa un IRP: il quadro d’insieme del sistema I/O
- Le profondità dell’I/O di Windows (4ª puntata) — Cache Manager: quando il vostro WriteFile arriva sul disco
- Le profondità dell’I/O di Windows (5ª puntata) — Struttura interna di NTFS: capire il file system dall’MFT
- Guida pratica a Process Monitor (ProcMon) — Individuare in 10 minuti «la configurazione non viene letta» e «ACCESS DENIED»
- Se un’app Windows sviluppata in casa viene trattata come virus — Risposta ai falsi positivi di Microsoft Defender e come convivere con l’impatto sulle prestazioni
- Process Explorer / Handle / VMMap in pratica — Inseguire hang, leak e «file in uso» dallo stato di questo istante
- Checklist minima di sicurezza per le app Windows
Aree di consulenza correlate
KomuraSoft LLC si occupa dell’indagine di problemi di prestazioni e guasti delle app aziendali Windows in cui sono coinvolti i driver filtro, del tipo «è lento solo in un ambiente specifico» o «il software di sicurezza e l’app in casa interferiscono».
- Sviluppo di applicazioni Windows
- Analisi dei bug e delle cause
- Consulenza tecnica e revisione del progetto
- Contattaci
Riferimenti
-
Microsoft Learn, About file system filter drivers. Sul fatto che un driver filtro del file system è un driver opzionale che può intercettare le richieste dirette a un file system o a un altro driver filtro; sul fatto che intercettando una richiesta può estendere o sostituire una funzione prima che passi alla destinazione originale, e può registrare, monitorare, modificare i dati, impedire un comportamento; sul fatto che utilità antivirus, programmi di cifratura, sistemi di gestione della memoria gerarchica ecc. sono esempi di driver filtro. ↩ ↩2 ↩3
-
Microsoft Learn, Filter Manager Concepts. Sul fatto che il Filter Manager (FltMgr) è un driver in modalità kernel in dotazione a Windows e pubblica funzioni che semplificano lo sviluppo dei driver minifilter; sul fatto che un minifilter può registrare un trattamento prima e dopo un’operazione I/O (callback pre/post); sul fatto che, per coesistere con i filtri legacy, FltMgr può attaccarsi in più punti dello stack I/O come frame; sul fatto che un minifilter, anche se scaricato e ricaricato, torna alla stessa altitudine dello stesso frame. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Advantages of the Filter Manager Model. Sul fatto che, tra i vantaggi del modello minifilter rispetto al modello filtro legacy, ci sono un controllo migliore dell’ordine di caricamento dei filtri, il fatto che a differenza dei filtri legacy un minifilter si può caricare in qualsiasi momento, il fatto che si può scaricare, il collegamento a volumi DAX ecc. ↩ ↩2
-
Microsoft Learn, Load order groups and altitudes for minifilter drivers. Sul fatto che per i filtri del file system sono definiti gruppi di ordine di caricamento per uso e a ciascun gruppo è assegnata una fascia di altitudine; sul fatto che ogni driver filtro ha un identificatore di altitudine univoco che determina la posizione relativa rispetto agli altri filtri nello stack I/O; sul fatto che tra gli esempi di gruppo ci sono FSFilter Activity Monitor (360000–389999, osservazione e segnalazione dell’I/O), FSFilter Undelete (340000–349999), FSFilter Anti-Virus (320000–329999, rilevamento ed eradicazione dei virus durante l’I/O sui file), FSFilter Replication (300000–309999), FSFilter Continuous Backup (280000–289999) ecc. ↩ ↩2 ↩3
-
Microsoft Learn, Allocated altitudes. Sul fatto che l’altitudine dei minifilter è assegnata e gestita da Microsoft e che viene mantenuto un elenco pubblico delle altitudini già assegnate; sul fatto che in quell’elenco WdFilter.sys è elencato come 328010 del gruppo FSFilter Anti-Virus, cldflt.sys come 409500 del gruppo FSFilter Top. ↩ ↩2 ↩3
-
Microsoft Learn, Configure and validate exclusions for Microsoft Defender Antivirus. Sul fatto che con l’impostazione di esclusione di Microsoft Defender i file, le cartelle e i processi esclusi escono dal bersaglio della scansione; sul fatto che l’esclusione abbassa il livello di protezione, quindi va definita con cautela dopo averne valutato la necessità, come avvertito ripetutamente. ↩ ↩2 ↩3
-
Microsoft Learn, Set up a Dev Drive on Windows 11. Sul fatto che Dev Drive è un volume progettato per i carichi di lavoro di sviluppo e che Microsoft Defender gira in modalità prestazioni (scansione asincrona); sul fatto che è posizionato come alternativa sicura all’esclusione di cartelle (secure alternative to folder exclusions) tenendo conto di velocità e prestazioni; sul fatto che per default i filtri aggiuntivi non vengono attaccati a un Dev Drive; sul fatto che è avvertito che un’operatività che stacca i filtri antivirus è un rischio di sicurezza grave. ↩ ↩2 ↩3
-
Microsoft Learn, Request a Filter Altitude Identifier. Sul fatto che la richiesta di una nuova altitudine di filtro si fa inviando una mail di testo ASCII con oggetto «Filter altitude request» a fsfcomm@microsoft.com; sul fatto che occorre compilare tutti i campi nome azienda, mail di contatto (alias aziendale di lungo periodo, non personale), nome prodotto, URL prodotto, descrizione del filtro, nome file del filtro, tipo di filtro, tipo di avvio, gruppo di ordine di caricamento desiderato, altitudine desiderata; sul fatto che si deve prevedere un trattamento di 30 giorni lavorativi e che non c’è altro sportello di richiesta oltre a questa procedura; sul fatto che Microsoft può assegnare un’altitudine diversa da quella desiderata; sul fatto che se si ha già un’altitudine intera si può creare un’altitudine propria con un decimale nello stesso gruppo di ordine di caricamento e basta una comunicazione a posteriori. ↩ ↩2
-
Microsoft Learn, Blocking legacy file system filter drivers. Sul fatto che eseguendo
fltmc filtersda un prompt dei comandi con privilegi di amministratore i filtri vengono elencati in 4 colonne «Filter Name / Num Instances / Altitude / Frame»; sul fatto che quelli con Frame<Legacy>sono driver filtro del file system legacy che non passano da FltMgr, e che nei minifilter in Frame entra un numero (0 ecc.). ↩ ↩2 -
Microsoft Learn, Cloud Files API. Sul fatto che l’API Cloud Files (cloud filter) è il fondamento dei motori di sincronizzazione (file su richiesta di OneDrive ecc.) che mostrano in locale i file sul cloud come segnaposto e, all’accesso, ottengono l’entità. ↩ ↩2
-
Microsoft Learn, Process Monitor - Sysinternals. Sul fatto che Process Monitor è uno strumento di monitoraggio avanzato che visualizza in tempo reale l’attività di file system, Registro e processi/thread (come nel corpo, in esecuzione si osserva che compare come minifilter nell’elenco di fltmc). ↩ ↩2
Articoli correlati
Articoli recenti con gli stessi tag per approfondire argomenti vicini.
Le profondità dell'I/O di Windows (5ª puntata) — Struttura interna di NTFS: capire il file system dall'MFT
Quinta puntata della serie che spiega con i diagrammi la struttura interna di NTFS. Si organizzano, dal punto di vista dello sviluppatore...
Le profondità dell'I/O di Windows (4ª puntata) — Cache Manager: quando il vostro WriteFile arriva sul disco
Quarta puntata della serie che spiega con i diagrammi il Cache Manager di Windows. Si organizzano la cache implementata come file mapping...
Le profondità della virtualizzazione Windows (parte 2) — Memoria che nemmeno il kernel può vedere: come funzionano VBS, HVCI e Credential Guard
Su un'installazione pulita su hardware compatibile, VBS è abilitata per default e usa l'hypervisor e SLAT per creare un isolamento più fo...
Named pipe in pratica — L'IPC standard di Windows, dalla progettazione alla sicurezza
Guida pratica alle named pipe, il meccanismo standard di comunicazione tra processi su Windows. L'articolo organizza, a partire dalle fon...
Scegliere l'account di un servizio Windows — LocalSystem, account virtuali e gMSA
Eseguite ancora i servizi Windows come LocalSystem? Questo articolo confronta privilegi e identità di rete di LocalService, NetworkServic...
Argomenti correlati
Queste pagine collocano l’argomento in un contesto più ampio di servizi e decisioni.
Argomenti tecnici Windows
Portale su sviluppo Windows, analisi dei problemi e valorizzazione delle risorse esistenti.
Servizi collegati all’argomento
L’articolo è direttamente collegato ai servizi seguenti.
Sviluppo di applicazioni Windows
Applicazioni aziendali, integrazione di dispositivi e strumenti di comunicazione, dai requisiti allo sviluppo.
Domande frequenti
Domande che ricorrono nelle consulenze sull’argomento dell’articolo.
- Che differenza c'è tra un driver filtro del file system e un minifilter?
- Entrambi sono «driver che intercettano le richieste I/O verso il file system», ma differisce la generazione del modo di intercettare. Il filtro legacy più vecchio impilava direttamente il proprio oggetto dispositivo sullo stack di dispositivi del file system: la posizione era decisa dall'ordine di caricamento e difficile da garantire, e c'erano problemi come non poter scaricare in sicurezza una volta caricato. Lo standard attuale, il minifilter, è un modo che registra callback presso il Filter Manager (FltMgr) in dotazione a Windows, dicendo in sostanza «chiamami prima e dopo questa operazione». La posizione è decisa in modo deterministico da un numero chiamato altitudine, si può caricare in qualsiasi momento, e un filtro che implementa un callback di unload si può anche staccare in esecuzione. Antivirus, cifratura, strumenti di monitoraggio, sincronizzazione cloud: i filtri moderni sono quasi tutti implementati come minifilter.
- Perché un software antivirus può ispezionare tutti gli accessi ai file?
- Perché il sistema operativo mette a disposizione, in modo ufficiale, un punto di estensione proprio per questo. Un minifilter può registrare presso il Filter Manager del codice chiamato prima (callback pre) e dopo (callback post) operazioni come aprire, leggere, scrivere un file. Un filtro antivirus sta nella fascia di altitudine per anti-virus (320000–329999) e, per esempio, può scansionare il contenuto subito dopo che l'apertura del file è andata a buon fine (post-create) e, se c'è un problema, revocare quell'apertura e far fallire l'accesso. Come si è visto nella 1ª puntata della serie, tutto l'I/O sui file scorre nello stack di dispositivi, quindi la logica è che, stando in una posizione fissa su quel percorso, si possono ispezionare tutti gli accessi. Non è un hack: è un meccanismo incorporato nel progetto del sistema operativo.
- Che cosa fa, in termini tecnici, un'impostazione di esclusione (esclusione di cartelle) di un software antivirus?
- Per l'I/O verso un percorso che coincide con l'elenco di esclusione, fa omettere il trattamento di scansione che farebbe il filtro di quel prodotto. Il filtro in sé non sparisce dallo stack; la comprensione più vicina alla realtà è che il giudizio «questo percorso non si ispeziona» viene preso prima. Un limite importante è che l'esclusione vale solo per il prodotto che ha quella impostazione. Per esempio, l'impostazione di esclusione di Microsoft Defender cambia la scansione del filtro di Defender (WdFilter), e non ha effetto sul comportamento degli altri minifilter che coabitano — antivirus di terzi, EDR, backup e così via. Serve un'impostazione di esclusione per ciascun prodotto, e se «ho escluso ma resta lento» può essere un altro filtro la causa. E, come la documentazione Microsoft avverte ripetutamente, un'esclusione indebolisce la protezione in quel posto, quindi va tenuta al minimo insieme a una valutazione del rischio. Per uso di sviluppo vale anche considerare Dev Drive (modalità prestazioni = scansione asincrona), progettato come alternativa più sicura all'esclusione di cartelle.
- Come fa Process Monitor a registrare tutto l'I/O?
- Perché Procmon stesso, all'avvio, si registra presso il Filter Manager come minifilter nella fascia di altitudine per Activity Monitor. Se, con Procmon avviato, si esegue fltmc da un prompt dei comandi con privilegi di amministratore, si conferma che nell'elenco compare un filtro con un nome che inizia per PROCMON. Essendo presente come minifilter al pre/post delle operazioni I/O su tutti i volumi, può registrare senza omissioni quale processo ha fatto quale operazione su quale file. Il motivo per cui i termini IRP e Fast I/O visti nella serie escono così com'è nella visualizzazione di Procmon è proprio che osserva stando sul percorso stesso dell'I/O.
- Quando la build sulla macchina di sviluppo è lenta, si devono sospettare i driver filtro?
- Il valore di sospettarlo è alto. Una build è un ammasso di creazione, lettura, scrittura ed eliminazione di tantissimi file piccoli, e ciascuno di quelli diventa bersaglio di ispezione dei filtri (soprattutto la scansione antivirus), quindi è il carico di lavoro in cui il costo dei filtri emerge più facilmente. L'indagine di base è guardare la colonna Duration di Procmon per confermare in quale operazione sparisce il tempo, e confrontare la differenza di configurazione dei filtri tra ambienti con fltmc instances. Come contromisura, oltre all'impostazione di esclusione dopo una valutazione del rischio, c'è l'uso di Dev Drive, progettato apposta per i volumi di sviluppo. Su un Dev Drive l'antivirus gira in modalità prestazioni (scansione asincrona), e Microsoft lo posiziona come alternativa più sicura a un'impostazione di esclusione.
Profilo dell’autore
Pagina di presentazione dell’autore dell’articolo.
Go Komura
Rappresentante di KomuraSoft LLC
Specializzato nello sviluppo di software Windows, nella consulenza tecnica e nell’analisi dei malfunzionamenti, soprattutto nei progetti con sistemi esistenti e guasti difficili da riprodurre.