Hey. Im trying to block image mappings based on hash, I filter on IRP_MJ_AQUIRE_SECTION_SYNCHRONIZATION . Here’s my preop routine
FLT_PREOP_CALLBACK_STATUS
RattleEyePreOperation(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_Flt_CompletionContext_Outptr_ PVOID* CompletionContext
)
{
NTSTATUS status;
ULONG MappedImageHash;
ULONG BytesRead = 0;
FILE_STANDARD_INFORMATION FileInfo;
PVOID DiskContent;
LARGE_INTEGER ByteOffset;
ByteOffset.QuadPart = 0;
UNREFERENCED_PARAMETER(CompletionContext);
// get file size
status = FltQueryInformationFile(FltObjects->Instance, FltObjects->FileObject, &FileInfo, sizeof(FileInfo), FileStandardInformation, NULL);
if (!NT_SUCCESS(status))
return FLT_PREOP_SUCCESS_NO_CALLBACK;
if (&FltObjects->FileObject->FileName && FltObjects->FileObject)
{
DiskContent = FltAllocatePoolAlignedWithTag(FltObjects->Instance, NonPagedPool, FileInfo.EndOfFile.QuadPart, TAG);
if (!DiskContent)
return FLT_PREOP_SUCCESS_NO_CALLBACK;
status = FltReadFile(FltObjects->Instance, FltObjects->FileObject, &ByteOffset, FileInfo.EndOfFile.QuadPart, DiskContent, FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET | FLTFL_IO_OPERATION_NON_CACHED, &BytesRead, NULL, NULL);
if (!NT_SUCCESS(status))
{
FltFreePoolAlignedWithTag(FltObjects->Instance, DiskContent, TAG);
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
MappedImageHash = Djb2HashFile(DiskContent, (SIZE_T)FileInfo.EndOfFile.QuadPart);
if (MappedImageHash == 0x389ae136)
{
DbgPrint("[*] Blocking loading of image %wZ !\n", FltObjects->FileObject->FileName);
FltFreePoolAlignedWithTag(FltObjects->Instance, DiskContent, TAG);
Data->IoStatus.Status = STATUS_INVALID_IMAGE_HASH;
return FLT_PREOP_COMPLETE;
}
FltFreePoolAlignedWithTag(FltObjects->Instance, DiskContent, TAG);
}
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
I get a BSOD after a few seconds or minutes
EXCEPTION_RECORD: fffffe0581b8dc48 – (.exr 0xfffffe0581b8dc48)
ExceptionAddress: fffff8040b189bae (Ntfs!NtfsAcquirePagingShared+0x000000000000004a)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 0000000000000000
Parameter[1]: 0000000000000010
Attempt to read from address 0000000000000010
anyone has a clue what did I do wrong here ?
Stop code often being CACHE_MANAGER
What’s the stack?
My instinct is that you are confusing Cc and NTFS by causing some sort of reentrancy. Possibly creating a section while creating a section? I know your io is non cached but NTFS is at liberty to do what it wants when it gets told to do a read and that might involve refreshing the SOP.
I’d also poke around for transactions (my go to blame point for ‘that’s weird’).
@rod_widdowson said:
What’s the stack?
My instinct is that you are confusing Cc and NTFS by causing some sort of reentrancy. Possibly creating a section while creating a section? I know your io is non cached but NTFS is at liberty to do what it wants when it gets told to do a read and that might involve refreshing the SOP.
I’d also poke around for transactions (my go to blame point for ‘that’s weird’).
The Stack: ( It works if I ignore requests from kernel mode… still curious what the issue is tho)
00 fffff8057ad17f82 : ffffbf86
e6d44430 fffff8057ab7df60 00000000
00000000 0000000000000000 : nt!DbgBreakPointWithStatus 01 fffff805
7ad17566 : 0000000000000003 ffffbf86
e6d44430 fffff8057ac14a40 00000000
00000034 : nt!KiBugCheckDebugBreak+0x12
02 fffff8057abfd747 : ffffffc3
ee0071e3 ffffbf86e6d45760 fffff805
7a871f40 ffffbf86e6d41000 : nt!KeBugCheck2+0x946 03 fffff805
7ac1a5db : 0000000000000034 00000000
00051384 ffffbf86e6d45aa8 ffffbf86
e6d452e0 : nt!KeBugCheckEx+0x107
04 fffff8057abd01bf : ffffbf86
00000003 fffff8057a871f50 ffffbf86
e6d41000 ffffbf86e6d47000 : nt!CcCachemapUninitWorkerThread$filt$0+0x42 05 fffff805
7abf927e : fffff8057a871f50 ffffbf86
e6d45aa8 ffffbf86e6d46a90 ffffbf86
e6d450e0 : nt!_C_specific_handler+0x9f
06 fffff8057ac07d2f : fffff805
7a8d3c2c ffffbf86e6d450d0 fffff805
7abf9214 fffff8057ab02fe1 : nt!_GSHandlerCheck_SEH+0x6a 07 fffff805
7aaca3c7 : ffffbf86e6d450d0 00000000
00000000 ffffbf86e6d46a90 fffff805
7ab02fe1 : nt!RtlpExecuteHandlerForException+0xf
08 fffff8057aac94e6 : ffffbf86
e6d45aa8 ffffbf86e6d457e0 ffffbf86
e6d45aa8 ffffaf8294458d00 : nt!RtlDispatchException+0x297 09 fffff805
7ac1186c : 0000000000001000 ffffbf86
e6d45b50 ffff800000000000 00000000
00000000 : nt!KiDispatchException+0x186
0a fffff8057ac0d2bd : 00000000
00000003 0000000000000000 000004e8
fffffb30 000004d0fffffb30 : nt!KiExceptionDispatch+0x12c 0b fffff805
7f8d090e : ffffe4879aa4d6d0 fffff805
7aaa3b85 8000000000000000 00000000
00000000 : nt!KiPageFault+0x43d
0c fffff8057f8c7964 : 00000000
00000000 ffffbf86e6d45f60 ffffe487
9ab03100 0000000000000000 : Ntfs!NtfsAcquirePagingResourceExclusive+0x36 0d fffff805
7f8c926c : ffffe487a023e4e8 ffffe487
a3bf2a20 ffffe48710000000 00000000
00000000 : Ntfs!NtfsCommonRead+0xf44
0e fffff8057aa10665 : ffffe487
9ff7fa20 ffffe487a3bf2a20 ffffe487
a3bf2a20 ffffe4879a9a1d60 : Ntfs!NtfsFsdRead+0x1fc 0f fffff805
796c710f : ffffe4879ff7fa20 ffffbf86
e6d460d0 0000000000000000 fffff805
796c5f7a : nt!IofCallDriver+0x55
10 fffff805796c879d : ffffbf86
e6d460d0 ffffe487a24d5b18 ffffe487
9ff7fb08 ffffe4879ff7fb08 : FLTMGR!FltpLegacyProcessingAfterPreCallbacksCompleted+0x28f 11 fffff805
796cf3ce : ffffe4879ff7fa20 ffffe487
9ff7fb08 0000000000000000 ffffe487
98103f70 : FLTMGR!FltPerformSynchronousIo+0x3dd
12 fffff805796c1111 : 00000000
72746579 0000000010000000 ffffab72
00000000 ffffab55b921e920 : FLTMGR!FltReadFileEx+0xe2ae 13 fffff805
962210f9 : ffffbf86e6d463e8 ffffe487
9fe8fc10 ffffbf86e6d463e8 00000000
00000000 : FLTMGR!FltReadFile+0x51
14 fffff805796c64cc : ffffe487
a0158a20 0000000000000000 ffffe487
a0158b08 0000000000000008 : RattleEye+0x10f9 15 fffff805
796c2844 : 0000000000000000 00000000
000000ff ffffbf86e6d46500 ffffbf86
00000000 : FLTMGR!FltpPerformPreCallbacksWorker+0x36c
16 fffff8057aa64e47 : ffffbf86
e6d47000 ffffe4879ab03180 ffffbf86
e6d41000 ffffaf8294458ef0 : FLTMGR!FltpPreFsFilterOperation+0x184 17 fffff805
7ae21d31 : fffff805796c8eb0 00000000
00000000 ffffbf86e6d46890 fffff805
796c26c0 : nt!FsFilterPerformCallbacks+0xe7
18 fffff8057ae21a27 : ffffe487
9fcaf010 fffff8057aa06d7a ffffe487
9fcaf010 ffffbf8600000000 : nt!FsRtlAcquireFileExclusiveCommon+0x121 19 fffff805
7aa57bcb : ffffe487a4831170 7fffffff
00000000 ffffe48700000000 ffffe487
987d2b00 : nt!FsRtlAcquireFileExclusive+0x17
1a fffff8057ab057b1 : ffffe487
a581d8a0 0000000000000000 ffffe487
987d2b00 ffffe48700000000 : nt!CcWriteBehindInternal+0x31b 1b fffff805
7ab02fe1 : ffffe48798715080 ffffe487
98674560 ffffe487a581d8a0 ffffe487
9c565000 : nt!CcWriteBehind+0x91
1c fffff8057aa50545 : ffffe487
98715080 ffffe48798702ab0 ffffe487
98674560 0000000000000000 : nt!CcCachemapUninitWorkerThread+0xf1 1d fffff805
7ab0e6f5 : ffffe48798715080 00000000
00000080 ffffe4879867b040 00000000
00000000 : nt!ExpWorkerThread+0x105
1e fffff8057ac06278 : ffff9981
eb1a0180 ffffe48798715080 fffff805
7ab0e6a0 0000000000000000 : nt!PspSystemThreadStartup+0x55 1f 00000000
00000000 : ffffbf86e6d47000 ffffbf86
e6d41000 0000000000000000 00000000
00000000 : nt!KiStartSystemThread+0x28
The cache is dirty, so the section has already been created. When you issue the non cached read you are therefor causing a flush and NTFS is making some weird assumption).
You are working well outside the bounds of “normal” at this stage. The Cache Manager is subtle and quick to anger.
@rod_widdowson said:
The cache is dirty, so the section has already been created. When you issue the non cached read you are therefor causing a flush and NTFS is making some weird assumption).
You are working well outside the bounds of “normal” at this stage. The Cache Manager is subtle and quick to anger.
hmm probably a noob question here but this confused me a bit : when does the IRP_MJ_AQUIRE_FOR_SECTION_SYNCHRONIZATION pre operation gets called ? I thought it’s for creation of shareable section objects but seems like as you said it was triggered after the section has already been created?
I Thought it’s for creation of shareable section objects
Actually - it rather looks like it is being called to tear down the (non existent) section.
Certainly NTFS doesn’t like you doing IO at that stage,
@rod_widdowson said:
I Thought it’s for creation of shareable section objects
Actually - it rather looks like it is being called to tear down the (non existent) section.
Certainly NTFS doesn’t like you doing IO at that stage,
It works by removing the the noncached flag in the FltReadFile. I’m pretty sure it’s called for creation of section objects since BattleEye (anti cheat) is blocking image loads this way and It indeed works. maybe its called under other conditions which is what im not sure about