When dealing with legacy filters the approach to get the callbacks is pretty well-known and it relies on looking at the fields in the DRIVER_OBJECT:
Of course, legacy filters also have a couple of other sets of entrypoints, the FastIO routines and the FS_FILTER_CALLBACKS, which we might need to set breakpoints on:0: kd> !drvobj sr Driver object (82332290) is for: \FileSystem\sr Driver Extension List: (id , addr) Device Object list: 8207d830 8213add0 8235e020 8238e248 8238e030 0: kd> dt 82332290 nt!_DRIVER_OBJECT +0x000 Type : 0n4 +0x002 Size : 0n168 +0x004 DeviceObject : 0x8207d830 _DEVICE_OBJECT +0x008 Flags : 0x12 +0x00c DriverStart : 0xf8489000 Void +0x010 DriverSize : 0x11f00 +0x014 DriverSection : 0x823eb998 Void +0x018 DriverExtension : 0x82332338 _DRIVER_EXTENSION +0x01c DriverName : _UNICODE_STRING "\FileSystem\sr" +0x024 HardwareDatabase : 0x8067d260 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM" +0x028 FastIoDispatch : 0xf848b4c0 _FAST_IO_DISPATCH +0x02c DriverInit : 0xf8498fd4 long sr!GsDriverEntry+0 +0x030 DriverStartIo : (null) +0x034 DriverUnload : (null) +0x038 MajorFunction : [28] 0xf848e726 long sr!SrCreate+0 0: kd> dps 82332290+0x38 L0n28 823322c8 f848e726 sr!SrCreate 823322cc f8489428 sr!SrPassThrough 823322d0 f8489428 sr!SrPassThrough 823322d4 f8489428 sr!SrPassThrough 823322d8 f8489320 sr!SrWrite … 82332330 f8489428 sr!SrPassThrough 82332334 f848dd52 sr!SrPnp
Things are similar for minifilters. There is a !fltkd command that tries to make things easier, but in my oppinion it could do a better job at helping out. For one, even though the callbacks are defined on a per-filter basis, the !fltkd.filter command that lists the contents of the filter structure doesn't actually show the registered callbacks, and instead one must use the the !fltkd.instance command on one of the instances of the filter , command that has a special flag that can be used to see the callbacks:0: kd> dt 0xf848b4c0 _FAST_IO_DISPATCH nt!_FAST_IO_DISPATCH +0x000 SizeOfFastIoDispatch : 0x70 +0x004 FastIoCheckIfPossible : 0xf8490914 unsigned char sr!SrFastIoCheckIfPossible+0 +0x008 FastIoRead : 0xf8490962 unsigned char sr!SrFastIoRead+0 +0x00c FastIoWrite : 0xf84909b0 unsigned char sr!SrFastIoWrite+0 ... +0x060 FastIoQueryOpen : 0xf8490f30 unsigned char sr!SrFastIoQueryOpen+0 +0x064 ReleaseForModWrite : (null) +0x068 AcquireForCcFlush : (null) +0x06c ReleaseForCcFlush : (null) 0: kd> dt 0x82332338 nt!_DRIVER_EXTENSION +0x000 DriverObject : 0x82332290 _DRIVER_OBJECT +0x004 AddDevice : (null) +0x008 Count : 0 +0x00c ServiceKeyName : _UNICODE_STRING "sr" +0x014 ClientDriverExtension : (null) +0x018 FsFilterCallbacks : 0x8236d238 _FS_FILTER_CALLBACKS 0: kd> dt 0x8236d238 _FS_FILTER_CALLBACKS nt!_FS_FILTER_CALLBACKS +0x000 SizeOfFsFilterCallbacks : 0x38 +0x004 Reserved : 0 +0x008 PreAcquireForSectionSynchronization : 0xf8490c30 long sr!SrPreAcquireForSectionSynchronization+0 +0x00c PostAcquireForSectionSynchronization : (null) ... +0x030 PreReleaseForModifiedPageWriter : (null) +0x034 PostReleaseForModifiedPageWriter : (null)
However, the above mentioned debugger function returns pointers to a CALLBACK_NODE structure from which one can figure out what the actual function is. Please note that the structure contains unions and so a lot of the members actually point to the same function. It generally is pretty clear which member should be used depending on the function for which we got the CALLBACK_NODE. For this example I took the IRP_MJ_CREATE callback and the NORMALIZE_NAME_COMPONENT callback:1: kd> !fltkd.filters Filter List: 92cddd1c "Frame 0" FLT_FILTER: 94144008 "luafv" "135000" FLT_INSTANCE: 94146008 "luafv" "135000" FLT_FILTER: 92cdda58 "FileInfo" "45000" FLT_INSTANCE: 930e7730 "FileInfo" "45000" FLT_INSTANCE: 93448dc8 "FileInfo" "45000" FLT_INSTANCE: 9357c340 "FileInfo" "45000" FLT_INSTANCE: 93584560 "FileInfo" "45000" FLT_INSTANCE: 9359a948 "FileInfo" "45000" 1: kd> !fltkd.filter 94144008 FLT_FILTER: 94144008 "luafv" "135000" FLT_OBJECT: 94144008 [02000000] Filter RundownRef : 0x00000008 (4) PointerCount : 0x00000001 PrimaryLink : [92cdda64-92cddd1c] Frame : 92cddcc0 "Frame 0" Flags : [00000006] FilteringInitiated NameProvider DriverObject : 941427a8 FilterLink : [92cdda64-92cddd1c] PreVolumeMount : 81f980cc luafv!LuafvPreRedirect PostVolumeMount : 00000000 (null) FilterUnload : 00000000 (null) InstanceSetup : 81fa462b luafv!LuafvInstanceSetup InstanceQueryTeardown : 00000000 (null) InstanceTeardownStart : 00000000 (null) InstanceTeardownComplete : 00000000 (null) ActiveOpens : (941440dc) mCount=1 Communication Port List : (94144108) mCount=0 Client Port List : (94144134) mCount=0 VerifierExtension : 00000000 Operations : 94144164 OldDriverUnload : 00000000 (null) SupportedContexts : (941440a0) VolumeContexts : (941440a0) InstanceContexts : (941440a4) ALLOCATE_CONTEXT_NODE: 94144a20 "luafv" [01] LookasideList (size=608) FileContexts : (941440a8) StreamContexts : (941440ac) StreamHandleContexts : (941440b0) ALLOCATE_CONTEXT_NODE: 94144ae8 "luafv" [01] LookasideList (size=20) TransactionContext : (941440b4) InstanceList : (94144038) FLT_INSTANCE: 94146008 "luafv" "135000" 1: kd> !fltkd.instance 94146008 4 FLT_INSTANCE: 94146008 "luafv" "135000" CallbackNodes : (94146054) NORMALIZE_NAME_COMPONENT (-22) CALLBACK_NODE: 94146584 Inst:(94146008,"luafv","\Device\HarddiskVolume2") "luafv" "135000" GENERATE_FILE_NAME (-21) CALLBACK_NODE: 9414656c Inst:(94146008,"luafv","\Device\HarddiskVolume2") "luafv" "135000" MDL_WRITE_COMPLETE (-18) CALLBACK_NODE: 9414611c Inst:(94146008,"luafv","\Device\HarddiskVolume2") "luafv" "135000" PREPARE_MDL_WRITE (-17) ... ACQUIRE_FOR_SECTION_SYNC (-1) CALLBACK_NODE: 941462b4 Inst:(94146008,"luafv","\Device\HarddiskVolume2") "luafv" "135000" CREATE (0) CALLBACK_NODE: 941462cc Inst:(94146008,"luafv","\Device\HarddiskVolume2") "luafv" "135000" CREATE_NAMED_PIPE (1) CALLBACK_NODE: 941462e4 Inst:(94146008,"luafv","\Device\HarddiskVolume2") "luafv" "135000" ... SET_QUOTA (26) CALLBACK_NODE: 9414653c Inst:(94146008,"luafv","\Device\HarddiskVolume2") "luafv" "135000" PNP (27) CALLBACK_NODE: 94146554 Inst:(94146008,"luafv","\Device\HarddiskVolume2") "luafv" "135000"
Personally I found this approach somewhat cumbersome to use and so what I've done is to list the array of callback directly from the filter object. Please note that the array ends with a record for the IRP_MJ_OPERATION_END pseudo-operation (which is just an array terminator) which has the value of 0x80. This is actually the array of FLT_OPERATION_REGISTRATION structures that is passed to FltRegisterFilter() function in the FLT_REGISTRATION.OperationRegistration field. As such this array does not include the name generation callbacks.1: kd> dt 941462cc fltmgr!_CALLBACK_NODE +0x000 CallbackLinks : _LIST_ENTRY [ 0x93448edc - 0x9343757c ] +0x008 Instance : 0x94146008 _FLT_INSTANCE +0x00c PreOperation : 0x81f9f263 _FLT_PREOP_CALLBACK_STATUS luafv!LuafvPreCreate+0 +0x010 PostOperation : 0x81fa24e8 _FLT_POSTOP_CALLBACK_STATUS luafv!LuafvPostCreate+0 +0x00c GenerateFileName : 0x81f9f263 long luafv!LuafvPreCreate+0 +0x00c NormalizeNameComponent : 0x81f9f263 long luafv!LuafvPreCreate+0 +0x00c NormalizeNameComponentEx : 0x81f9f263 long luafv!LuafvPreCreate+0 +0x010 NormalizeContextCleanup : 0x81fa24e8 void luafv!LuafvPostCreate+0 +0x014 Flags : 0 (No matching name) 1: kd> dt 94146584 fltmgr!_CALLBACK_NODE +0x000 CallbackLinks : _LIST_ENTRY [ 0x934374cc - 0x934374cc ] +0x008 Instance : 0x94146008 _FLT_INSTANCE +0x00c PreOperation : 0x81fa09b2 _FLT_PREOP_CALLBACK_STATUS luafv!LuafvNormalizeNameComponentEx+0 +0x010 PostOperation : (null) +0x00c GenerateFileName : 0x81fa09b2 long luafv!LuafvNormalizeNameComponentEx+0 +0x00c NormalizeNameComponent : 0x81fa09b2 long luafv!LuafvNormalizeNameComponentEx+0 +0x00c NormalizeNameComponentEx : 0x81fa09b2 long luafv!LuafvNormalizeNameComponentEx+0 +0x010 NormalizeContextCleanup : (null) +0x014 Flags : 4 ( CBNFL_USE_NAME_CALLBACK_EX )
: kd> dt -oca60 94144164 _FLT_OPERATION_REGISTRATION
fltmgr!_FLT_OPERATION_REGISTRATION
[0] @ 94144164 MajorFunction 0xec '' Flags 0 PreOperation 0x81f980cc _FLT_PREOP_CALLBACK_STATUS luafv!LuafvPreRedirect+0 PostOperation (null) Reserved1 (null)
[1] @ 94144178 MajorFunction 0xed '' Flags 0 PreOperation 0x81f980cc _FLT_PREOP_CALLBACK_STATUS luafv!LuafvPreRedirect+0 PostOperation (null) Reserved1 (null)
[2] @ 9414418c MajorFunction 0xee '' Flags 0 PreOperation 0x81f98005 _FLT_PREOP_CALLBACK_STATUS luafv!LuafvPreWrite+0 PostOperation (null) Reserved1 (null)
[3] @ 941441a0 MajorFunction 0xef '' Flags 0 PreOperation 0x81f980cc _FLT_PREOP_CALLBACK_STATUS luafv!LuafvPreRedirect+0 PostOperation (null) Reserved1 (null)
…
[45] @ 941444e8 MajorFunction 0x19 '' Flags 0 PreOperation 0x81f980cc _FLT_PREOP_CALLBACK_STATUS luafv!LuafvPreRedirect+0 PostOperation (null) Reserved1 (null)
[46] @ 941444fc MajorFunction 0x1a '' Flags 0 PreOperation 0x81f980cc _FLT_PREOP_CALLBACK_STATUS luafv!LuafvPreRedirect+0 PostOperation (null) Reserved1 (null)
[47] @ 94144510 MajorFunction 0x1b '' Flags 0 PreOperation 0x81fa3330 _FLT_PREOP_CALLBACK_STATUS luafv!LuafvPrePnp+0 PostOperation (null) Reserved1 (null)
[48] @ 94144524 MajorFunction 0x80 '' Flags 0 PreOperation (null) PostOperation (null) Reserved1 (null)
...
No comments:
Post a Comment