IRP_MJ_CREATE, минифильтр. Как отличить именно СОЗДАНИЕ файл
От: sergey77666 Марс  
Дата: 03.01.18 08:49
Оценка:
Вот такой код. Должно "лететь в лог" только создание файлов в обычном понимании.
Не папок.
И не открытие, а именно создание.
Но летит это всё.
Ясно, что нужно еще что-то проверять. Может кто подскажет? Желательно именно в Pre-, хотя в данном случае подошел бы и Post-.

Думаю так:
— перед созданием проверять, что файла нет, и по параметрам проверять, что с данными параметрами он должен быть создан (но как проверять, что его нет, не открывая его? и это не лучший вариант — а вдруг что-то помешает созданию? лучше иметь ОБА — и before, и по факту)
— а по папкам не знаю где в параметрах.

С хуками SSDT работал, была эта проблема. Ладно, перешел на фильтры — и опять она. Неужели нельзя было хоть одно нормальное API сделать, хосспидя-ты-бозезьмой...

FLT_PREOP_CALLBACK_STATUS
PreFileOperationCallback (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
    ) {
    PFILE_OBJECT FileObject;
            
    if(FLT_IS_FS_FILTER_OPERATION(Data))
    {
        return FLT_PREOP_SUCCESS_NO_CALLBACK;
    }
            if (FltObjects->FileObject != NULL && Data != NULL) {
        FileObject = Data->Iopb->TargetFileObject;
                if(FileObject != NULL && Data->Iopb->MajorFunction == IRP_MJ_CREATE)
                {
                    // здесь еще проверка FltObjects->FileObject->FileName на NULL и его логирование
                }
            }
            
            
        return FLT_PREOP_SUCCESS_NO_CALLBACK;
    }
Отредактировано 03.01.2018 8:54 sergey77666 . Предыдущая версия . Еще …
Отредактировано 03.01.2018 8:50 sergey77666 . Предыдущая версия .
Отредактировано 03.01.2018 8:49 sergey77666 . Предыдущая версия .
Re: IRP_MJ_CREATE, минифильтр. Как отличить именно СОЗДАНИЕ файл
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 03.01.18 09:16
Оценка:
Здравствуйте, sergey77666, Вы писали:

S>только создание файлов в обычном понимании. Не папок.


Найдется все.

S>И не открытие, а именно создание.


Это, само собой, невозможно до проверки наличия файла. В некоторых случаях может помочь проверка Disposition в Parameters.Create.Options.

S>лучше иметь ОБА — и before, и по факту)


Именно.

S>Неужели нельзя было хоть одно нормальное API сделать, хосспидя-ты-бозезьмой...


"Нормальное" — это такое, в котором быстрее и легче всего решается именно Ваша задача?
Re: IRP_MJ_CREATE, минифильтр. Как отличить именно СОЗДАНИЕ файл
От: okman Беларусь https://searchinform.ru/
Дата: 03.01.18 09:23
Оценка:
Здравствуйте, sergey77666, Вы писали:

S>Вот такой код. Должно "лететь в лог" только создание файлов в обычном понимании.

S>Не папок.
S>И не открытие, а именно создание.
S>Но летит это всё.
S>Ясно, что нужно еще что-то проверять. Может кто подскажет? Желательно именно в Pre-, хотя в данном случае подошел бы и Post-.

См. поле Data->Iopb->Parameters.Create.Options:

FLT_PARAMETERS for IRP_MJ_CREATE union
https://msdn.microsoft.com/en-us/library/windows/hardware/ff544687%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

Options

Bitmask of flags that specify the options to be applied when creating or opening the file, as well as the action to be
taken if the file already exists. The low 24 bits of this member correspond to the CreateOptions parameter to FltCreateFile.
The high 8 bits correspond to the CreateDisposition parameter to FltCreateFile.

Ну т.е. в старших 8 битах будет один из флагов FILE_CREATE, FILE_OPEN_IF и т.д., по которому можно различать
режимы создания/открытия файла друг от друга, подробно они описаны в доках к ZwCreateFile/FltCreateFile.

Отличить файл от папки можно, например, при помощи FltIsDirectory, только звать ее нужно из Post-калбэка.

Еще, наверное, стоит отфильтровать открытие томов (DASD open), в сэмплах из WDK это делают так:
BOOLEAN
IsVolumeOpen(
    _In_ PFLT_CALLBACK_DATA Cbd
    )
/*++

Routine Description:

    This routine returns if the target object in this callback datastructure
    is a volume.  If the file object is NULL then assume this is NOT a volume 
    file object

Arguments:

    Cbd                   - Supplies a pointer to the callbackData which
                            declares the requested operation.

Return Value:

    TRUE  - target is a volume
    FALSE - target is not a volume

--*/
{
    PAGED_CODE();

    if ((Cbd->Iopb->TargetFileObject != NULL) &&
        FlagOn( Cbd->Iopb->TargetFileObject->Flags, FO_VOLUME_OPEN )) {

         return TRUE;
    } else {

        return FALSE;
    }
}
Re: IRP_MJ_CREATE, минифильтр. Как отличить именно СОЗДАНИЕ файл
От: Alexander G Украина  
Дата: 03.01.18 09:24
Оценка:
Здравствуйте, sergey77666, Вы писали:

S>Вот такой код. Должно "лететь в лог" только создание файлов в обычном понимании.

S>Не папок.
S>И не открытие, а именно создание.
S>Но летит это всё.

Ну, ведь даже обычная CreateFile из Winapi и создаёт и открывает.
(потому что должно быть такое апи, которое и создаёт и открывает, иначе будет гонка при перезаписи файла)

И работает она и с файлам и с папками (, с симлинками, со стримами, с точками монтирования, с томами).

В FLT_PARAMETERS for IRP_MJ_CREATE union в поле Options есть такое:
* Disposition биты (создавать или открывать)
* CreateOptions биты (среди них FILE_DIRECTORY_FILE и FILE_NON_DIRECTORY_FILE)

Но есть пара нюансов:
* Disposition может разрешать и создание и открытие (вариант "октрыть, а если нет — создать", или другой "создать, а если есть — очистить и открыть")
* Может быть не задано ни FILE_DIRECTORY_FILE, ни FILE_NON_DIRECTORY_FILE

Бороться с неоднозначным Disposition можно, таки применив post-обработку, IO_STATUS_BLOCK будет содержать в поле Information значения FILE_CREATED,FILE_OPENED, FILE_OVERWRITTEN...
Русский военный корабль идёт ко дну!
Re[2]: IRP_MJ_CREATE, минифильтр. Как отличить именно СОЗДАНИЕ файл
От: sergey77666 Марс  
Дата: 03.01.18 10:56
Оценка:
Здравствуйте, okman, Вы писали:

O>Ну т.е. в старших 8 битах будет один из флагов FILE_CREATE, FILE_OPEN_IF и т.д., по которому можно различать

O>режимы создания/открытия файла друг от друга, подробно они описаны в доках к ZwCreateFile/FltCreateFile.

Да про IoStatus я знаю, но только FILE_OPEN_IF и т.д. могут вызвать уже при существующем файле! Не для всех случаев подойдут такие наработки. Например, в случае с вредоносом, который где-то создает свой файл плагина к какому-то софту (что запрещено без участия юзера), то антивирусной защите будет интересно отследить именно создание (непосредственно через CreateFile или через CopyFile), а не открывание уже созданного файла, допустим, по 10 раз за день с целью что-то поменять. Или, во всяком случае, нужна дифференциация первого от второго.

O>Отличить файл от папки можно, например, при помощи FltIsDirectory, только звать ее нужно из Post-калбэка.


Не очень гуд.
Если нельзя ни по каким входным параметрам NtCreateFile определить, файл это создается или папка, то как само ядро определяет, что ему создавать?

O>Еще, наверное, стоит отфильтровать открытие томов (DASD open), в сэмплах из WDK это делают так:


Кроме папок и файлов там еще есть томы?
ОК.
Re[2]: IRP_MJ_CREATE, минифильтр. Как отличить именно СОЗДАНИЕ файл
От: sergey77666 Марс  
Дата: 03.01.18 11:01
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG> * Может быть не задано ни FILE_DIRECTORY_FILE, ни FILE_NON_DIRECTORY_FILE


Что тогда сделает система?

AG>Бороться с неоднозначным Disposition можно, таки применив post-обработку


Просто определить в Pre-каллбэке, есть ли такой файл (до вызова) или нет — никак?
Ладно.
Re[2]: IRP_MJ_CREATE, минифильтр. Как отличить именно СОЗДАН
От: sergey77666 Марс  
Дата: 03.01.18 15:22
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>"Нормальное" — это такое, в котором быстрее и легче всего решается именно Ваша задача?


Задача отнюдь не только моя. Спора не будет. Уметь отличать удобное от неудобного — это надо родиться. И жить не слишком хорошо. А уж понять, что Microsoft ничего бы не стоило сделать 10 разных API — тем более.
Отредактировано 03.01.2018 15:29 sergey77666 . Предыдущая версия . Еще …
Отредактировано 03.01.2018 15:25 sergey77666 . Предыдущая версия .
Re[3]: IRP_MJ_CREATE, минифильтр. Как отличить именно СОЗДАН
От: Alexander G Украина  
Дата: 03.01.18 18:33
Оценка:
Здравствуйте, sergey77666, Вы писали:

AG>> * Может быть не задано ни FILE_DIRECTORY_FILE, ни FILE_NON_DIRECTORY_FILE


S>Что тогда сделает система?


Если ничего не было, и Disposition позволяет создавать — создаст файл.
Если что-то было, и Disposition позволяет открывать — откроет и файл, и папку.

(Вообще насчёт таких вопросов — можно пробовать вызвать NtCreateFile из ntdll.dll в usermode приложении и смотреть, что будет)
Русский военный корабль идёт ко дну!
Отредактировано 03.01.2018 18:34 Alexander G . Предыдущая версия .
Re: IRP_MJ_CREATE, минифильтр. Как отличить именно СОЗДАНИЕ файл
От: ononim  
Дата: 04.01.18 04:27
Оценка:
S>Вот такой код. Должно "лететь в лог" только создание файлов в обычном понимании.
S>Не папок.
S>И не открытие, а именно создание.
S>PreFileOperationCallback (
Сразу — ошибка в дизайне. До исполнения операции никак нельзя знать будет файл создан или открыт существующий, т.к. таких операций может прилететь одновременно 100500 штук и какая именно из них в итоге файл создаст, а какие окажутся опоздунами — будет ясно только постфактум, после того как запросы пролетят через фс.
Так что ищите ответ в Post FileOperationCallback
Как много веселых ребят, и все делают велосипед...
Re[2]: IRP_MJ_CREATE, минифильтр. Как отличить именно СОЗДАН
От: sergey77666 Марс  
Дата: 04.01.18 09:06
Оценка: -2
Здравствуйте, ononim, Вы писали:

S>>Вот такой код. Должно "лететь в лог" только создание файлов в обычном понимании.

S>>Не папок.
S>>И не открытие, а именно создание.
S>>PreFileOperationCallback (
O>Сразу — ошибка в дизайне. До исполнения операции никак нельзя знать будет файл создан или открыт существующий, т.к. таких операций может прилететь одновременно 100500 штук и какая именно из них в итоге файл создаст, а какие окажутся опоздунами — будет ясно только постфактум, после того как запросы пролетят через фс.
O>Так что ищите ответ в Post FileOperationCallback

Согласен, ошибка в дизайне этого API. Да и не то, что ошибка, а просто нет никакого дизайна, просто никто не позаботился, чтобы оно не было таким, какое оно и есть (каким его проще сделать), а было реально удобно им пользоваться.

Если нужен не столько даже мониторинг, сколько возможность запретить именно создание именно файла, то глубоко насрать, сколько там операций прилетит этому файлу. Все равно либо запрещать все, либо разрешать все.
И также глубоко, будет ли оно там реально создан или помешает скажем нехватка места на диске — важна сама попытка его создать. А попытку создать можно определять по наличию одного из флагов, способных создавать файл, ПЛЮС по отсутствию файла до вызова. Но вот как нормально проверить последнее, и не вызвать этим рекурсии (Create) — я пока не знаю.

В данном драйвере применю Post.
Этот драйвер — только мониторит.
Зачем он вообще нужен, я не знаю. Заказчик очень скрытный тип.
Но, скажем, если это такой тул для детекта вредоногосного ПО, то вроде очевидно, что не стоило бы пропускать попытки сотворить недозволенное (и тем самым оставлять зловред без внимания!) лишь из-за того, что они по какой-то причине провалились... А значит, Pre лучше...
Отредактировано 04.01.2018 9:11 sergey77666 . Предыдущая версия . Еще …
Отредактировано 04.01.2018 9:08 sergey77666 . Предыдущая версия .
Re[3]: IRP_MJ_CREATE, минифильтр. Как отличить именно СОЗДАН
От: ononim  
Дата: 04.01.18 20:20
Оценка: +2
S>>>PreFileOperationCallback (
O>>Сразу — ошибка в дизайне. До исполнения операции никак нельзя знать будет файл создан или открыт существующий, т.к. таких операций может прилететь одновременно 100500 штук и какая именно из них в итоге файл создаст, а какие окажутся опоздунами — будет ясно только постфактум, после того как запросы пролетят через фс.
O>>Так что ищите ответ в Post FileOperationCallback
S>Согласен, ошибка в дизайне этого API.
Вы работаете не в MSDOS, а в многозадачной операционной системе. Реализаций вашей хотелки означает глобальный лок поверх всех операций с файловой системой, что сразу отметает возможность кучи разных оптимизаций на уровне связки драйверов FS и блочного устройства под ним, не говоря о сетевых файловый системах.
Но если прям надо — то такой лок вы можете сами создать, правда это не поможет с сетевыми ФС — на удаленном сервере файл может быть создан удаленно с совершенно другого компа, где нету вашего драйвера вообще.

S>Да и не то, что ошибка, а просто нет никакого дизайна просто никто не позаботился, чтобы оно не было таким, какое оно и есть (каким его проще сделать), а было реально удобно им пользоваться.

Операционная система создана для того чтобы оптимально работать с оборудованием. Всякие АПИ для разработчиков ненужного софта всяких антиврей — опциональный бонус, функционал которого ограничен первичными требованиями.
Как много веселых ребят, и все делают велосипед...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.