Познаю минифильтр, который шифрует/расшифровует файлы.
Сталкнулся с проблемой, когда, например, файл был открыт ранее без использования минифильтра.
В общем проблема выглядит так:
1. Минифильтр офф:
а) пользователь читает зашифрованный файл;
б) в кэше появляется шифртекст — пользователь видит мусор;
в) пользователь включает шифрование;
г) опять пытается читать тот же файл;
д) данные читаются из кэша — пользователь видит мусор (хотя ожидает plaintext).
2. Минифильтр он:
а) пользователь работает с зашифрованным файлом;
б) в кэше открытые данные;
в) пользователь выключает режим шифрования для файла;
г) снова открывается тот же файл;
д) пользователь видит открытые данные из кэша (хотя ожидает шифртекст).
Решил пойти по пути, когда в IRP_MJ_CREATE пакете в post-callback процедуре очищаю кэш.
Основные моменты в PostCreate:
— проверяю с тем ли файлом буду работать;
— считываю хэадер файла с помощью:
status = FltReadFile(
Instance,
FileObject,
&offset,
(ULONG)FILE_HEADER_LENGTH,
buffer,
FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET,
&bytesRead,
NULL,
NULL);
— очищаю кэш.
В IRP_MJ_CLEANUP пакете в pre-callback процедуре делаю, почти тоже:
— проверяю с тем ли файлом буду работать;
— очищаю кэш.
Вот пример как очищаю кэш:
if(CcIsFileCached(FltObjects->FileObject))
{
fcb = (PFSRTL_COMMON_FCB_HEADER)FltObjects->FileObject->FsContext;
if (fcb == NULL)
{
DbgPrint();
}
if (fcb->Resource != NULL)
{
ExEnterCriticalRegionAndAcquireResourceExclusive(fcb->Resource);
}
if (fcb->PagingIoResource != NULL)
{
ExEnterCriticalRegionAndAcquireResourceExclusive(fcb->PagingIoResource);
}
if (FltObjects->FileObject->SectionObjectPointer != NULL)
{
if (FltObjects->FileObject->SectionObjectPointer->ImageSectionObject != NULL)
{
if (!MmFlushImageSection(FltObjects->FileObject->SectionObjectPointer, MmFlushForDelete))
{
DbgPrint();
}
}
if (FltObjects->FileObject->SectionObjectPointer->DataSectionObject != NULL)
{
if (!CcPurgeCacheSection(FltObjects->FileObject->SectionObjectPointer, NULL, 0, FALSE))
{
DbgPrint();
}
}
}
ExReleaseResourceAndLeaveCriticalRegion(fcb->Resource);
ExReleaseResourceAndLeaveCriticalRegion(fcb->PagingIoResource);
}
Например, рассмотрим чтение текстового файла с помощью Notepad++:
1. Захожу в папку и открываю test.txt. Фильтр не перехватывает ничего. Вижу зашифрованное содержимое в файле.
2. Далее использую минифильтр. Он начинает перехватывать запросы к test.txt в данной папке. Открываю файл и вижу расшифрованное содержимое.
3. Делаю так что бы минифильтр не перехватывал запросы к нужной папке и снова открываю тот же файл. Вижу зашифрованный файл.
Все ок. Но с Notepad такое не получается. 1-й и 2-й шаги проходят как и у Notepad++, а вот в 3-м шаге открывается РАСШИФРОВАННЫЙ файл, а должен быть зашифрованный.
Кстати 2 шаг получается сделать корректно, так как я не установил флаг FLTFL_IO_OPERATION_NON_CACHED в функцию FltReadFile. А с этих флагом на 2 шаге будет неудача для маппед файлов.
Подскажите, пожалуйста, как корректно выгрузить маппед файлы с памяти в IRP_MJ_CLEANUP? Или в IRP_MJ_CLOSE нужно это делать?