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;
к которому и приводят все ветви.
Здравствуйте, 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 и т.д., а это очень низкий шанс, тем более в сочетании с "лажей". Но...
Здравствуйте, Слава, Вы писали:
С>Здравствуйте, sergey77666, Вы писали:
S>>Примерно такой код
С>У меня есть подозрение, что в таком стиле лучше вести разработку под NodeJS и Mongo.
Ну я ее в таком стиле веду под десятки платформ, хотя Си с асмом действительно не очень нравятся, кроме случаев, когда нужно сделать что-то локальное, типа взломать прогу или написать небольшую библиотечку.
Но для драйверов я могу много полезного сделать — библиотеку функций, которая упростит работу в дальнейшем. В родном API ведь даже долбаного strtok нету...
Здравствуйте, 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 столько не жрет (а проблема была уже после его запуска).