Enabling driver verifier on ntoskrnl.exe causes a different FltRegisterFilter to be imported

The version of windows (Windows 11 x64 22H2):

Windows 10 Kernel Version 22621 MP (2 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Edition build lab: 22621.1.amd64fre.ni_release.220506-1250
Kernel base = 0xfffff804`6da1c000 PsLoadedModuleList = 0xfffff804`6e62f410
Debug session time: Fri Mar 21 08:49:52.198 2025 (UTC + 3:00)

Enabled all verifier options except:

  • low resource
  • systematic low resource
  • code integrity checks

I also added ntoskrnl.exe to the verified driver list (along with my driver).
Loading the driver, when it calls FltStartFiltering, it will bugcheck with the following stack trace:

0b ffffa80b`a5fec220 fffff804`6edf53a8     : 00000000`0000000d 00000000`00000000 00000000`00000000 ffffe68d`a830ccf8 : FLTMGR!FltpvValidateVerifierState+0x85
0c ffffa80b`a5fec250 fffff804`6edcb6dc     : ffffe68d`a950ec50 00000000`00000000 00000000`00000000 00000000`00000001 : FLTMGR!FltvInstanceSetup+0x38
0d ffffa80b`a5fec2b0 fffff804`6edcc420     : 00000000`00000000 ffffe68d`a830cc30 ffffe68d`82d367c4 ffffe68d`a950ec50 : FLTMGR!FltpDoInstanceSetupNotification+0x7c
0e ffffa80b`a5fec320 fffff804`6edcba94     : 00000000`00000000 fffff804`6e62f400 ffffe68d`00000001 ffffa80b`a5fec420 : FLTMGR!FltpInitInstance+0x490
0f ffffa80b`a5fec3c0 fffff804`6edcb853     : 00000000`00000000 ffffe68d`82d36790 ffffe68d`82d367a0 00000000`0000001a : FLTMGR!FltpCreateInstanceFromName+0x1e0
10 ffffa80b`a5fec4a0 fffff804`6eddb87d     : 00000000`0000002c ffffe68d`82d367a0 ffffe68d`81e36948 ffffffff`80002e20 : FLTMGR!FltpEnumerateRegistryInstances+0xe3
11 ffffa80b`a5fec530 fffff804`6eddb75b     : 00000000`00000000 ffffe68d`bfaeee01 ffffe68d`cacd7001 00000000`00010246 : FLTMGR!FltpDoVolumeNotificationForNewFilter+0xa5
12 ffffa80b`a5fec570 fffff800`34b10c05     : 00000000`00000000 00000000`00000000 ffffe68d`cacd7001 fffff800`34afd330 : FLTMGR!FltStartFiltering+0x2b

The cause of the bugcheck in the verifier function is because the VerifierExtension (of _FLT_VERIFIER_EXTENSION type) structure has it's Flags (_FLT_VERIFIER_EXTENSION_FLAGS) set to 0, when it should be FLTVFL_REGISTER_FILTER_THUNK (0x80000000):

0: kd> u FLTMGR!FltpvValidateVerifierState+70
FLTMGR!FltpvValidateVerifierState+0x70:
fffff804`6edac470 833800          cmp     dword ptr [rax],0
fffff804`6edac473 7c10            jl      FLTMGR!FltpvValidateVerifierState+0x85 (fffff804`6edac485)
fffff804`6edac475 b950000000      mov     ecx,50h
fffff804`6edac47a 4c8bc7          mov     r8,rdi
fffff804`6edac47d 488bd3          mov     rdx,rbx
fffff804`6edac480 e857240400      call    FLTMGR!FltpvPrintErrors (fffff804`6edee8dc)

When ntoskrnl.exe is not verified, this check will not cause a bugcheck, because the FLTMGR!FltRegisterFilter correctly sets the flags value to FLTVFL_REGISTER_FILTER_THUNK, because the actual imported function will be FLTMGR!FltvRegisterFilter (with the "v"), which actually calls FltRegisterFilter and sets the flag:

fffff804`6edf5ded e85e6cfeff      call    FLTMGR!FltRegisterFilter (fffff804`6eddca50)
fffff804`6edf5df2 8bf8            mov     edi,eax
fffff804`6edf5df4 85c0            test    eax,eax
fffff804`6edf5df6 7819            js      FLTMGR!FltvRegisterFilter+0x31 (fffff804`6edf5e11)
fffff804`6edf5df8 488b0b          mov     rcx,qword ptr [rbx]
fffff804`6edf5dfb 488b91e8000000  mov     rdx,qword ptr [rcx+0E8h]
fffff804`6edf5e02 f0810a00000080  lock or dword ptr [rdx],80000000h
fffff804`6edf5e09 488b0b          mov     rcx,qword ptr [rbx]

When ntoskrnl.exe is verified, the imported function will be directly FLTMGR!FltRegisterFilter, which does not set the flag in the VerifierExtension structure.