Пишу драйвер минифильтр в связке с программой управления. фильтр цепляется на IRP пакет IRP_MJ_CREATE. По PreCreate Он проверяет имя файла, точнее отправляет имя файла в юзер моде приложение, которое в свою очередь должно проверить имя файла на валидность. Ниже идеть код копирования имени файла в буфер для отправки к приложению, здесь же и просиходит сбой, как будет видно далее из !analyze -v. Код (Text): if (name->Buffer!=NULL){ __try{ RtlCopyMemory( ¬ification.Contents, name->Buffer, 10//(ULONG)name->Length ); } __except(EXCEPTION_EXECUTE_HANDLER){ DbgPrint("pp"); }} Код (Text): ******************************************************************************* * * * Bugcheck Analysis * * * ******************************************************************************* PAGE_FAULT_IN_NONPAGED_AREA (50) Invalid system memory was referenced. This cannot be protected by try-except, it must be protected by a Probe. Typically the address is just plain bad or it is pointing at freed memory. Arguments: Arg1: e1045040, memory referenced. Arg2: 00000000, value 0 = read operation, 1 = write operation. Arg3: f9f9063b, If non-zero, the instruction address which referenced the bad memory address. Arg4: 00000001, (reserved) Debugging Details: ------------------ ***** Kernel symbols are WRONG. Please fix symbols to do analysis. ************************************************************************* *** *** *** *** *** Your debugger is not using the correct symbols *** *** *** *** In order for this command to work properly, your symbol path *** *** must point to .pdb files that have full type information. *** *** *** *** Certain .pdb files (such as the public OS symbols) do not *** *** contain the required information. Contact the group that *** *** provided you with these symbols if you need this command to *** *** work. *** *** *** *** Type referenced: nt!_KPRCB *** *** *** ************************************************************************* ************************************************************************* *** *** *** *** *** Your debugger is not using the correct symbols *** *** *** *** In order for this command to work properly, your symbol path *** *** must point to .pdb files that have full type information. *** *** *** *** Certain .pdb files (such as the public OS symbols) do not *** *** contain the required information. Contact the group that *** *** provided you with these symbols if you need this command to *** *** work. *** *** *** *** Type referenced: nt!_KPRCB *** *** *** ************************************************************************* ************************************************************************* *** *** *** *** *** Your debugger is not using the correct symbols *** *** *** *** In order for this command to work properly, your symbol path *** *** must point to .pdb files that have full type information. *** *** *** *** Certain .pdb files (such as the public OS symbols) do not *** *** contain the required information. Contact the group that *** *** provided you with these symbols if you need this command to *** *** work. *** *** *** *** Type referenced: kernel32!pNlsUserInfo *** *** *** ************************************************************************* ************************************************************************* *** *** *** *** *** Your debugger is not using the correct symbols *** *** *** *** In order for this command to work properly, your symbol path *** *** must point to .pdb files that have full type information. *** *** *** *** Certain .pdb files (such as the public OS symbols) do not *** *** contain the required information. Contact the group that *** *** provided you with these symbols if you need this command to *** *** work. *** *** *** *** Type referenced: kernel32!pNlsUserInfo *** *** *** ************************************************************************* ADDITIONAL_DEBUG_TEXT: Use '!findthebuild' command to search for the target build information. If the build information is available, run '!findthebuild -s ; .reload' to set symbol path and load symbols. FAULTING_MODULE: 804d7000 nt DEBUG_FLR_IMAGE_TIMESTAMP: 4a3cae56 READ_ADDRESS: unable to get nt!MmSpecialPoolStart unable to get nt!MmSpecialPoolEnd unable to get nt!MmPoolCodeStart unable to get nt!MmPoolCodeEnd e1045040 FAULTING_IP: NullFilter!checkFile+5b [j:\drivers\testfiltr\tob\nullfilter.c @ 827] f9f9063b 83790400 cmp dword ptr [ecx+4],0 MM_INTERNAL_CODE: 1 DEFAULT_BUCKET_ID: DRIVER_FAULT BUGCHECK_STR: 0x50 LAST_CONTROL_TRANSFER: from 8053321e to 804e3592 STACK_TEXT: WARNING: Stack unwind information not available. Following frames may be wrong. f9c5b234 8053321e 00000003 806ef03c c0384114 nt!DbgBreakPointWithStatus+0x4 f9c5b614 8053380e 00000050 e1045040 00000000 nt!KeDeregisterBugCheckReasonCallback+0x6c7 f9c5b634 805241a0 00000050 e1045040 00000000 nt!KeBugCheckEx+0x1b f9c5b680 804e1718 00000000 e1045040 00000000 nt!IoSetFileOrigin+0xc1dc f9c5b73c 805646c3 00000000 00000005 f9c5b770 nt!Kei386EoiHelper+0x26bc f9c5b950 f9f907e8 e104503c f9c5b97f 003ca537 nt!SeDeleteAccessState+0x4a5 f9c5b9a0 f9946888 81310f5c f9c5b9c0 f9c5b9f0 NullFilter!DefenderPreCreate+0xb8 [j:\drivers\testfiltr\tob\nullfilter.c @ 960] f9c5ba00 f99482a0 00c5ba44 81310f00 8130f198 fltMgr!FltRequestOperationStatusCallback+0xf52 f9c5ba14 f9955217 f9c5ba44 f99536aa 00000000 fltMgr!FltGetIrpName+0x4e2 f9c5ba2c f9955742 f9c5ba44 813ae218 8130f018 fltMgr!FltProcessFileLock+0x1cdb f9c5ba60 804e37f7 8166eee8 8130f008 8130f008 fltMgr!FltProcessFileLock+0x2206 f9c5bb50 80563fec 817e9818 00000000 81616f30 nt!IofCallDriver+0x32 f9c5bbd8 805684da 00000000 f9c5bc18 00000040 nt!RtlEqualUnicodeString+0x4cf f9c5bc2c 8056cbeb 00000000 00000000 7b673001 nt!ObOpenObjectByName+0xdb f9c5bca8 8056ccba 0052e218 00100001 0052e1bc nt!FsRtlCurrentBatchOplock+0x212 f9c5bd04 8056cd82 0052e218 00100001 0052e1bc nt!IoCreateFile+0x4f f9c5bd44 804de7ec 0052e218 00100001 0052e1bc nt!NtOpenFile+0x27 f9c5bddc 804f88ea f9868b85 8167a7d0 00000000 nt!ZwYieldExecution+0xb78 f9c5be4c 7c9101bb 00000000 00000000 00000000 nt!KeInitializeTimer+0x107 00000000 f000ff53 f000ff53 f000ff53 f000ff53 ntdll!RtlAllocateHeap+0x117 00000000 00000000 f000ff53 f000ff53 f000ff53 0xf000ff53 STACK_COMMAND: .bugcheck ; kb FOLLOWUP_IP: NullFilter!checkFile+5b [j:\drivers\testfiltr\tob\nullfilter.c @ 827] f9f9063b 83790400 cmp dword ptr [ecx+4],0 FAULTING_SOURCE_CODE: 823: //RtlInitUnicodeString(&(notification.fName), 824: // 825: // Copy only as much as the buffer can hold 826: // > 827: RtlCopyMemory( ¬ification.Contents, 828: name->Buffer, 829: (ULONG)name->Length 830: ); 831: 832: replyLength = sizeof( DEFENDER_REPLY ); SYMBOL_NAME: NullFilter!checkFile+5b FOLLOWUP_NAME: MachineOwner MODULE_NAME: NullFilter IMAGE_NAME: NullFilter.sys BUCKET_ID: WRONG_SYMBOLS Followup: MachineOwner --------- Как пишет анализ, такие траблы не отловишь траем. Сбой происходит в разное время и при разных обстоятельствах. Что нужно проверять чтобы не получить бсод? Структуры: Код (Text): DEFENDER_NOTIFICATION notification; typedef struct _DEFENDER_NOTIFICATION { ULONG Reserved; WCHAR Contents[256]; } DEFENDER_NOTIFICATION, *PDEFENDER_NOTIFICATION; name - это *UNICODE_STRING. nullfilter - это мой драйвер. ОС win xp sp2 на virtualbox
Во-первых, убери амперсанд (&) в первом параметре в RtlCopyMemory(). Во-вторых, подгрузи наконец-то нормальные символы, ибо сейчас стек отображается некорректно.
Пути к символам: C:\WINDOWS\SYMBOLS.NET*http://msdl.microsoft.com/download/symbols;J:\drivers\testFiltr\tob\objchk_wxp_x86\i386 Амперсанд убрал. Ошибка осталась...
Но! как проверить его? Он не НУЛЛ и его буфер тоже. Пробывал ставить счетчик обращений на копирование, но всегда разное число получается...
указатель на name передается в функцию для отправки NTSTATUS checkFile(__in UNICODE_STRING * name, __out PBOOLEAN granted) из обработчика PreCreate Код (Text): status = FltGetFileNameInformation( Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo ); if (!NT_SUCCESS( status )) { return FLT_POSTOP_FINISHED_PROCESSING; } FltParseFileNameInformation( nameInfo ); // // Check if the extension matches the list of extensions we are interested in // catchstr = &nameInfo->Name; // // Release file name info, we're done with it // FltReleaseFileNameInformation( nameInfo ); granted = TRUE; __try{ checkFile(catchstr,&granted); } __except(EXCEPTION_EXECUTE_HANDLER){ return FLT_PREOP_SUCCESS_WITH_CALLBACK; }
Это, мягко говоря, не решение. А проблема у тебя в преждевременном вызове FltReleaseFileNameInformation().
да... действительно, слишком рано осводил... Но почему тогда сбой происходит не всегда? В теории я использую FltReleaseFileNameInformation задолго до того как передаю параметр функции.
Filter Manager - штука вообще объёмная и нетривиальная и писалась она далеко не студентами; это касается и внутреннего кэширования в том числе. Буфер, который возвращает тебе FltGetFileNameInformation() на самом деле не принадлежит тебе, он шарится между всеми фильтрами внутри фильтрующего ядра. Вызывая FltReleaseFileNameInformation() реально ты не освобождаешь память под имя, ты лишь сообщаешь Filter Manager'у, что оно тебе больше не нужно, а настоящее освобождение памяти произойдёт тогда, когда все фильтры скажут, что имя им больше не нужно плюс, возможно, что Filter Manager хранит имя в кэше ещё какое-то время по собственной инициативе.