FS Minifilter, IRP_MJ_CREATE. Кривой FileName?
От: sergey77666 Марс  
Дата: 08.01.18 05:21
Оценка:
Примерно такой код
FLT_POSTOP_CALLBACK_STATUS PostFileOperationCallback ( IN OUT PFLT_CALLBACK_DATA Data, 
                IN PCFLT_RELATED_OBJECTS FltObjects, 
                IN PVOID CompletionContext, 
                IN FLT_POST_OPERATION_FLAGS Flags) {
..
FILE_OBJECT pFileObject;
PWCHAR bufPFO = NULL; 
..
if (Data != NULL && Data->Iopb != NULL && !(Data->Iopb->Parameters.Create.Options & FILE_DIRECTORY_FILE)) {
            
            if (Data->Iopb->TargetFileObject != NULL)
            {
                pFileObject = *Data->Iopb->TargetFileObject;
                if (Data->IoStatus.Information == FILE_CREATED && pFileObject.FileName.Length > 0)
                {
                    ..
                    bufPFO = (PWCHAR)ExAllocatePoolWithTag(NonPagedPool, sizeof(WCHAR) * 1024, 'NC__');
                    for (iii = 0; iii < 1024; iii++)
                    {
                        bufPFO[iii] = 0;
                    }
                    res = RtlStringCchPrintfW(bufPFO, 1024, L"%wZ", pFileObject.FileName);


И вот на этом самом месте, где RtlStringCchPrintfW, иногда происходит ерунда. Обычно это было, когда я запускал Edge и пытался им скачать и запустить ChromeSetup.exe
То BSOD, то buffer overflow (хотя 1024 — это ведь даже много для пути к файлу, да и перед этим он логируется и видно, что там отнюдь не столько.

Какие есть мысли:
— разве что в след. раз посмотреть, не в нехватки ли оперативки проблема (это виртуалка, есть такое подозрение)
— ну, и проверить, что в этом самом pFileObject.FileName, взять его Buffer до \0 и попробовать обойтись без RtlStringCchPrintfW

Есть что добавить?
Можно вообще вот так напрямую пихать этот pFileObject.FileName в PWCHAR или UNICODE_STRING?

Еще: бывало Access violation (в основном опять тот же Edge), в том же каллбеке, в самом конце, где нет буквально ничего, кроме
return FLT_POSTOP_FINISHED_PROCESSING;
к которому и приводят все ветви.
Отредактировано 08.01.2018 5:31 sergey77666 . Предыдущая версия . Еще …
Отредактировано 08.01.2018 5:30 sergey77666 . Предыдущая версия .
Отредактировано 08.01.2018 5:26 sergey77666 . Предыдущая версия .
Отредактировано 08.01.2018 5:26 sergey77666 . Предыдущая версия .
Отредактировано 08.01.2018 5:26 sergey77666 . Предыдущая версия .
Re: FS Minifilter, IRP_MJ_CREATE. Кривой FileName?
От: okman Беларусь https://searchinform.ru/
Дата: 08.01.18 06:21
Оценка: +1
Здравствуйте, sergey77666, Вы писали:

S>Примерно такой код

S>...
S>И вот на этом самом месте, где RtlStringCchPrintfW, иногда происходит ерунда.

1. Спецификатор '%wZ' требует передачи указателя на UNICODE_STRING, а не сам UNICODE_STRING.

2. Вместо вытаскивания имени из FILE_OBJECT надежнее FltGetFileNameInformation.
Re[2]: FS Minifilter, IRP_MJ_CREATE. Кривой FileName?
От: sergey77666 Марс  
Дата: 08.01.18 14:38
Оценка:
Здравствуйте, okman, Вы писали:

O>Здравствуйте, sergey77666, Вы писали:


S>>Примерно такой код

S>>...
S>>И вот на этом самом месте, где RtlStringCchPrintfW, иногда происходит ерунда.

O>1. Спецификатор '%wZ' требует передачи указателя на UNICODE_STRING, а не сам UNICODE_STRING.


O>2. Вместо вытаскивания имени из FILE_OBJECT надежнее FltGetFileNameInformation.


1. А почему тогда у меня кругом без указателя, и в основном все работает?
На моем ноутбуке драйвер работал в течение минут 20. Edge тоже. Нигде так и не упало.

2. Хм, может и переделаю. Как я понял, она даст более "нормальный" путь, с буквой диска — это бы не помешало...
А нужны ли тогда будут многочисленные проверки, которые есть в начале этого кода? Проверка PFILE_OBJECT на NULL, проверка того, что вернет FltGetFileNameInformation (там структура, в ней много UNICODE_STRING, не надо ли проверять какие-то из них с помощью &str == NULL (или с помощью str.Length==0?))

3. Еще бы точно определить, файл или папка. Все-таки моя проверка FILE_DIRECTORY_FILE почему-то иногда лажает. Вроде бы не страшно, поскольку я потом еще расширение проверяю, и у папок нету шанса попасть в лог, если не оканчивается .sys/.dll/.exe/.bat и т.д., а это очень низкий шанс, тем более в сочетании с "лажей". Но...
Re: FS Minifilter, IRP_MJ_CREATE. Кривой FileName?
От: Слава  
Дата: 08.01.18 15:13
Оценка:
Здравствуйте, sergey77666, Вы писали:

S>Примерно такой код


У меня есть подозрение, что в таком стиле лучше вести разработку под NodeJS и Mongo.
Re[2]: FS Minifilter, IRP_MJ_CREATE. Кривой FileName?
От: sergey77666 Марс  
Дата: 08.01.18 15:21
Оценка:
Здравствуйте, Слава, Вы писали:

С>Здравствуйте, sergey77666, Вы писали:


S>>Примерно такой код


С>У меня есть подозрение, что в таком стиле лучше вести разработку под NodeJS и Mongo.


Ну я ее в таком стиле веду под десятки платформ, хотя Си с асмом действительно не очень нравятся, кроме случаев, когда нужно сделать что-то локальное, типа взломать прогу или написать небольшую библиотечку.
Но для драйверов я могу много полезного сделать — библиотеку функций, которая упростит работу в дальнейшем. В родном API ведь даже долбаного strtok нету...
Re[2]: FS Minifilter, IRP_MJ_CREATE. Кривой FileName?
От: sergey77666 Марс  
Дата: 08.01.18 16:01
Оценка:
Здравствуйте, okman, Вы писали:

O>Здравствуйте, sergey77666, Вы писали:


S>>Примерно такой код

S>>...
S>>И вот на этом самом месте, где RtlStringCchPrintfW, иногда происходит ерунда.

O>1. Спецификатор '%wZ' требует передачи указателя на UNICODE_STRING, а не сам UNICODE_STRING.


O>2. Вместо вытаскивания имени из FILE_OBJECT надежнее FltGetFileNameInformation.


Так. От тотального перехода на указатели стало хуже.
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "CreateFile: %wZ\r\n", &(pFileObject.FileName)); — работает
res = RtlStringCchPrintfW(bufPFO, 1024, L"%wZ", &(pFileObject.FileName)); — не работает, теперь постоянно выдает то 80000005, то просто пустая строка
Значит, сам pFileObject.FileName "кривой", что ли. Еще есть подозрения на функцию
FsRtlIsNameInExpression(&strExeExtCheckPattern, &(pFileObject.FileName), TRUE, NULL
где:
UNICODE_STRING strExeExtCheckPattern = RTL_CONSTANT_STRING(L"*.EXE");
Вряд ли она повреждает этот FileName. Но все же надо смотреть.

BSOD не там, а именно на return, во всяком случае в ситуации с Edge.
Сперва надо вообще все потихоньку выкинуть, по крайней мере все это безумие со строками, и посмотреть что будет.

Оперативки на момент падения было 400 МБ свободной (по диспетчеру задач). ChromeSetup столько не жрет (а проблема была уже после его запуска).
Отредактировано 08.01.2018 16:13 sergey77666 . Предыдущая версия . Еще …
Отредактировано 08.01.2018 16:12 sergey77666 . Предыдущая версия .
Отредактировано 08.01.2018 16:11 sergey77666 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.