Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results
The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.
Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/
I have used minispy as an example to block access to some processes for some files. I am sending the file path and process path to the user-mode application and in user-mode processing is done. Finally, the user-mode application returns TRUE/FALSE, and in kernel mode, if the response is TRUE from the user-mode application then Blocking is done.
This runs successfully for approx 45min and sometimes 1hr. And finally the blue screen system crash with an error as PAGE FAULT IN NONPAGED AREA.
I am unable to figure out why this is happening after some periods of time?
I am lost now. Please help me to identify the cause of this problem.
I will be very thankful to you.
Note: User Mode application takes 1-8 milli sec to respond after processing.
I have also attached a screenshot of BlueScreenView: https://ibb.co/Nmsv3Nc
Minifilter Code:
FLT_PREOP_CALLBACK_STATUS MiniPreRead(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext) { UNREFERENCED_PARAMETER(Data); UNREFERENCED_PARAMETER(FltObjects); UNREFERENCED_PARAMETER(CompletionContext); //DbgPrint("MiniPreRead"); PFLT_FILE_NAME_INFORMATION FileNameInfo = NULL; PMINISPY_NOTIFICATION notification = NULL; PUNICODE_STRING pni = NULL; BOOLEAN isBlock, shouldSkipThisFileName; ULONG seconds_to_wait; PVOID replyBuffer = NULL; ULONG replyLength; LARGE_INTEGER timeOut; NTSTATUS status; WCHAR Name[260] = { 0 }; WCHAR ProcessPath[260] = { 0 }; //update from usermode reply isBlock = FALSE; shouldSkipThisFileName = FALSE; //TODO: How much Waiting Time? seconds_to_wait = 5; timeOut.QuadPart = -((LONGLONG)seconds_to_wait * 10 * 1000 * 1000); status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &FileNameInfo); if (!NT_SUCCESS(status)) { goto cleanup; } status = FltParseFileNameInformation(FileNameInfo); if (!NT_SUCCESS(status)) { goto cleanup; } if (FileNameInfo->Name.MaximumLength >= 260) { goto cleanup; } RtlCopyMemory(Name, FileNameInfo->Name.Buffer, FileNameInfo->Name.MaximumLength); DbgPrint("\n\nMiniPreRead: FileName = %ws\n", Name); //skip systm process as fileName: ntoskrnl svchost, & fileType: .sys, .dll shouldSkipThisFileName = (wcsstr(Name, L"ntoskrnl") != NULL || wcsstr(Name, L"svchost") != NULL || wcsstr(Name, L".SYS") != NULL || wcsstr(Name, L".sys") != NULL || wcsstr(Name, L".DLL") != NULL || wcsstr(Name, L".dll") != NULL) ? TRUE : FALSE; //skip if path is not the drivePath if (wcsstr(Name, L"Device\\HarddiskVolume") == NULL) { goto cleanup; } if (shouldSkipThisFileName) { goto cleanup; } status = STATUS_UNSUCCESSFUL; status = GetProcessImageName(IoThreadToProcess(Data->Thread), &pni); //TODO: Improve by https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-getprocessimagefilenamea try { if (!NT_SUCCESS(status)) { leave; } if (NULL == pni->Buffer) { status = STATUS_INSUFFICIENT_RESOURCES; leave; } RtlCopyMemory(ProcessPath, pni->Buffer, pni->MaximumLength); //TODO: skip for system32 process for now if (wcsstr(ProcessPath, L"Windows\\System32") != NULL) { DbgPrint("\n\nMiniPreRead: kernelToUserMode: Skipping SystemProcess: %ws\n", ProcessPath); leave; } //TODO: skip Just for Testing purpose if (wcsstr(ProcessPath, L"explorer.exe") != NULL) { DbgPrint("\n\nMiniPreRead: kernelToUserMode: Skipping explorer: %ws\n", ProcessPath); leave; } DbgPrint("\n\nMiniPreRead: kernelToUserMode:| |\n"); DbgPrint("\n\nMiniPreRead: kernelToUserMode: Final psName: %ws\n", ProcessPath); DbgPrint("\n\nMiniPreRead: kernelToUserMode: Final FileName: %ws\n", Name); #ifndef KERNEL_TO_USER notification = ExAllocatePoolWithTag(NonPagedPool, sizeof(MINISPY_NOTIFICATION), SPY_TAG); if (NULL == notification) { status = STATUS_INSUFFICIENT_RESOURCES; leave; } RtlCopyMemory(¬ification->ProcessPath, ProcessPath, 260); RtlCopyMemory(¬ification->filePath, Name, 260); notification->msgCountNumId = ++globalCount % 10000000; //replyLength = sizeof(MINISPY_REPLY); //TODO For both userMode and kernel mode as recommend on doc: replyLength = sizeof(FILTER_REPLY_HEADER) + sizeof(MINISPY_REPLY); replyLength = sizeof(FILTER_REPLY_HEADER) + sizeof(MINISPY_REPLY); DbgPrint("\n\nMiniPreRead: kernelToUserMode: Waiting for usermode reply for MsgSendId: %d,ps: %ws...\n", notification->msgCountNumId, pni->Buffer); status = FltSendMessage(MiniSpyData.Filter, &MiniSpyData.ClientPort, notification, sizeof(MINISPY_NOTIFICATION), notification, &replyLength, NULL); if (STATUS_TIMEOUT == status) { DbgPrint("\n\nMiniPreRead: kernelToUserMode: timeout occured!\n"); } else if (STATUS_SUCCESS == status) { try { isBlock = ((PMINISPY_REPLY)notification)->res; } finally {} DbgPrint("\n\nMiniPreRead: kernelToUserMode: Reply isBlock: %d,MsgSendId: %d,ps: %ws\n", isBlock, ((PMINISPY_REPLY)notification)->msgCountId ,ProcessPath); } else { DbgPrint("\n\nMiniPreRead: kernelToUserMode: --- couldn't send processPath %ws to the user-mode, status 0x%X\n", ProcessPath, status); // STATUS_INSUFFICIENT_RESOURCES STATUS_PORT_DISCONNECTED STATUS_THREAD_IS_TERMINATING } #endif } finally { if (notification != NULL) { ExFreePoolWithTag(notification, SPY_TAG); } if (pni != NULL) { ExFreePool(pni); } } Blocking: if (isBlock) { KdPrint(("read file: %ws blocked \r\n", Name)); // only in DEBUG DbgPrint(("read file: %ws blocked \r\n", Name)); Data->IoStatus.Status = STATUS_ACCESS_DENIED; Data->IoStatus.Information = 0; if (FileNameInfo) { FltReleaseFileNameInformation(FileNameInfo); } return FLT_PREOP_COMPLETE; } cleanup: if (FileNameInfo) { FltReleaseFileNameInformation(FileNameInfo); } return FLT_PREOP_SUCCESS_NO_CALLBACK; }
Upcoming OSR Seminars | ||
---|---|---|
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead! | ||
Kernel Debugging | 16-20 October 2023 | Live, Online |
Developing Minifilters | 13-17 November 2023 | Live, Online |
Internals & Software Drivers | 4-8 Dec 2023 | Live, Online |
Writing WDF Drivers | 10-14 July 2023 | Live, Online |
Comments
what does
!anaylze -v
say Thats usually far more interesting that code@rod_widdowson I didn't understand what do you mean.
Open the dump file in WinDBG and show us what the result was.
The dump file is in C: \ Windows \ if you i not mistaken.
Google translator
@rod_widdowson Output of !analyze -v
Loading Dump File [C:\Windows\Minidump\030121-48640-01.dmp]
...
For analysis of this file, run !analyze -v
nt!KeBugCheckEx:
fffff807
58ff5a80 48894c2408 mov qword ptr [rsp+8],rcx ss:0018:ffffe18c
05c3d310=0000000000000050Loading Dump File [C:\WINDOWS\MEMORY.DMP]
Kernel Bitmap Dump File: Kernel address space is available, User address space may not be available.
Can't set dump file contexts
MachineInfo::SetContext failed - Thread: 00000285612F4E50 Handle: 1 Id: 1 - Error == 0x8000FFFF
***** Path validation summary ******
Response Time (ms) Location
Deferred srv*
Symbol search path is: srv*
Executable search path is:
Windows 10 Kernel Version 19041 MP (4 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Edition build lab: 19041.1.amd64fre.vb_release.191206-1406
Machine Name:
Kernel base = 0xfffff804
44800000 PsLoadedModuleList = 0xfffff804
4542a390Debug session time: Mon Mar 1 19:21:54.034 2021 (UTC + 5:30)
System Uptime: 0 days 5:50:54.796
Loading Kernel Symbols
...............................................................
................Page 11befc not present in the dump file. Type ".hh dbgerr004" for details
................................................
................................................................
......................................................
Loading User Symbols
PEB address is NULL !
Loading unloaded module list
................
nt!KeBugCheckEx:
fffff804
44bf5a80 48894c2408 mov qword ptr [rsp+8],rcx ss:0018:ffff8185
54785310=0000000000000050||1:3: kd> !analyze -v
PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced. This cannot be protected by try-except.
Typically the address is just plain bad or it is pointing at freed memory.
Arguments:
Arg1: ffff8b8e6a20eec0, memory referenced.
Arg2: 0000000000000010, value 0 = read operation, 1 = write operation.
Arg3: ffff8b8e6a20eec0, If non-zero, the instruction address which referenced the bad memory
address.
Arg4: 0000000000000002, (reserved)
Debugging Details:
KEY_VALUES_STRING: 1
ADDITIONAL_XML: 1
OS_BUILD_LAYERS: 1
BUGCHECK_CODE: 50
BUGCHECK_P1: ffff8b8e6a20eec0
BUGCHECK_P2: 10
BUGCHECK_P3: ffff8b8e6a20eec0
BUGCHECK_P4: 2
READ_ADDRESS: ffff8b8e6a20eec0 Paged session pool
MM_INTERNAL_CODE: 2
IMAGE_NAME: win32kbase.sys
MODULE_NAME: win32kbase
FAULTING_MODULE: ffff8b8e6a200000 win32kbase
BLACKBOXBSD: 1 (!blackboxbsd)
BLACKBOXNTFS: 1 (!blackboxntfs)
BLACKBOXPNP: 1 (!blackboxpnp)
BLACKBOXWINLOGON: 1
PROCESS_NAME: Registry
TRAP_FRAME: ffff8185547855b0 -- (.trap 0xffff8185547855b0)
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=ffff8b8e6a20eec0 rbx=0000000000000000 rcx=ffffca0e20ce12c0
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=ffff8b8e6a20eec0 rsp=ffff818554785748 rbp=0000000000000000
r8=ffff8185547857f0 r9=0000000000000000 r10=000000004f414f41
r11=0000000000001001 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei ng nz na po nc
win32kbase!UserIsUserCritSecIn:
ffff8b8e`6a20eec0 ?? ???
Resetting default scope
FAILED_INSTRUCTION_ADDRESS:
win32kbase!UserIsUserCritSecIn+0
ffff8b8e`6a20eec0 ?? ???
STACK_TEXT:
ffff8185
54785308 fffff804
44c1ebbb : 0000000000000050 ffff8b8e
6a20eec0 0000000000000010 ffff8185
547855b0 : nt!KeBugCheckExffff8185
54785310 fffff804
44a0c960 : 0000000000000000 00000000
00000010 ffff818554785630 00000000
00000000 : nt!MiSystemFault+0x1f43abffff8185
54785410 fffff804
44c03c5e : 0000000000000240 ffffca0e
0e968c50 0000000000000240 ffff8185
547856c1 : nt!MmAccessFault+0x400ffff8185
547855b0 ffff8b8e
6a20eec0 : fffff8045eeba14f 00000000
00000000 ffff818554785a30 00000000
00000020 : nt!KiPageFault+0x35effff8185
54785748 fffff804
5eeba14f : 0000000000000000 ffff8185
54785a30 0000000000000020 fffff804
5eecab6e : win32kbase!UserIsUserCritSecInffff8185
54785750 fffff804
5eebaa5d : ffff8185547858c8 ffffca0e
00000000 0000000000004a61 00000000
00000000 : SpyShelter!SpS_GetProcessPathW+0x15ebffff8185
547857e0 fffff804
44e0fc1c : ffffa40573e28200 ffff8185
547858c8 ffff8185547858c8 00000000
00000000 : SpyShelter!SpS_GetProcessPathW+0x1ef9ffff8185
54785810 fffff804
44e0fd8a : 0000000000000000 00000000
00000000 0000000000000000 ffffdc4d
19a20f67 : nt!ObpCallPreOperationCallbacks+0x10cffff8185
54785890 fffff804
44e2c20d : 0000000000000000 ffff8185
54785a20 ffffca0e25e0e050 ffffca0e
25e0e050 : nt!ObpPreInterceptHandleCreate+0xaaffff8185
54785900 fffff804
44de1029 : ffffa4057343d350 00000000
00000000 0038005f00620075 0079006b
00000000 : nt!ObpCreateHandle+0xa1dffff8185
54785af0 fffff804
4395104b : ffff818554786339 fffff804
44b3c67c 0000000000000208 ffffca0e
25c4c8d8 : nt!ObOpenObjectByPointer+0x1b9ffff8185
54785d70 fffff804
439512f9 : fffff80443952be0 00000000
00000200 0000000000000000 00000000
00000000 : minispy+0x104bffff8185
54785dd0 fffff804
4712608c : 0000000000000000 ffffca0e
25c4c7f0 ffffca0e25c4c8d8 ffffca0e
253efbb0 : minispy+0x12f9ffff8185
54786280 fffff804
47125b37 : ffff818554786400 00000000
00000003 ffffca0e26747600 00000000
00000000 : FLTMGR!FltpPerformPreCallbacksWorker+0x36cffff8185
547863a0 fffff804
47124b46 : ffff818554788000 ffff8185
54781000 0000000000000000 ffff8185
547864c0 : FLTMGR!FltpPassThroughInternal+0xc7ffff8185
547863f0 fffff804
471248bb : 0000000000000000 00000000
00000000 0000000000000000 fffff804
44e2b3c1 : FLTMGR!FltpPassThrough+0x1d6ffff8185
54786490 fffff804
44a52f55 : ffffca0e1f8d0630 00000000
00001000 0000000000000000 ffffffff
80004210 : FLTMGR!FltpDispatch+0x8bffff8185
547864f0 fffff804
44dfd878 : 0000000000000000 ffffca0e
267476a0 0000000000000001 ffffca0e
0f7ef501 : nt!IofCallDriver+0x55ffff8185
54786530 fffff804
44de59b9 : ffffca0e00000000 ffff8185
547867a0 ffffca0e1c7d16e0 ffff8185
547867a0 : nt!IopSynchronousServiceTail+0x1a8ffff8185
547865d0 fffff804
44c074b5 : ffffca0e20ce1910 ffffffff
80004210 0000000000000000 00000000
00000000 : nt!NtReadFile+0x599ffff8185
547866b0 fffff804
44bf98e0 : fffff80444b18673 ffffa405
86efe000 ffffffff80001b14 00000000
00000000 : nt!KiSystemServiceCopyEnd+0x25ffff8185
547868b8 fffff804
44b18673 : ffffa40586efe000 ffffffff
80001b14 0000000000000000 00000000
00000000 : nt!KiServiceLinkageffff8185
547868c0 fffff804
44ee07ac : ffffa40586efe000 ffff8185
54786a58 ffffa40500000000 ffffa405
86efe000 : nt!CmpDoFileRead+0xb7ffff8185
54786970 fffff804
44e873fc : 01d70ea209a2a5e3 ffffa405
970df000 0000000000000000 00000000
00000000 : nt!CmpFileRead+0x2cffff8185
547869c0 fffff804
44e858a3 : 01d70ea209a2a5e3 ffffa405
84d99e20 ffffa405970df000 ffffa405
84d99e20 : nt!HvpGetHiveHeader+0x7cffff8185
54786a00 fffff804
44e8857b : ffffa4057626f400 01d70ea2
09a2a5e3 0000000000000001 ffffa405
970df000 : nt!HvLoadHive+0xa7ffff8185
54786b50 fffff804
44e88b73 : 0000000000000000 ffff8185
54786c90 0000000000000001 ffffa405
970df000 : nt!HvHiveStartFileBacked+0x107ffff8185
54786b90 fffff804
44e639e1 : 0000000000000000 ffffca0e
0000009c ffff818554786ee0 00000000
00000000 : nt!CmpCreateHive+0x3d3ffff8185
54786de0 fffff804
44dd63dc : 0000000000000000 00000000
00000000 ffff8185547871d0 fffff804
44e2b3c1 : nt!CmpInitHiveFromFile+0x3a9ffff8185
54787020 fffff804
44e94ce3 : ffffa40584d99e20 00000000
00000000 ffffa40500000000 ffffa405
84d99e20 : nt!CmpCmdHiveOpen+0xdcffff8185
54787120 fffff804
44e8cf82 : 0000000000000000 ffff8185
00000010 0000000000000000 00000000
00000001 : nt!CmLoadAppKey+0x46bffff8185
547875a0 fffff804
44e8c77d : 00007ff800000000 ffffa405
7be70580 ffff818554787a00 fffffbbf
fc1c5d38 : nt!CmLoadDifferencingKey+0x7f6ffff8185
54787920 fffff804
44c074b5 : 0000000000000000 00000000
00000001 000000b333ffe148 ffff8185
54787a80 : nt!NtLoadKeyEx+0x5dffff8185
54787990 00007ff8
4510e734 : 0000000000000000 00000000
00000000 0000000000000000 00000000
00000000 : nt!KiSystemServiceCopyEnd+0x25000000b3
33ffe1e8 00000000
00000000 : 0000000000000000 00000000
00000000 0000000000000000 00000000
00000000 : 0x00007ff8`4510e734SYMBOL_NAME: win32kbase!UserIsUserCritSecIn+0
STACK_COMMAND: .thread ; .cxr ; kb
BUCKET_ID_FUNC_OFFSET: 0
FAILURE_BUCKET_ID: AV_INVALID_BAD_IP_win32kbase!UserIsUserCritSecIn
OS_VERSION: 10.0.19041.1
BUILDLAB_STR: vb_release
OSPLATFORM_TYPE: x64
OSNAME: Windows 10
FAILURE_ID_HASH: {c8670668-72de-2a31-2f67-c17c5864267c}
Followup: MachineOwner
||1:3: kd> lmvm win32kbase
Browse full module list
start end module name
ffff8b8e
6a200000 ffff8b8e
6a4da000 win32kbase # (pdb symbols) C:\ProgramData\Dbg\sym\win32kbase.pdb\E51C1F9B0FA0D0F8FD417E3DB89E9E911\win32kbase.pdbLoaded symbol image file: win32kbase.sys
Mapped memory image file: C:\ProgramData\Dbg\sym\win32kbase.sys\A6BD5AD22da000\win32kbase.sys
Image path: \SystemRoot\System32\win32kbase.sys
Image name: win32kbase.sys
Browse all global symbols functions data
Image was built with /Brepro flag.
Timestamp: A6BD5AD2 (This is a reproducible build file hash, not a timestamp)
CheckSum: 002CC779
ImageSize: 002DA000
Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4
Information from resource tables:
please analyze this output and help me to get out of the exception. I am completely lost now & need help from the OSR community.
I'd turn off "SpyShelter"
@rod_widdowson I haven't installed SpyShelter.
All the more reason to get rid of it.
-scott
OSR
@Scott_Noone_(OSR) please show some helping hand. I am unable to fix it out
Well, I think maybe, it tends to copy some information into user mode, and it is not available, "the user's address space may not be available" according to the dump file, try the following, before call RtlCopyMemory, make sure the user is connected to the driver.
SpyShelter (whatever that is) has a kernel component and it's trying to call an undocumented Win32K function:
You're in the Registry process which does not map Win32K, so you get a crash from SpyShelter calling an invalid address.
Best thing to do is uninstall SpyShelter
-scott
OSR
@rod_widdowson @Scott_Noone_(OSR) Thank you so much both for the info you provided. It was SpyShelter who causing the problem. I am very thankful to you
@Scott_Noone_(OSR) @rod_widdowson Crash is only from this code. When trying to get the process name then a crash occurs if spyShelter also running. so is there any wrong with this code?
Code: ToGetProcessName
You need to learn to debug your code. Have you set up kernel debugging with WinDbg yet?
-scott
OSR
Yes. I have done setting up the kernel debugging with windbg.
What steps have you taken to debug the problem?
-scott
OSR
@Scott_Noone_(OSR) I have followed this https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/getting-started-with-windbg--kernel-mode-#:~:text=On%20the%20host%20computer%2C%20open,in%20Debugging%20Tools%20for%20Windows.
Now the stack shows Line Number 702 and 1009 of file minispy.c
STACK_TEXT
LINE 702:
status = ObOpenObjectByPointer(eProcess,
0, NULL, 0, 0, KernelMode, &hProcess);
if (!NT_SUCCESS(status))
{
DbgPrint("ObOpenObjectByPointer Failed: %08x\n", status);
return status;
}
LINE 1009:
status = GetProcessImageName(IoThreadToProcess(Data->Thread), &pni);
Did you look at the stack? It's the same crash as before:
Get rid of SpyShelter.
-scott
OSR
@Scott_Noone_(OSR) So why system crashes due to my program. If the only spyShelter runs then no crash happens. Once my program runs along with SpyShelter then a crash happens.
Since the crash happens only in getting process path. So should I pass ProcessId to user-mode and then find the process path in user-mode and then do processing accordingly?
You're opening a Process Object from the context of a process (Registry) that does not have a valid session space. This is valid but unusual. SpyShelter has a bug in their code and they don't handle this properly.
So, last time: SpyShelter has a bug. Disable it and move on. If you can't live without SpyShelter then you need to contact them and have them fix their code.
-scott
OSR
Thank you so much @Scott_Noone_(OSR).