00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "mi.h"
00021
00022 #define THUNKED_API
00023
00024
THUNKED_API
00025 PVOID
00026
VerifierAllocatePool(
00027 IN POOL_TYPE PoolType,
00028 IN SIZE_T NumberOfBytes
00029 );
00030
00031
THUNKED_API
00032 PVOID
00033
VerifierAllocatePoolWithTag(
00034 IN POOL_TYPE PoolType,
00035 IN SIZE_T NumberOfBytes,
00036 IN ULONG Tag
00037 );
00038
00039
THUNKED_API
00040 PVOID
00041
VerifierAllocatePoolWithQuotaTag(
00042 IN POOL_TYPE PoolType,
00043 IN SIZE_T NumberOfBytes,
00044 IN ULONG Tag
00045 );
00046
00047
THUNKED_API
00048 PVOID
00049
VerifierAllocatePoolWithTagPriority(
00050 IN POOL_TYPE PoolType,
00051 IN SIZE_T NumberOfBytes,
00052 IN ULONG Tag,
00053 IN EX_POOL_PRIORITY Priority
00054 );
00055
00056 PVOID
00057
VeAllocatePoolWithTagPriority(
00058 IN POOL_TYPE PoolType,
00059 IN SIZE_T NumberOfBytes,
00060 IN ULONG Tag,
00061 IN EX_POOL_PRIORITY Priority,
00062 IN PVOID CallingAddress
00063 );
00064
00065
VOID
00066
VerifierFreePool(
00067 IN PVOID P
00068 );
00069
00070
THUNKED_API
00071
VOID
00072
VerifierFreePoolWithTag(
00073 IN PVOID P,
00074 IN ULONG TagToFree
00075 );
00076
00077
THUNKED_API
00078 LONG
00079
VerifierSetEvent(
00080 IN
PRKEVENT Event,
00081 IN KPRIORITY Increment,
00082 IN BOOLEAN Wait
00083 );
00084
00085
THUNKED_API
00086 KIRQL
00087
FASTCALL
00088
VerifierKfRaiseIrql (
00089 IN KIRQL NewIrql
00090 );
00091
00092
THUNKED_API
00093
VOID
00094
FASTCALL
00095
VerifierKfLowerIrql (
00096 IN KIRQL NewIrql
00097 );
00098
00099
THUNKED_API
00100
VOID
00101
VerifierKeRaiseIrql (
00102 IN KIRQL NewIrql,
00103 OUT PKIRQL OldIrql
00104 );
00105
00106
THUNKED_API
00107
VOID
00108
VerifierKeLowerIrql (
00109 IN KIRQL NewIrql
00110 );
00111
00112
THUNKED_API
00113
VOID
00114
VerifierKeAcquireSpinLock (
00115 IN PKSPIN_LOCK SpinLock,
00116 OUT PKIRQL OldIrql
00117 );
00118
00119
THUNKED_API
00120
VOID
00121
VerifierKeReleaseSpinLock (
00122 IN PKSPIN_LOCK SpinLock,
00123 IN KIRQL NewIrql
00124 );
00125
00126
THUNKED_API
00127 KIRQL
00128
FASTCALL
00129
VerifierKfAcquireSpinLock (
00130 IN PKSPIN_LOCK SpinLock
00131 );
00132
00133
THUNKED_API
00134
VOID
00135
FASTCALL
00136
VerifierKfReleaseSpinLock (
00137 IN PKSPIN_LOCK SpinLock,
00138 IN KIRQL NewIrql
00139 );
00140
00141
THUNKED_API
00142
VOID
00143
VerifierKeInitializeTimerEx(
00144 IN
PKTIMER Timer,
00145 IN TIMER_TYPE Type
00146 );
00147
00148
THUNKED_API
00149
VOID
00150
VerifierKeInitializeTimer(
00151 IN
PKTIMER Timer
00152 );
00153
00154
THUNKED_API
00155 BOOLEAN
00156
FASTCALL
00157
VerifierExTryToAcquireFastMutex (
00158 IN
PFAST_MUTEX FastMutex
00159 );
00160
00161
THUNKED_API
00162
VOID
00163
FASTCALL
00164
VerifierExAcquireFastMutex (
00165 IN
PFAST_MUTEX FastMutex
00166 );
00167
00168
THUNKED_API
00169
VOID
00170
FASTCALL
00171
VerifierExReleaseFastMutex (
00172 IN
PFAST_MUTEX FastMutex
00173 );
00174
00175
THUNKED_API
00176
VOID
00177
FASTCALL
00178
VerifierExAcquireFastMutexUnsafe (
00179 IN
PFAST_MUTEX FastMutex
00180 );
00181
00182
THUNKED_API
00183
VOID
00184
FASTCALL
00185
VerifierExReleaseFastMutexUnsafe (
00186 IN
PFAST_MUTEX FastMutex
00187 );
00188
00189
THUNKED_API
00190 BOOLEAN
00191
VerifierExAcquireResourceExclusive(
00192 IN
PERESOURCE Resource,
00193 IN BOOLEAN Wait
00194 );
00195
00196
THUNKED_API
00197
VOID
00198
FASTCALL
00199
VerifierExReleaseResource(
00200 IN
PERESOURCE Resource
00201 );
00202
00203
THUNKED_API
00204 KIRQL
00205
FASTCALL
00206
VerifierKeAcquireQueuedSpinLock (
00207 IN KSPIN_LOCK_QUEUE_NUMBER Number
00208 );
00209
00210
THUNKED_API
00211
VOID
00212
FASTCALL
00213
VerifierKeReleaseQueuedSpinLock (
00214 IN KSPIN_LOCK_QUEUE_NUMBER Number,
00215 IN KIRQL OldIrql
00216 );
00217
00218
THUNKED_API
00219 BOOLEAN
00220
VerifierSynchronizeExecution (
00221 IN
PKINTERRUPT Interrupt,
00222 IN
PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,
00223 IN PVOID SynchronizeContext
00224 );
00225
00226
THUNKED_API
00227
VOID
00228
VerifierProbeAndLockPages (
00229 IN OUT
PMDL MemoryDescriptorList,
00230 IN KPROCESSOR_MODE AccessMode,
00231 IN
LOCK_OPERATION Operation
00232 );
00233
00234
THUNKED_API
00235
VOID
00236
VerifierProbeAndLockProcessPages (
00237 IN OUT
PMDL MemoryDescriptorList,
00238 IN
PEPROCESS Process,
00239 IN KPROCESSOR_MODE AccessMode,
00240 IN LOCK_OPERATION Operation
00241 );
00242
00243
THUNKED_API
00244
VOID
00245
VerifierProbeAndLockSelectedPages (
00246 IN OUT
PMDL MemoryDescriptorList,
00247 IN PFILE_SEGMENT_ELEMENT SegmentArray,
00248 IN KPROCESSOR_MODE AccessMode,
00249 IN LOCK_OPERATION Operation
00250 );
00251
00252
VOID
00253
VerifierUnlockPages (
00254 IN OUT
PMDL MemoryDescriptorList
00255 );
00256
00257
VOID
00258
VerifierUnmapLockedPages (
00259 IN PVOID BaseAddress,
00260 IN
PMDL MemoryDescriptorList
00261 );
00262
00263
VOID
00264
VerifierUnmapIoSpace (
00265 IN PVOID BaseAddress,
00266 IN SIZE_T NumberOfBytes
00267 );
00268
00269
THUNKED_API
00270 PVOID
00271
VerifierMapIoSpace (
00272 IN PHYSICAL_ADDRESS PhysicalAddress,
00273 IN SIZE_T NumberOfBytes,
00274 IN
MEMORY_CACHING_TYPE CacheType
00275 );
00276
00277
THUNKED_API
00278 PVOID
00279
VerifierMapLockedPages (
00280 IN
PMDL MemoryDescriptorList,
00281 IN KPROCESSOR_MODE AccessMode
00282 );
00283
00284
THUNKED_API
00285 PVOID
00286
VerifierMapLockedPagesSpecifyCache (
00287 IN
PMDL MemoryDescriptorList,
00288 IN KPROCESSOR_MODE AccessMode,
00289 IN MEMORY_CACHING_TYPE CacheType,
00290 IN PVOID RequestedAddress,
00291 IN ULONG BugCheckOnFailure,
00292 IN MM_PAGE_PRIORITY Priority
00293 );
00294
00295
VOID
00296
VerifierFreeTrackedPool(
00297 IN PVOID VirtualAddress,
00298 IN SIZE_T ChargedBytes,
00299 IN LOGICAL CheckType,
00300 IN LOGICAL SpecialPool
00301 );
00302
00303
VOID
00304
ViPrintString (
00305 IN PUNICODE_STRING DriverName
00306 );
00307
00308 LOGICAL
00309
ViInjectResourceFailure (
00310 VOID
00311 );
00312
00313
VOID
00314
ViTrimAllSystemPagableMemory (
00315 VOID
00316 );
00317
00318
VOID
00319
ViInitializeEntry (
00320 IN
PMI_VERIFIER_DRIVER_ENTRY Verifier,
00321 IN LOGICAL FirstLoad
00322 );
00323
00324 LOGICAL
00325
ViReservePoolAllocation (
00326 IN
PMI_VERIFIER_DRIVER_ENTRY Verifier
00327 );
00328
00329 ULONG_PTR
00330
ViInsertPoolAllocation (
00331 IN
PMI_VERIFIER_DRIVER_ENTRY Verifier,
00332 IN PVOID VirtualAddress,
00333 IN PVOID CallingAddress,
00334 IN SIZE_T NumberOfBytes,
00335 IN ULONG Tag
00336 );
00337
00338
VOID
00339
ViCancelPoolAllocation (
00340 IN
PMI_VERIFIER_DRIVER_ENTRY Verifier
00341 );
00342
00343
VOID
00344
ViReleasePoolAllocation (
00345 IN
PMI_VERIFIER_DRIVER_ENTRY Verifier,
00346 IN PVOID VirtualAddress,
00347 IN ULONG_PTR ListIndex,
00348 IN SIZE_T ChargedBytes
00349 );
00350
00351
VOID
00352
KfSanityCheckRaiseIrql (
00353 IN KIRQL NewIrql
00354 );
00355
00356
VOID
00357
KfSanityCheckLowerIrql (
00358 IN KIRQL NewIrql
00359 );
00360
00361 MM_DRIVER_VERIFIER_DATA MmVerifierData;
00362
00363
00364
00365
00366
00367 ULONG
VerifierModifyableOptions;
00368 ULONG
VerifierOptionChanges;
00369
00370 LIST_ENTRY
MiSuspectDriverList;
00371
00372 LOGICAL
MiVerifyAllDrivers;
00373
00374 WCHAR
MiVerifyRandomDrivers;
00375
00376 ULONG
MiActiveVerifies;
00377
00378 ULONG
MiActiveVerifierThunks;
00379
00380 ULONG
MiNoPageOnRaiseIrql;
00381
00382 ULONG
MiVerifierStackProtectTime;
00383
00384 LOGICAL
MmDontVerifyRandomDrivers =
TRUE;
00385
00386 LOGICAL
VerifierSystemSufficientlyBooted;
00387
00388 LARGE_INTEGER
VerifierRequiredTimeSinceBoot = {(ULONG)(40 * 1000 * 1000 * 10), 1};
00389
00390 LOGICAL
VerifierIsTrackingPool =
FALSE;
00391
00392 KSPIN_LOCK
VerifierListLock;
00393
00394 KSPIN_LOCK
VerifierPoolLock;
00395
00396 FAST_MUTEX VerifierPoolMutex;
00397
00398 PRTL_BITMAP
VerifierLargePagedPoolMap;
00399
00400 LIST_ENTRY
MiVerifierDriverAddedThunkListHead;
00401
00402 extern LOGICAL
MmSpecialPoolCatchOverruns;
00403
00404 LOGICAL
KernelVerifier =
FALSE;
00405
00406 ULONG
KernelVerifierTickPage = 0x7;
00407
00408 LOGICAL
00409
MiEnableVerifier (
00410 IN PLDR_DATA_TABLE_ENTRY DataTableEntry
00411 );
00412
00413
VOID
00414
ViInsertVerifierEntry (
00415 IN
PMI_VERIFIER_DRIVER_ENTRY Verifier
00416 );
00417
00418 PVOID
00419
ViPostPoolAllocation (
00420 IN PVOID VirtualAddress,
00421 IN SIZE_T NumberOfBytes,
00422 IN POOL_TYPE PoolType,
00423 IN ULONG Tag,
00424 IN PVOID CallingAddress
00425 );
00426
00427
PMI_VERIFIER_DRIVER_ENTRY
00428
ViLocateVerifierEntry (
00429 IN PVOID SystemAddress
00430 );
00431
00432
VOID
00433
MiVerifierCheckThunks (
00434 IN PLDR_DATA_TABLE_ENTRY DataTableEntry
00435 );
00436
00437
#ifdef ALLOC_PRAGMA
00438
#pragma alloc_text(INIT,MiInitializeDriverVerifierList)
00439
#if defined(_X86_)
00440
#pragma alloc_text(INIT,MiEnableKernelVerifier)
00441
#endif
00442
#pragma alloc_text(PAGE,MiApplyDriverVerifier)
00443
#pragma alloc_text(PAGE,MiEnableVerifier)
00444
#pragma alloc_text(PAGE,ViPrintString)
00445
#pragma alloc_text(PAGE,MmGetVerifierInformation)
00446
#pragma alloc_text(PAGE,MmSetVerifierInformation)
00447
#pragma alloc_text(PAGE,MmAddVerifierThunks)
00448
#pragma alloc_text(PAGELK,MiVerifierCheckThunks)
00449
#pragma alloc_text(PAGELK,MiVerifyingDriverUnloading)
00450
00451
#pragma alloc_text(PAGEVRFY,VerifierProbeAndLockPages)
00452
#pragma alloc_text(PAGEVRFY,VerifierProbeAndLockProcessPages)
00453
#pragma alloc_text(PAGEVRFY,VerifierProbeAndLockSelectedPages)
00454
#pragma alloc_text(PAGEVRFY,VerifierUnlockPages)
00455
#pragma alloc_text(PAGEVRFY,VerifierMapIoSpace)
00456
#pragma alloc_text(PAGEVRFY,VerifierMapLockedPages)
00457
#pragma alloc_text(PAGEVRFY,VerifierMapLockedPagesSpecifyCache)
00458
#pragma alloc_text(PAGEVRFY,VerifierUnmapLockedPages)
00459
#pragma alloc_text(PAGEVRFY,VerifierUnmapIoSpace)
00460
#pragma alloc_text(PAGEVRFY,VerifierAllocatePool)
00461
#pragma alloc_text(PAGEVRFY,VerifierAllocatePoolWithTag)
00462
#pragma alloc_text(PAGEVRFY,VerifierAllocatePoolWithTagPriority)
00463
#pragma alloc_text(PAGEVRFY,VerifierAllocatePoolWithQuotaTag)
00464
#pragma alloc_text(PAGEVRFY,VerifierFreePool)
00465
#pragma alloc_text(PAGEVRFY,VerifierFreePoolWithTag)
00466
#pragma alloc_text(PAGEVRFY,VerifierKfRaiseIrql)
00467
#pragma alloc_text(PAGEVRFY,VerifierKfLowerIrql)
00468
#pragma alloc_text(PAGEVRFY,VerifierKeRaiseIrql)
00469
#pragma alloc_text(PAGEVRFY,VerifierKeLowerIrql)
00470
#pragma alloc_text(PAGEVRFY,VerifierKeAcquireSpinLock)
00471
#pragma alloc_text(PAGEVRFY,VerifierKeReleaseSpinLock)
00472
#pragma alloc_text(PAGEVRFY,VerifierKfAcquireSpinLock)
00473
#pragma alloc_text(PAGEVRFY,VerifierKfReleaseSpinLock)
00474
#pragma alloc_text(PAGEVRFY,VerifierKeInitializeTimer)
00475
#pragma alloc_text(PAGEVRFY,VerifierKeInitializeTimerEx)
00476
#pragma alloc_text(PAGEVRFY,VerifierExTryToAcquireFastMutex)
00477
#pragma alloc_text(PAGEVRFY,VerifierExAcquireFastMutex)
00478
#pragma alloc_text(PAGEVRFY,VerifierExReleaseFastMutex)
00479
#pragma alloc_text(PAGEVRFY,VerifierExAcquireFastMutexUnsafe)
00480
#pragma alloc_text(PAGEVRFY,VerifierExReleaseFastMutexUnsafe)
00481
#pragma alloc_text(PAGEVRFY,VerifierExAcquireResourceExclusive)
00482
#pragma alloc_text(PAGEVRFY,VerifierExReleaseResource)
00483
#pragma alloc_text(PAGEVRFY,VerifierKeAcquireQueuedSpinLock)
00484
#pragma alloc_text(PAGEVRFY,VerifierKeReleaseQueuedSpinLock)
00485
#pragma alloc_text(PAGEVRFY,VerifierSynchronizeExecution)
00486
00487
#pragma alloc_text(PAGEVRFY,VerifierFreeTrackedPool)
00488
00489
#pragma alloc_text(PAGEVRFY,VeAllocatePoolWithTagPriority)
00490
#pragma alloc_text(PAGEVRFY,ViInsertVerifierEntry)
00491
#pragma alloc_text(PAGEVRFY,ViLocateVerifierEntry)
00492
#pragma alloc_text(PAGEVRFY,ViPostPoolAllocation)
00493
#pragma alloc_text(PAGEVRFY,ViInjectResourceFailure)
00494
#pragma alloc_text(PAGEVRFY,ViTrimAllSystemPagableMemory)
00495
#pragma alloc_text(PAGEVRFY,ViInitializeEntry)
00496
#pragma alloc_text(PAGEVRFY,ViReservePoolAllocation)
00497
#pragma alloc_text(PAGEVRFY,ViInsertPoolAllocation)
00498
#pragma alloc_text(PAGEVRFY,ViCancelPoolAllocation)
00499
#pragma alloc_text(PAGEVRFY,ViReleasePoolAllocation)
00500
#pragma alloc_text(PAGEVRFY,KfSanityCheckRaiseIrql)
00501
#pragma alloc_text(PAGEVRFY,KfSanityCheckLowerIrql)
00502
#endif
00503
00504 typedef struct _VERIFIER_THUNKS {
00505 PDRIVER_VERIFIER_THUNK_ROUTINE
PristineRoutine;
00506 PDRIVER_VERIFIER_THUNK_ROUTINE
NewRoutine;
00507 ULONG
Flag;
00508 }
VERIFIER_THUNKS, *
PVERIFIER_THUNKS;
00509
00510 typedef struct _DRIVER_SPECIFIED_VERIFIER_THUNKS {
00511 LIST_ENTRY
ListEntry;
00512 PLDR_DATA_TABLE_ENTRY
DataTableEntry;
00513 ULONG
NumberOfThunks;
00514 }
DRIVER_SPECIFIED_VERIFIER_THUNKS, *
PDRIVER_SPECIFIED_VERIFIER_THUNKS;
00515
00516
#if defined (_X86_)
00517
00518
#define VI_KE_RAISE_IRQL 0
00519
#define VI_KE_LOWER_IRQL 1
00520
#define VI_KE_ACQUIRE_SPINLOCK 2
00521
#define VI_KE_RELEASE_SPINLOCK 3
00522
#define VI_KF_RAISE_IRQL 4
00523
#define VI_KF_LOWER_IRQL 5
00524
#define VI_KF_ACQUIRE_SPINLOCK 6
00525
#define VI_KF_RELEASE_SPINLOCK 7
00526
#define VI_KE_ACQUIRE_QUEUED_SPINLOCK 8
00527
#define VI_KE_RELEASE_QUEUED_SPINLOCK 9
00528
00529
#define VI_HALMAX 10
00530
00531 PVOID MiKernelVerifierOriginalCalls[VI_HALMAX];
00532
00533
#endif
00534
00535
THUNKED_API
00536
VOID
00537 VerifierProbeAndLockPages (
00538 IN OUT
PMDL MemoryDescriptorList,
00539 IN KPROCESSOR_MODE AccessMode,
00540 IN LOCK_OPERATION Operation
00541 )
00542 {
00543 KIRQL CurrentIrql;
00544
00545 CurrentIrql = KeGetCurrentIrql();
00546
if (CurrentIrql >
DISPATCH_LEVEL) {
00547
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
00548 0x70,
00549 CurrentIrql,
00550 (ULONG_PTR)MemoryDescriptorList,
00551 (ULONG_PTR)AccessMode);
00552 }
00553
00554
if (
ViInjectResourceFailure () ==
TRUE) {
00555
ExRaiseStatus (STATUS_WORKING_SET_QUOTA);
00556 }
00557
00558
MmProbeAndLockPages (MemoryDescriptorList, AccessMode, Operation);
00559 }
00560
00561
THUNKED_API
00562
VOID
00563 VerifierProbeAndLockProcessPages (
00564 IN OUT
PMDL MemoryDescriptorList,
00565 IN
PEPROCESS Process,
00566 IN KPROCESSOR_MODE AccessMode,
00567 IN LOCK_OPERATION Operation
00568 )
00569 {
00570 KIRQL CurrentIrql;
00571
00572 CurrentIrql = KeGetCurrentIrql();
00573
if (CurrentIrql >
DISPATCH_LEVEL) {
00574
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
00575 0x71,
00576 CurrentIrql,
00577 (ULONG_PTR)MemoryDescriptorList,
00578 (ULONG_PTR)Process);
00579 }
00580
00581
if (
ViInjectResourceFailure () ==
TRUE) {
00582
ExRaiseStatus (STATUS_WORKING_SET_QUOTA);
00583 }
00584
00585
MmProbeAndLockProcessPages (MemoryDescriptorList,
00586 Process,
00587 AccessMode,
00588 Operation);
00589 }
00590
00591
THUNKED_API
00592
VOID
00593 VerifierProbeAndLockSelectedPages (
00594 IN OUT
PMDL MemoryDescriptorList,
00595 IN PFILE_SEGMENT_ELEMENT SegmentArray,
00596 IN KPROCESSOR_MODE AccessMode,
00597 IN LOCK_OPERATION Operation
00598 )
00599 {
00600 KIRQL CurrentIrql;
00601
00602 CurrentIrql = KeGetCurrentIrql();
00603
if (CurrentIrql >
APC_LEVEL) {
00604
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
00605 0x72,
00606 CurrentIrql,
00607 (ULONG_PTR)MemoryDescriptorList,
00608 (ULONG_PTR)AccessMode);
00609 }
00610
00611
if (
ViInjectResourceFailure () ==
TRUE) {
00612
ExRaiseStatus (STATUS_WORKING_SET_QUOTA);
00613 }
00614
00615
MmProbeAndLockSelectedPages (MemoryDescriptorList,
00616 SegmentArray,
00617 AccessMode,
00618 Operation);
00619 }
00620
00621
00622
00623
00624
00625
00626 #define VI_BAD_MAPPERS_MAX 100
00627
00628 KSPIN_LOCK
ViBadMapperLock;
00629 PVOID
ViBadMappers[
VI_BAD_MAPPERS_MAX];
00630
00631 LOGICAL
00632 ViAddBadMapper (
00633 IN PVOID BadMapper
00634 )
00635 {
00636 ULONG i;
00637 KIRQL OldIrql;
00638 LOGICAL Added;
00639
00640 Added =
FALSE;
00641 ExAcquireSpinLock (&
ViBadMapperLock, &OldIrql);
00642
00643
for (i = 0; i <
VI_BAD_MAPPERS_MAX; i += 1) {
00644
if (
ViBadMappers[i] == BadMapper) {
00645
break;
00646 }
00647
00648
if (
ViBadMappers[i] ==
NULL) {
00649
ViBadMappers[i] = BadMapper;
00650 Added =
TRUE;
00651
break;
00652 }
00653 }
00654
00655 ExReleaseSpinLock (&
ViBadMapperLock, OldIrql);
00656
00657
return Added;
00658 }
00659
00660
THUNKED_API
00661 PVOID
00662 VerifierMapIoSpace (
00663 IN PHYSICAL_ADDRESS PhysicalAddress,
00664 IN SIZE_T NumberOfBytes,
00665 IN MEMORY_CACHING_TYPE CacheType
00666 )
00667 {
00668 KIRQL CurrentIrql;
00669
00670 CurrentIrql = KeGetCurrentIrql();
00671
if (CurrentIrql >
DISPATCH_LEVEL) {
00672
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
00673 0x73,
00674 CurrentIrql,
00675 (ULONG_PTR)PhysicalAddress.LowPart,
00676 NumberOfBytes);
00677 }
00678
00679
if (
ViInjectResourceFailure () ==
TRUE) {
00680
return NULL;
00681 }
00682
00683
return MmMapIoSpace (PhysicalAddress, NumberOfBytes, CacheType);
00684 }
00685
00686
THUNKED_API
00687 PVOID
00688 VerifierMapLockedPages (
00689 IN
PMDL MemoryDescriptorList,
00690 IN KPROCESSOR_MODE AccessMode
00691 )
00692 {
00693 PVOID CallingAddress;
00694 PVOID CallersCaller;
00695 KIRQL CurrentIrql;
00696
00697
#if defined (_X86_)
00698
RtlGetCallersAddress(&CallingAddress, &CallersCaller);
00699
#else
00700
CallingAddress = (PVOID)_ReturnAddress();
00701
#endif
00702
00703 CurrentIrql = KeGetCurrentIrql();
00704
00705
if (AccessMode ==
KernelMode) {
00706
if (CurrentIrql >
DISPATCH_LEVEL) {
00707
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
00708 0x74,
00709 CurrentIrql,
00710 (ULONG_PTR)MemoryDescriptorList,
00711 (ULONG_PTR)AccessMode);
00712 }
00713 }
00714
else {
00715
if (CurrentIrql >
APC_LEVEL) {
00716
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
00717 0x75,
00718 CurrentIrql,
00719 (ULONG_PTR)MemoryDescriptorList,
00720 (ULONG_PTR)AccessMode);
00721 }
00722 }
00723
00724
if ((MemoryDescriptorList->MdlFlags &
MDL_MAPPING_CAN_FAIL) == 0) {
00725
00726
if (
ViAddBadMapper (CallingAddress) ==
TRUE) {
00727
00728
00729
00730
00731
00732
00733
DbgPrint (
"*******************************************************************************\n");
00734
DbgPrint (
"* *\n");
00735
00736
DbgPrint (
"* The Driver Verifier has detected the driver at address %p\n", CallingAddress);
00737
DbgPrint (
"* is calling MmMapLockedPages instead of MmMapLockedPagesSpecifyCache.\n");
00738
DbgPrint (
"* This can cause the system to needlessly bugcheck whenever system\n");
00739
DbgPrint (
"* resources are low. This driver needs to be fixed.\n");
00740
00741
DbgPrint (
"* *\n");
00742
DbgPrint (
"*******************************************************************************\n");
00743 }
00744 }
00745
00746
return MmMapLockedPages (MemoryDescriptorList, AccessMode);
00747 }
00748
00749
THUNKED_API
00750 PVOID
00751 VerifierMapLockedPagesSpecifyCache (
00752 IN
PMDL MemoryDescriptorList,
00753 IN KPROCESSOR_MODE AccessMode,
00754 IN MEMORY_CACHING_TYPE CacheType,
00755 IN PVOID RequestedAddress,
00756 IN ULONG BugCheckOnFailure,
00757 IN MM_PAGE_PRIORITY Priority
00758 )
00759 {
00760 PVOID CallingAddress;
00761 PVOID CallersCaller;
00762 KIRQL CurrentIrql;
00763
00764
#if defined (_X86_)
00765
RtlGetCallersAddress(&CallingAddress, &CallersCaller);
00766
#else
00767
CallingAddress = (PVOID)_ReturnAddress();
00768
#endif
00769
00770 CurrentIrql = KeGetCurrentIrql();
00771
if (AccessMode ==
KernelMode) {
00772
if (CurrentIrql >
DISPATCH_LEVEL) {
00773
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
00774 0x76,
00775 CurrentIrql,
00776 (ULONG_PTR)MemoryDescriptorList,
00777 (ULONG_PTR)AccessMode);
00778 }
00779 }
00780
else {
00781
if (CurrentIrql >
APC_LEVEL) {
00782
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
00783 0x77,
00784 CurrentIrql,
00785 (ULONG_PTR)MemoryDescriptorList,
00786 (ULONG_PTR)AccessMode);
00787 }
00788 }
00789
00790
if ((MemoryDescriptorList->MdlFlags &
MDL_MAPPING_CAN_FAIL) ||
00791 (BugCheckOnFailure == 0)) {
00792
00793
if (
ViInjectResourceFailure () ==
TRUE) {
00794
return NULL;
00795 }
00796 }
00797
else {
00798
00799
00800
00801
00802
00803
00804
00805
if (
ViAddBadMapper (CallingAddress) ==
TRUE) {
00806
00807
DbgPrint (
"*******************************************************************************\n");
00808
DbgPrint (
"* *\n");
00809
00810
DbgPrint (
"* The Driver Verifier has detected the driver at address %p\n", CallingAddress);
00811
DbgPrint (
"* is not calling the safe version of MmMapLockedPagesSpecifyCache.\n");
00812
DbgPrint (
"* This can cause the system to needlessly bugcheck whenever system\n");
00813
DbgPrint (
"* resources are low. This driver needs to be fixed.\n");
00814
00815
DbgPrint (
"* *\n");
00816
DbgPrint (
"*******************************************************************************\n");
00817 }
00818 }
00819
00820
return MmMapLockedPagesSpecifyCache (MemoryDescriptorList,
00821 AccessMode,
00822 CacheType,
00823 RequestedAddress,
00824 BugCheckOnFailure,
00825 Priority);
00826 }
00827
00828
VOID
00829 VerifierUnlockPages (
00830 IN OUT
PMDL MemoryDescriptorList
00831 )
00832 {
00833 KIRQL CurrentIrql;
00834
00835 CurrentIrql = KeGetCurrentIrql();
00836
if (CurrentIrql >
DISPATCH_LEVEL) {
00837
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
00838 0x78,
00839 CurrentIrql,
00840 (ULONG_PTR)MemoryDescriptorList,
00841 0);
00842 }
00843
00844
if ((MemoryDescriptorList->MdlFlags &
MDL_PAGES_LOCKED) == 0) {
00845
00846
00847
00848
00849
00850
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
00851 0x7C,
00852 (ULONG_PTR)MemoryDescriptorList,
00853 (ULONG_PTR)MemoryDescriptorList->MdlFlags,
00854 0);
00855 }
00856
00857
if (MemoryDescriptorList->MdlFlags &
MDL_SOURCE_IS_NONPAGED_POOL) {
00858
00859
00860
00861
00862
00863
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
00864 0x7D,
00865 (ULONG_PTR)MemoryDescriptorList,
00866 (ULONG_PTR)MemoryDescriptorList->MdlFlags,
00867 0);
00868 }
00869
00870
MmUnlockPages (MemoryDescriptorList);
00871 }
00872
00873
VOID
00874 VerifierUnmapLockedPages (
00875 IN PVOID BaseAddress,
00876 IN
PMDL MemoryDescriptorList
00877 )
00878 {
00879 KIRQL CurrentIrql;
00880
00881 CurrentIrql = KeGetCurrentIrql();
00882
00883
if (BaseAddress > MM_HIGHEST_USER_ADDRESS) {
00884
if (CurrentIrql >
DISPATCH_LEVEL) {
00885
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
00886 0x79,
00887 CurrentIrql,
00888 (ULONG_PTR)BaseAddress,
00889 (ULONG_PTR)MemoryDescriptorList);
00890 }
00891 }
00892
else {
00893
if (CurrentIrql >
APC_LEVEL) {
00894
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
00895 0x7A,
00896 CurrentIrql,
00897 (ULONG_PTR)BaseAddress,
00898 (ULONG_PTR)MemoryDescriptorList);
00899 }
00900 }
00901
00902
MmUnmapLockedPages (BaseAddress, MemoryDescriptorList);
00903 }
00904
00905
VOID
00906 VerifierUnmapIoSpace (
00907 IN PVOID BaseAddress,
00908 IN SIZE_T NumberOfBytes
00909 )
00910 {
00911 KIRQL CurrentIrql;
00912
00913 CurrentIrql = KeGetCurrentIrql();
00914
if (CurrentIrql >
DISPATCH_LEVEL) {
00915
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
00916 0x7B,
00917 CurrentIrql,
00918 (ULONG_PTR)BaseAddress,
00919 (ULONG_PTR)NumberOfBytes);
00920 }
00921
00922
MmUnmapIoSpace (BaseAddress, NumberOfBytes);
00923 }
00924
00925
THUNKED_API
00926 PVOID
00927 VerifierAllocatePool(
00928 IN POOL_TYPE PoolType,
00929 IN SIZE_T NumberOfBytes
00930 )
00931 {
00932 PVOID CallingAddress;
00933 PVOID CallersCaller;
00934
PMI_VERIFIER_DRIVER_ENTRY Verifier;
00935
00936
#if defined (_X86_)
00937
RtlGetCallersAddress(&CallingAddress, &CallersCaller);
00938
#else
00939
CallingAddress = (PVOID)_ReturnAddress();
00940
#endif
00941
00942
if (
KernelVerifier ==
TRUE) {
00943
00944 Verifier =
ViLocateVerifierEntry (CallingAddress);
00945
00946
if ((Verifier ==
NULL) ||
00947 ((Verifier->
Flags &
VI_VERIFYING_DIRECTLY) == 0)) {
00948
00949
return ExAllocatePool (PoolType |
POOL_DRIVER_MASK, NumberOfBytes);
00950 }
00951 PoolType |=
POOL_DRIVER_MASK;
00952 }
00953
00954
MmVerifierData.AllocationsWithNoTag += 1;
00955
00956
return VeAllocatePoolWithTagPriority (PoolType,
00957 NumberOfBytes,
00958 'parW',
00959
HighPoolPriority,
00960 CallingAddress);
00961 }
00962
00963
THUNKED_API
00964 PVOID
00965 VerifierAllocatePoolWithTag(
00966 IN POOL_TYPE PoolType,
00967 IN SIZE_T NumberOfBytes,
00968 IN ULONG Tag
00969 )
00970 {
00971 PVOID CallingAddress;
00972 PVOID CallersCaller;
00973
PMI_VERIFIER_DRIVER_ENTRY Verifier;
00974
00975
#if defined (_X86_)
00976
RtlGetCallersAddress(&CallingAddress, &CallersCaller);
00977
#else
00978
CallingAddress = (PVOID)_ReturnAddress();
00979
#endif
00980
00981
if (
KernelVerifier ==
TRUE) {
00982 Verifier =
ViLocateVerifierEntry (CallingAddress);
00983
00984
if ((Verifier ==
NULL) ||
00985 ((Verifier->
Flags &
VI_VERIFYING_DIRECTLY) == 0)) {
00986
00987
return ExAllocatePoolWithTag (PoolType |
POOL_DRIVER_MASK,
00988 NumberOfBytes,
00989 Tag);
00990 }
00991 PoolType |=
POOL_DRIVER_MASK;
00992 }
00993
00994
return VeAllocatePoolWithTagPriority (PoolType,
00995 NumberOfBytes,
00996 Tag,
00997
HighPoolPriority,
00998 CallingAddress);
00999 }
01000
01001
THUNKED_API
01002 PVOID
01003 VerifierAllocatePoolWithQuota(
01004 IN POOL_TYPE PoolType,
01005 IN SIZE_T NumberOfBytes
01006 )
01007 {
01008 PVOID Va;
01009 LOGICAL RaiseOnQuotaFailure;
01010 PVOID CallingAddress;
01011 PVOID CallersCaller;
01012
PMI_VERIFIER_DRIVER_ENTRY Verifier;
01013
01014
#if defined (_X86_)
01015
RtlGetCallersAddress(&CallingAddress, &CallersCaller);
01016
#else
01017
CallingAddress = (PVOID)_ReturnAddress();
01018
#endif
01019
01020
if (
KernelVerifier ==
TRUE) {
01021 Verifier =
ViLocateVerifierEntry (CallingAddress);
01022
01023
if ((Verifier ==
NULL) ||
01024 ((Verifier->
Flags &
VI_VERIFYING_DIRECTLY) == 0)) {
01025
01026
return ExAllocatePoolWithQuota (PoolType |
POOL_DRIVER_MASK,
01027 NumberOfBytes);
01028 }
01029 PoolType |=
POOL_DRIVER_MASK;
01030 }
01031
01032
MmVerifierData.AllocationsWithNoTag += 1;
01033
01034
if (PoolType &
POOL_QUOTA_FAIL_INSTEAD_OF_RAISE) {
01035 RaiseOnQuotaFailure =
FALSE;
01036 PoolType &= ~
POOL_QUOTA_FAIL_INSTEAD_OF_RAISE;
01037 }
01038
else {
01039 RaiseOnQuotaFailure =
TRUE;
01040 }
01041
01042 Va =
VeAllocatePoolWithTagPriority (PoolType,
01043 NumberOfBytes,
01044 'parW',
01045
HighPoolPriority,
01046 CallingAddress);
01047
01048
if (Va ==
NULL) {
01049
if (RaiseOnQuotaFailure ==
TRUE) {
01050
ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
01051 }
01052 }
01053
01054
return Va;
01055 }
01056
01057
THUNKED_API
01058 PVOID
01059 VerifierAllocatePoolWithQuotaTag(
01060 IN POOL_TYPE PoolType,
01061 IN SIZE_T NumberOfBytes,
01062 IN ULONG Tag
01063 )
01064 {
01065 PVOID Va;
01066 LOGICAL RaiseOnQuotaFailure;
01067 PVOID CallingAddress;
01068 PVOID CallersCaller;
01069
PMI_VERIFIER_DRIVER_ENTRY Verifier;
01070
01071
#if defined (_X86_)
01072
RtlGetCallersAddress(&CallingAddress, &CallersCaller);
01073
#else
01074
CallingAddress = (PVOID)_ReturnAddress();
01075
#endif
01076
01077
if (
KernelVerifier ==
TRUE) {
01078 Verifier =
ViLocateVerifierEntry (CallingAddress);
01079
01080
if ((Verifier ==
NULL) ||
01081 ((Verifier->
Flags &
VI_VERIFYING_DIRECTLY) == 0)) {
01082
01083
return ExAllocatePoolWithQuotaTag (PoolType |
POOL_DRIVER_MASK,
01084 NumberOfBytes,
01085 Tag);
01086 }
01087 PoolType |=
POOL_DRIVER_MASK;
01088 }
01089
01090
if (PoolType &
POOL_QUOTA_FAIL_INSTEAD_OF_RAISE) {
01091 RaiseOnQuotaFailure =
FALSE;
01092 PoolType &= ~
POOL_QUOTA_FAIL_INSTEAD_OF_RAISE;
01093 }
01094
else {
01095 RaiseOnQuotaFailure =
TRUE;
01096 }
01097
01098 Va =
VeAllocatePoolWithTagPriority (PoolType,
01099 NumberOfBytes,
01100 Tag,
01101
HighPoolPriority,
01102 CallingAddress);
01103
01104
if (Va ==
NULL) {
01105
if (RaiseOnQuotaFailure ==
TRUE) {
01106
ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
01107 }
01108 }
01109
01110
return Va;
01111 }
01112
01113
THUNKED_API
01114 PVOID
01115 VerifierAllocatePoolWithTagPriority(
01116 IN POOL_TYPE PoolType,
01117 IN SIZE_T NumberOfBytes,
01118 IN ULONG Tag,
01119 IN EX_POOL_PRIORITY Priority
01120 )
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135 {
01136 PVOID CallingAddress;
01137 PVOID CallersCaller;
01138
PMI_VERIFIER_DRIVER_ENTRY Verifier;
01139
01140
#if defined (_X86_)
01141
RtlGetCallersAddress(&CallingAddress, &CallersCaller);
01142
#else
01143
CallingAddress = (PVOID)_ReturnAddress();
01144
#endif
01145
01146
if (
KernelVerifier ==
TRUE) {
01147 Verifier =
ViLocateVerifierEntry (CallingAddress);
01148
01149
if ((Verifier ==
NULL) ||
01150 ((Verifier->
Flags &
VI_VERIFYING_DIRECTLY) == 0)) {
01151
01152
return ExAllocatePoolWithTagPriority (PoolType |
POOL_DRIVER_MASK,
01153 NumberOfBytes,
01154 Tag,
01155 Priority);
01156 }
01157 PoolType |=
POOL_DRIVER_MASK;
01158 }
01159
01160
return VeAllocatePoolWithTagPriority (PoolType,
01161 NumberOfBytes,
01162 Tag,
01163 Priority,
01164 CallingAddress);
01165 }
01166
01167 LOGICAL
01168 ViInjectResourceFailure (
01169 VOID
01170 )
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194 {
01195 LARGE_INTEGER CurrentTime;
01196
01197
if ((
MmVerifierData.Level & DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES) == 0) {
01198
return FALSE;
01199 }
01200
01201
01202
01203
01204
01205
01206
if (
VerifierSystemSufficientlyBooted ==
FALSE) {
01207
KeQuerySystemTime (&CurrentTime);
01208
if (CurrentTime.QuadPart >
KeBootTime.QuadPart +
VerifierRequiredTimeSinceBoot.QuadPart) {
01209
VerifierSystemSufficientlyBooted =
TRUE;
01210 }
01211 }
01212
01213
if (
VerifierSystemSufficientlyBooted ==
TRUE) {
01214
01215
KeQueryTickCount(&CurrentTime);
01216
01217
if ((CurrentTime.LowPart & 0xF) == 0) {
01218
01219
MmVerifierData.AllocationsFailedDeliberately += 1;
01220
01221
01222
01223
01224
01225
return TRUE;
01226 }
01227 }
01228
01229
return FALSE;
01230 }
01231
01232 LOGICAL
01233 ViReservePoolAllocation (
01234 IN
PMI_VERIFIER_DRIVER_ENTRY Verifier
01235 )
01236 {
01237 ULONG_PTR OldSize;
01238 ULONG_PTR NewSize;
01239 ULONG_PTR NewHashOffset;
01240 ULONG_PTR
Increment;
01241 ULONG_PTR Entries;
01242 ULONG_PTR i;
01243 KIRQL OldIrql;
01244 PVOID NewHashTable;
01245
PVI_POOL_ENTRY HashEntry;
01246
PVI_POOL_ENTRY OldHashTable;
01247
01248 ExAcquireSpinLock (&Verifier->VerifierPoolLock, &OldIrql);
01249
01250
while (Verifier->PoolHashSize <= Verifier->CurrentPagedPoolAllocations + Verifier->CurrentNonPagedPoolAllocations + Verifier->PoolHashReserved) {
01251
01252
01253
01254
01255
01256
#define VI_POOL_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(VI_POOL_ENTRY))
01257
01258 OldSize = Verifier->PoolHashSize *
sizeof(
VI_POOL_ENTRY);
01259
01260
if (Verifier->PoolHashSize >=
VI_POOL_ENTRIES_PER_PAGE) {
01261
Increment =
PAGE_SIZE;
01262 }
01263
else {
01264
Increment = 16 *
sizeof (
VI_POOL_ENTRY);
01265 }
01266
01267 ExReleaseSpinLock (&Verifier->VerifierPoolLock, OldIrql);
01268
01269 NewSize = OldSize +
Increment;
01270
01271
if (NewSize < OldSize) {
01272
return FALSE;
01273 }
01274
01275
01276
01277
01278
01279
01280 NewHashTable =
ExAllocatePoolWithTagPriority (
NonPagedPool |
POOL_DRIVER_MASK,
01281 NewSize,
01282 'ppeV',
01283
HighPoolPriority);
01284
01285 ExAcquireSpinLock (&Verifier->VerifierPoolLock, &OldIrql);
01286
01287 OldSize = Verifier->PoolHashSize *
sizeof(
VI_POOL_ENTRY);
01288
01289
if (NewHashTable ==
NULL) {
01290
if (Verifier->PoolHashSize <= Verifier->CurrentPagedPoolAllocations + Verifier->CurrentNonPagedPoolAllocations + Verifier->PoolHashReserved) {
01291 ExReleaseSpinLock (&Verifier->VerifierPoolLock, OldIrql);
01292
return FALSE;
01293 }
01294
01295
01296
01297
01298
01299
break;
01300 }
01301
01302
if (NewSize != OldSize +
Increment) {
01303
01304
01305
01306
01307
01308 ExReleaseSpinLock (&Verifier->VerifierPoolLock, OldIrql);
01309
ExFreePool (NewHashTable);
01310 ExAcquireSpinLock (&Verifier->VerifierPoolLock, &OldIrql);
01311 }
01312
else {
01313
01314
01315
01316
01317
01318 OldHashTable = Verifier->PoolHash;
01319
if (OldHashTable !=
NULL) {
01320 RtlCopyMemory (NewHashTable, OldHashTable, OldSize);
01321 }
01322
01323
01324
01325
01326
01327
01328 HashEntry = (
PVI_POOL_ENTRY) ((PCHAR)NewHashTable + OldSize);
01329 Entries =
Increment /
sizeof (
VI_POOL_ENTRY);
01330 NewHashOffset = HashEntry - (
PVI_POOL_ENTRY)NewHashTable;
01331
01332
01333
01334
01335
01336
01337
for (i = 0; i < Entries; i += 1) {
01338 HashEntry->
FreeListNext = NewHashOffset + i + 1;
01339 HashEntry += 1;
01340 }
01341 HashEntry -= 1;
01342 HashEntry->
FreeListNext = Verifier->PoolHashFree;
01343 Verifier->PoolHashFree = NewHashOffset;
01344 Verifier->PoolHash = NewHashTable;
01345 Verifier->PoolHashSize += Entries;
01346
01347
01348
01349
01350
01351
if (OldHashTable !=
NULL) {
01352 ExReleaseSpinLock (&Verifier->VerifierPoolLock, OldIrql);
01353
ExFreePool (OldHashTable);
01354 ExAcquireSpinLock (&Verifier->VerifierPoolLock, &OldIrql);
01355 }
01356 }
01357 }
01358
01359 Verifier->PoolHashReserved += 1;
01360
01361
ASSERT (Verifier->PoolHashSize >= Verifier->CurrentPagedPoolAllocations + Verifier->CurrentNonPagedPoolAllocations + Verifier->PoolHashReserved);
01362
01363 ExReleaseSpinLock (&Verifier->VerifierPoolLock, OldIrql);
01364
01365
return TRUE;
01366 }
01367
01368 ULONG_PTR
01369 ViInsertPoolAllocation (
01370 IN
PMI_VERIFIER_DRIVER_ENTRY Verifier,
01371 IN PVOID VirtualAddress,
01372 IN PVOID CallingAddress,
01373 IN SIZE_T NumberOfBytes,
01374 IN ULONG Tag
01375 )
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406 {
01407 ULONG_PTR
Index;
01408
PVI_POOL_ENTRY HashEntry;
01409
01410
ASSERT (KeGetCurrentIrql() ==
DISPATCH_LEVEL);
01411
01412
01413
01414
01415
01416
ASSERT (Verifier->PoolHashReserved != 0);
01417
01418
ASSERT (Verifier->PoolHashSize >= Verifier->CurrentPagedPoolAllocations + Verifier->CurrentNonPagedPoolAllocations + Verifier->PoolHashReserved);
01419
01420
01421
01422
01423
01424
Index = Verifier->PoolHashFree;
01425
ASSERT (
Index !=
VI_POOL_FREELIST_END);
01426
01427 HashEntry = Verifier->PoolHash +
Index;
01428
01429 Verifier->PoolHashFree = HashEntry->
FreeListNext;
01430
01431 Verifier->PoolHashReserved -= 1;
01432
01433
ASSERT (((HashEntry->
FreeListNext & MINLONG_PTR) == 0) ||
01434 (HashEntry->
FreeListNext ==
VI_POOL_FREELIST_END));
01435
01436 HashEntry->
InUse.
VirtualAddress = VirtualAddress;
01437 HashEntry->
InUse.
CallingAddress = CallingAddress;
01438 HashEntry->
InUse.
NumberOfBytes = NumberOfBytes;
01439 HashEntry->
InUse.
Tag = Tag;
01440
01441
ASSERT ((HashEntry->
FreeListNext & MINLONG_PTR) != 0);
01442
01443
return Index;
01444 }
01445
01446
VOID
01447 ViReleasePoolAllocation (
01448 IN
PMI_VERIFIER_DRIVER_ENTRY Verifier,
01449 IN PVOID VirtualAddress,
01450 IN ULONG_PTR ListIndex,
01451 IN SIZE_T ChargedBytes
01452 )
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482 {
01483 PFN_NUMBER PageFrameIndex;
01484 PFN_NUMBER PageFrameIndex2;
01485
PVI_POOL_ENTRY HashEntry;
01486
PMMPTE PointerPte;
01487
01488
ASSERT (KeGetCurrentIrql() ==
DISPATCH_LEVEL);
01489
01490
if (Verifier->PoolHash ==
NULL) {
01491
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
01492 0x59,
01493 (ULONG_PTR)VirtualAddress,
01494 ListIndex,
01495 (ULONG_PTR)Verifier);
01496 }
01497
01498
01499
01500
01501
01502
01503 HashEntry = Verifier->PoolHash + ListIndex;
01504
01505
if (ListIndex >= Verifier->PoolHashSize) {
01506
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
01507 0x54,
01508 (ULONG_PTR)VirtualAddress,
01509 Verifier->PoolHashSize,
01510 ListIndex);
01511 }
01512
01513
if (HashEntry->
InUse.
VirtualAddress != VirtualAddress) {
01514
01515 PageFrameIndex = 0;
01516 PageFrameIndex2 = 1;
01517
01518
if ((!
MI_IS_PHYSICAL_ADDRESS(VirtualAddress)) &&
01519 (
MI_IS_PHYSICAL_ADDRESS(HashEntry->
InUse.
VirtualAddress))) {
01520
01521 PointerPte =
MiGetPteAddress(VirtualAddress);
01522
if (PointerPte->
u.Hard.Valid == 1) {
01523 PageFrameIndex =
MI_GET_PAGE_FRAME_FROM_PTE (PointerPte);
01524
01525 PageFrameIndex2 =
MI_CONVERT_PHYSICAL_TO_PFN (HashEntry->
InUse.
VirtualAddress);
01526 }
01527 }
01528
01529
01530
01531
01532
01533
01534
if (PageFrameIndex != PageFrameIndex2) {
01535
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
01536 0x52,
01537 (ULONG_PTR)VirtualAddress,
01538 (ULONG_PTR)HashEntry->
InUse.
VirtualAddress,
01539 ChargedBytes);
01540 }
01541 }
01542
01543
if (HashEntry->
InUse.
NumberOfBytes != ChargedBytes) {
01544
01545
01546
01547
01548
01549
01550
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
01551 0x51,
01552 (ULONG_PTR)VirtualAddress,
01553 (ULONG_PTR)HashEntry,
01554 ChargedBytes);
01555 }
01556
01557
01558
01559
01560
01561 HashEntry->
FreeListNext = Verifier->PoolHashFree;
01562 Verifier->PoolHashFree = HashEntry - Verifier->PoolHash;
01563 }
01564
01565
VOID
01566 ViCancelPoolAllocation (
01567 IN
PMI_VERIFIER_DRIVER_ENTRY Verifier
01568 )
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593 {
01594 KIRQL OldIrql;
01595
01596 ExAcquireSpinLock (&Verifier->VerifierPoolLock, &OldIrql);
01597
01598
01599
01600
01601
01602
ASSERT (Verifier->PoolHashReserved != 0);
01603
01604
ASSERT (Verifier->PoolHashSize >= Verifier->CurrentPagedPoolAllocations + Verifier->CurrentNonPagedPoolAllocations + Verifier->PoolHashReserved);
01605
01606
ASSERT (Verifier->PoolHashFree !=
VI_POOL_FREELIST_END);
01607
01608 Verifier->PoolHashReserved -= 1;
01609
01610 ExReleaseSpinLock (&Verifier->VerifierPoolLock, OldIrql);
01611 }
01612
01613 PVOID
01614 ViPostPoolAllocation (
01615 IN PVOID VirtualAddress,
01616 IN SIZE_T NumberOfBytes,
01617 IN POOL_TYPE PoolType,
01618 IN ULONG Tag,
01619 IN PVOID CallingAddress
01620 )
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650 {
01651 KIRQL OldIrql;
01652
PMI_VERIFIER_POOL_HEADER Header;
01653 SIZE_T ChargedBytes;
01654
PMI_VERIFIER_DRIVER_ENTRY Verifier;
01655 ULONG_PTR InsertedIndex;
01656 LOGICAL SpecialPoolAllocation;
01657
PPOOL_HEADER PoolHeader;
01658
01659 InterlockedIncrement ((PLONG)&
MmVerifierData.AllocationsSucceeded);
01660 ChargedBytes =
EX_REAL_POOL_USAGE(NumberOfBytes);
01661 SpecialPoolAllocation =
FALSE;
01662
01663
if (VirtualAddress >=
MmSpecialPoolStart && VirtualAddress <
MmSpecialPoolEnd) {
01664 ChargedBytes = NumberOfBytes;
01665 InterlockedIncrement ((PLONG)&
MmVerifierData.AllocationsSucceededSpecialPool);
01666 SpecialPoolAllocation =
TRUE;
01667 }
01668
else if (NumberOfBytes <=
POOL_BUDDY_MAX) {
01669 ChargedBytes -=
POOL_OVERHEAD;
01670 }
01671
else {
01672
01673
01674
01675
01676
01677
01678 InterlockedIncrement ((PLONG)&
MmVerifierData.AllocationsSucceededSpecialPool);
01679 }
01680
01681
if ((PoolType &
POOL_VERIFIER_MASK) == 0) {
01682
return VirtualAddress;
01683 }
01684
01685
if (NumberOfBytes >
POOL_BUDDY_MAX) {
01686
ASSERT (
BYTE_OFFSET(VirtualAddress) == 0);
01687 }
01688
01689 Verifier =
ViLocateVerifierEntry (CallingAddress);
01690
ASSERT (Verifier !=
NULL);
01691
VerifierIsTrackingPool =
TRUE;
01692
01693
if (SpecialPoolAllocation ==
TRUE) {
01694
01695
01696
01697
01698
01699
01700
01701
if (((ULONG_PTR)VirtualAddress & (
PAGE_SIZE - 1))) {
01702 PoolHeader = (
PPOOL_HEADER)(
PAGE_ALIGN (VirtualAddress));
01703
Header = (
PMI_VERIFIER_POOL_HEADER) (PoolHeader + 1);
01704 VirtualAddress = (PVOID) ((PCHAR)VirtualAddress +
sizeof (
MI_VERIFIER_POOL_HEADER));
01705 }
01706
else {
01707 PoolHeader = (
PPOOL_HEADER)((PCHAR)
PAGE_ALIGN (VirtualAddress) +
PAGE_SIZE -
POOL_OVERHEAD);
01708
Header = (
PMI_VERIFIER_POOL_HEADER) (PoolHeader - 1);
01709 }
01710
01711 PoolHeader->
Ulong1 -=
sizeof (
MI_VERIFIER_POOL_HEADER);
01712 ChargedBytes -=
sizeof (
MI_VERIFIER_POOL_HEADER);
01713 PoolHeader->
Ulong1 |=
MI_SPECIAL_POOL_VERIFIER;
01714 }
01715
else {
01716
Header = (
PMI_VERIFIER_POOL_HEADER)((PCHAR)VirtualAddress +
01717 ChargedBytes -
01718
sizeof(
MI_VERIFIER_POOL_HEADER));
01719 }
01720
01721
ASSERT (((ULONG_PTR)
Header & (
sizeof(ULONG) - 1)) == 0);
01722
01723
01724
Header->Verifier = Verifier;
01725
01726
01727
01728
01729
01730
01731
01732 ExAcquireSpinLock (&Verifier->
VerifierPoolLock, &OldIrql);
01733
01734 InsertedIndex =
ViInsertPoolAllocation (Verifier,
01735 VirtualAddress,
01736 CallingAddress,
01737 ChargedBytes,
01738 Tag);
01739
01740
if ((PoolType &
BASE_POOL_TYPE_MASK) ==
PagedPool) {
01741
01742 Verifier->
PagedBytes += ChargedBytes;
01743
if (Verifier->
PagedBytes > Verifier->
PeakPagedBytes) {
01744 Verifier->
PeakPagedBytes = Verifier->
PagedBytes;
01745 }
01746
01747 Verifier->
CurrentPagedPoolAllocations += 1;
01748
if (Verifier->
CurrentPagedPoolAllocations > Verifier->
PeakPagedPoolAllocations) {
01749 Verifier->
PeakPagedPoolAllocations = Verifier->
CurrentPagedPoolAllocations;
01750 }
01751 }
01752
else {
01753 Verifier->
NonPagedBytes += ChargedBytes;
01754
if (Verifier->
NonPagedBytes > Verifier->
PeakNonPagedBytes) {
01755 Verifier->
PeakNonPagedBytes = Verifier->
NonPagedBytes;
01756 }
01757
01758 Verifier->
CurrentNonPagedPoolAllocations += 1;
01759
if (Verifier->
CurrentNonPagedPoolAllocations > Verifier->
PeakNonPagedPoolAllocations) {
01760 Verifier->
PeakNonPagedPoolAllocations = Verifier->
CurrentNonPagedPoolAllocations;
01761 }
01762 }
01763
01764 ExReleaseSpinLock (&Verifier->
VerifierPoolLock, OldIrql);
01765
01766
01767
01768
01769
01770
01771
Header->ListIndex = InsertedIndex;
01772
01773
01774
01775
01776
01777
if ((PoolType &
BASE_POOL_TYPE_MASK) ==
PagedPool) {
01778 ExAcquireFastMutex (&
VerifierPoolMutex);
01779
01780
MmVerifierData.PagedBytes += ChargedBytes;
01781
if (
MmVerifierData.PagedBytes >
MmVerifierData.PeakPagedBytes) {
01782
MmVerifierData.PeakPagedBytes =
MmVerifierData.PagedBytes;
01783 }
01784
01785
MmVerifierData.CurrentPagedPoolAllocations += 1;
01786
if (
MmVerifierData.CurrentPagedPoolAllocations >
MmVerifierData.PeakPagedPoolAllocations) {
01787
MmVerifierData.PeakPagedPoolAllocations =
MmVerifierData.CurrentPagedPoolAllocations;
01788 }
01789
01790 ExReleaseFastMutex (&
VerifierPoolMutex);
01791 }
01792
else {
01793 ExAcquireSpinLock (&
VerifierPoolLock, &OldIrql);
01794
01795
MmVerifierData.NonPagedBytes += ChargedBytes;
01796
if (
MmVerifierData.NonPagedBytes >
MmVerifierData.PeakNonPagedBytes) {
01797
MmVerifierData.PeakNonPagedBytes =
MmVerifierData.NonPagedBytes;
01798 }
01799
01800
MmVerifierData.CurrentNonPagedPoolAllocations += 1;
01801
if (
MmVerifierData.CurrentNonPagedPoolAllocations >
MmVerifierData.PeakNonPagedPoolAllocations) {
01802
MmVerifierData.PeakNonPagedPoolAllocations =
MmVerifierData.CurrentNonPagedPoolAllocations;
01803 }
01804
01805 ExReleaseSpinLock (&
VerifierPoolLock, OldIrql);
01806 }
01807
01808
return VirtualAddress;
01809 }
01810
01811 PVOID
01812 VeAllocatePoolWithTagPriority(
01813 IN POOL_TYPE PoolType,
01814 IN SIZE_T NumberOfBytes,
01815 IN ULONG Tag,
01816 IN EX_POOL_PRIORITY Priority,
01817 IN PVOID CallingAddress
01818 )
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833 {
01834 PVOID VirtualAddress;
01835
EX_POOL_PRIORITY AllocationPriority;
01836 SIZE_T ChargedBytes;
01837
PMI_VERIFIER_DRIVER_ENTRY Verifier;
01838 LOGICAL ReservedHash;
01839 ULONG HeaderSize;
01840
01841
ExAllocatePoolSanityChecks (PoolType, NumberOfBytes);
01842
01843 InterlockedIncrement ((PLONG)&
MmVerifierData.AllocationsAttempted);
01844
01845
if ((PoolType &
MUST_SUCCEED_POOL_TYPE_MASK) == 0) {
01846
01847
if (
ViInjectResourceFailure () ==
TRUE) {
01848
01849
01850
01851
01852
01853
if ((PoolType &
POOL_RAISE_IF_ALLOCATION_FAILURE) != 0) {
01854
ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
01855 }
01856
01857
return NULL;
01858 }
01859 }
01860
01861
ASSERT ((PoolType &
POOL_VERIFIER_MASK) == 0);
01862
01863 AllocationPriority = Priority;
01864
01865
if (
MmVerifierData.Level & DRIVER_VERIFIER_SPECIAL_POOLING) {
01866
01867
01868
01869
01870
01871
01872
if ((AllocationPriority & (
LowPoolPrioritySpecialPoolOverrun |
LowPoolPrioritySpecialPoolUnderrun)) == 0) {
01873
if (
MmSpecialPoolCatchOverruns ==
TRUE) {
01874 AllocationPriority |=
LowPoolPrioritySpecialPoolOverrun;
01875 }
01876
else {
01877 AllocationPriority |=
LowPoolPrioritySpecialPoolUnderrun;
01878 }
01879 }
01880 }
01881
01882 ReservedHash =
FALSE;
01883
if (
MmVerifierData.Level & DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS) {
01884
01885
if ((PoolType &
SESSION_POOL_MASK) && (
MiHydra ==
TRUE)) {
01886
01887
01888
01889
01890
01891 NOTHING;
01892 }
01893
else {
01894 HeaderSize =
sizeof(
MI_VERIFIER_POOL_HEADER);
01895
01896 ChargedBytes =
MI_ROUND_TO_SIZE (NumberOfBytes,
sizeof(ULONG)) + HeaderSize;
01897 Verifier =
ViLocateVerifierEntry (CallingAddress);
01898
01899
if ((Verifier ==
NULL) ||
01900 ((Verifier->
Flags &
VI_VERIFYING_DIRECTLY) == 0)) {
01901
01902
01903
01904
01905
01906
01907
01908
MmVerifierData.UnTrackedPool += 1;
01909 }
01910
else if (ChargedBytes <= NumberOfBytes) {
01911
01912
01913
01914
01915
01916
01917
01918
MmVerifierData.UnTrackedPool += 1;
01919 }
01920
else if (((PoolType &
MUST_SUCCEED_POOL_TYPE_MASK) == 0) ||
01921 (ChargedBytes <=
PAGE_SIZE)) {
01922
01923
01924
01925
01926
01927
01928
01929
01930
if (
ViReservePoolAllocation (Verifier) ==
TRUE) {
01931 ReservedHash =
TRUE;
01932 NumberOfBytes = ChargedBytes;
01933 PoolType |=
POOL_VERIFIER_MASK;
01934 }
01935 }
01936
else {
01937
ASSERT ((PoolType &
BASE_POOL_TYPE_MASK) ==
NonPagedPool);
01938
MmVerifierData.UnTrackedPool += 1;
01939 }
01940 }
01941 }
01942
01943 VirtualAddress =
ExAllocatePoolWithTagPriority (PoolType,
01944 NumberOfBytes,
01945 Tag,
01946 AllocationPriority);
01947
01948
if (VirtualAddress ==
NULL) {
01949
MmVerifierData.AllocationsFailed += 1;
01950
01951
if (ReservedHash ==
TRUE) {
01952
01953
01954
01955
01956
01957
ViCancelPoolAllocation (Verifier);
01958 }
01959
01960
if ((PoolType &
POOL_RAISE_IF_ALLOCATION_FAILURE) != 0) {
01961
ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
01962 }
01963
return NULL;
01964 }
01965
01966 VirtualAddress =
ViPostPoolAllocation (VirtualAddress,
01967 NumberOfBytes,
01968 PoolType,
01969 Tag,
01970 CallingAddress);
01971
01972
return VirtualAddress;
01973 }
01974
01975
VOID
01976 VerifierFreeTrackedPool(
01977 IN PVOID VirtualAddress,
01978 IN SIZE_T ChargedBytes,
01979 IN LOGICAL CheckType,
01980 IN LOGICAL SpecialPool
01981 )
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019 {
02020 KIRQL OldIrql;
02021 ULONG_PTR
Index;
02022
PPOOL_HEADER PoolHeader;
02023
PMI_VERIFIER_POOL_HEADER Header;
02024
PMI_VERIFIER_DRIVER_ENTRY Verifier;
02025
02026
if (
VerifierIsTrackingPool ==
FALSE) {
02027
02028
02029
02030
02031
02032
02033
02034
KeBugCheckEx (BAD_POOL_CALLER,
02035 0x99,
02036 (ULONG_PTR)VirtualAddress,
02037 0,
02038 0);
02039 }
02040
02041
if (SpecialPool ==
TRUE) {
02042
02043
02044
02045
02046
02047
if (((ULONG_PTR)VirtualAddress & (
PAGE_SIZE - 1))) {
02048 PoolHeader =
PAGE_ALIGN (VirtualAddress);
02049
Header = (
PMI_VERIFIER_POOL_HEADER)(PoolHeader + 1);
02050 }
02051
else {
02052 PoolHeader = (
PPOOL_HEADER)((PCHAR)
PAGE_ALIGN (VirtualAddress) +
PAGE_SIZE -
POOL_OVERHEAD);
02053
Header = (
PMI_VERIFIER_POOL_HEADER)(PoolHeader - 1);
02054 }
02055 }
02056
else if (
PAGE_ALIGNED(VirtualAddress)) {
02057
02058
02059
02060
02061
02062
Header = (
PMI_VERIFIER_POOL_HEADER) ((PCHAR)VirtualAddress +
02063 ChargedBytes -
02064
sizeof(
MI_VERIFIER_POOL_HEADER));
02065 }
02066
else {
02067 ChargedBytes -=
POOL_OVERHEAD;
02068
Header = (
PMI_VERIFIER_POOL_HEADER) ((PCHAR)VirtualAddress +
02069 ChargedBytes -
02070
sizeof(
MI_VERIFIER_POOL_HEADER));
02071 }
02072
02073 Verifier =
Header->Verifier;
02074
02075
02076
02077
02078
02079
02080
if ((((ULONG_PTR)Verifier & (
sizeof(ULONG) - 1)) != 0) ||
02081 (!
MmIsAddressValid(&Verifier->
Signature)) ||
02082 (Verifier->
Signature !=
MI_VERIFIER_ENTRY_SIGNATURE)) {
02083
02084
02085
02086
02087
02088
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02089 0x53,
02090 (ULONG_PTR)VirtualAddress,
02091 (ULONG_PTR)
Header,
02092 (ULONG_PTR)Verifier);
02093 }
02094
02095
Index =
Header->ListIndex;
02096
02097 ExAcquireSpinLock (&Verifier->
VerifierPoolLock, &OldIrql);
02098
02099
ViReleasePoolAllocation (Verifier,
02100 VirtualAddress,
02101
Index,
02102 ChargedBytes);
02103
02104
if (CheckType ==
PagedPool) {
02105 Verifier->
PagedBytes -= ChargedBytes;
02106 Verifier->
CurrentPagedPoolAllocations -= 1;
02107
02108 ExReleaseSpinLock (&Verifier->
VerifierPoolLock, OldIrql);
02109
02110 ExAcquireFastMutex (&
VerifierPoolMutex);
02111
MmVerifierData.PagedBytes -= ChargedBytes;
02112
MmVerifierData.CurrentPagedPoolAllocations -= 1;
02113 ExReleaseFastMutex (&
VerifierPoolMutex);
02114 }
02115
else {
02116 Verifier->
NonPagedBytes -= ChargedBytes;
02117 Verifier->
CurrentNonPagedPoolAllocations -= 1;
02118 ExReleaseSpinLock (&Verifier->
VerifierPoolLock, OldIrql);
02119
02120 ExAcquireSpinLock (&
VerifierPoolLock, &OldIrql);
02121
MmVerifierData.NonPagedBytes -= ChargedBytes;
02122
MmVerifierData.CurrentNonPagedPoolAllocations -= 1;
02123 ExReleaseSpinLock (&
VerifierPoolLock, OldIrql);
02124 }
02125 }
02126
02127
THUNKED_API
02128
VOID
02129 VerifierFreePool(
02130 IN PVOID P
02131 )
02132 {
02133
if (
KernelVerifier ==
TRUE) {
02134
ExFreePool (P);
02135
return;
02136 }
02137
02138
VerifierFreePoolWithTag (P, 0);
02139 }
02140
02141
THUNKED_API
02142
VOID
02143 VerifierFreePoolWithTag(
02144 IN PVOID P,
02145 IN ULONG TagToFree
02146 )
02147 {
02148
if (
KernelVerifier ==
TRUE) {
02149
ExFreePoolWithTag (P, TagToFree);
02150
return;
02151 }
02152
02153
ExFreePoolSanityChecks (P);
02154
02155
ExFreePoolWithTag (P, TagToFree);
02156 }
02157
02158
THUNKED_API
02159 LONG
02160 VerifierSetEvent (
02161 IN
PRKEVENT Event,
02162 IN KPRIORITY Increment,
02163 IN BOOLEAN Wait
02164 )
02165 {
02166 KIRQL CurrentIrql;
02167
02168 CurrentIrql = KeGetCurrentIrql();
02169
if (CurrentIrql >
DISPATCH_LEVEL) {
02170
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02171 0x80,
02172 CurrentIrql,
02173 (ULONG_PTR)
Event,
02174 (ULONG_PTR)0);
02175 }
02176
02177
return KeSetEvent (
Event,
Increment, Wait);
02178 }
02179
02180
THUNKED_API
02181 BOOLEAN
02182 VerifierExAcquireResourceExclusive(
02183 IN
PERESOURCE Resource,
02184 IN BOOLEAN Wait
02185 )
02186 {
02187 KIRQL CurrentIrql;
02188
02189 CurrentIrql = KeGetCurrentIrql ();
02190
02191
if ((CurrentIrql !=
APC_LEVEL) &&
02192 (!
IS_SYSTEM_THREAD(
PsGetCurrentThread())) &&
02193 (
KeGetCurrentThread()->KernelApcDisable == 0)) {
02194
02195
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02196 0x37,
02197 CurrentIrql,
02198 (ULONG_PTR)(
KeGetCurrentThread()->KernelApcDisable),
02199 (ULONG_PTR)
Resource);
02200 }
02201
02202
return ExAcquireResourceExclusiveLite (
Resource, Wait);
02203 }
02204
02205
THUNKED_API
02206
VOID
02207
FASTCALL
02208 VerifierExReleaseResource(
02209 IN
PERESOURCE Resource
02210 )
02211 {
02212 KIRQL CurrentIrql;
02213
02214 CurrentIrql = KeGetCurrentIrql ();
02215
02216
if ((CurrentIrql !=
APC_LEVEL) &&
02217 (!
IS_SYSTEM_THREAD(
PsGetCurrentThread())) &&
02218 (
KeGetCurrentThread()->KernelApcDisable == 0)) {
02219
02220
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02221 0x38,
02222 CurrentIrql,
02223 (ULONG_PTR)(
KeGetCurrentThread()->KernelApcDisable),
02224 (ULONG_PTR)
Resource);
02225 }
02226
02227
ExReleaseResourceLite (
Resource);
02228 }
02229
02230 int VerifierIrqlData[0x10];
02231
02232
VOID
02233 KfSanityCheckRaiseIrql (
02234 IN KIRQL NewIrql
02235 )
02236 {
02237 KIRQL CurrentIrql;
02238
02239
02240
02241
02242
02243 CurrentIrql = KeGetCurrentIrql ();
02244
02245
if (CurrentIrql == NewIrql) {
02246
VerifierIrqlData[0] += 1;
02247
if (CurrentIrql ==
APC_LEVEL) {
02248
VerifierIrqlData[1] += 1;
02249 }
02250
else if (CurrentIrql ==
DISPATCH_LEVEL) {
02251
VerifierIrqlData[2] += 1;
02252 }
02253
else {
02254
VerifierIrqlData[3] += 1;
02255 }
02256 }
02257
else {
02258
VerifierIrqlData[4] += 1;
02259 }
02260
02261
if (CurrentIrql > NewIrql) {
02262
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02263 0x30,
02264 CurrentIrql,
02265 NewIrql,
02266 0);
02267 }
02268
02269
02270
02271
02272
02273
if (NewIrql >
HIGH_LEVEL) {
02274
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02275 0x30,
02276 CurrentIrql,
02277 NewIrql,
02278 0);
02279 }
02280 }
02281
02282
VOID
02283 KfSanityCheckLowerIrql (
02284 IN KIRQL NewIrql
02285 )
02286 {
02287 KIRQL CurrentIrql;
02288
02289
02290
02291
02292
02293 CurrentIrql = KeGetCurrentIrql ();
02294
02295
if (CurrentIrql == NewIrql) {
02296
VerifierIrqlData[8] += 1;
02297
if (CurrentIrql ==
APC_LEVEL) {
02298
VerifierIrqlData[9] += 1;
02299 }
02300
else if (CurrentIrql ==
DISPATCH_LEVEL) {
02301
VerifierIrqlData[10] += 1;
02302 }
02303
else {
02304
VerifierIrqlData[11] += 1;
02305 }
02306 }
02307
else {
02308
VerifierIrqlData[12] += 1;
02309 }
02310
02311
if (CurrentIrql < NewIrql) {
02312
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02313 0x31,
02314 CurrentIrql,
02315 NewIrql,
02316 0);
02317 }
02318
02319
02320
02321
02322
02323
if (NewIrql >
HIGH_LEVEL) {
02324
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02325 0x31,
02326 CurrentIrql,
02327 NewIrql,
02328 0);
02329 }
02330 }
02331
02332
VOID
02333 ViTrimAllSystemPagableMemory (
02334 VOID
02335 )
02336 {
02337 LARGE_INTEGER CurrentTime;
02338 LOGICAL PageOut;
02339
02340 PageOut =
TRUE;
02341
if (
KernelVerifier ==
TRUE) {
02342
KeQueryTickCount(&CurrentTime);
02343
if ((CurrentTime.LowPart &
KernelVerifierTickPage) != 0) {
02344 PageOut =
FALSE;
02345 }
02346 }
02347
02348
if ((PageOut ==
TRUE) && (
MiNoPageOnRaiseIrql == 0)) {
02349
MmVerifierData.TrimRequests += 1;
02350
if (
MmTrimAllSystemPagableMemory (
FALSE) ==
TRUE) {
02351
MmVerifierData.Trims += 1;
02352 }
02353 }
02354 }
02355
02356
typedef
02357
VOID
02358 (*PKE_ACQUIRE_SPINLOCK) (
02359 IN PKSPIN_LOCK SpinLock,
02360 OUT PKIRQL OldIrql
02361 );
02362
02363
THUNKED_API
02364
VOID
02365 VerifierKeAcquireSpinLock (
02366 IN PKSPIN_LOCK SpinLock,
02367 OUT PKIRQL OldIrql
02368 )
02369 {
02370 KIRQL CurrentIrql;
02371
PKE_ACQUIRE_SPINLOCK HalRoutine;
02372
02373 CurrentIrql = KeGetCurrentIrql ();
02374
02375
KfSanityCheckRaiseIrql (
DISPATCH_LEVEL);
02376
02377
MmVerifierData.AcquireSpinLocks += 1;
02378
02379
if (
MmVerifierData.Level & DRIVER_VERIFIER_FORCE_IRQL_CHECKING) {
02380
if (CurrentIrql <
DISPATCH_LEVEL) {
02381
ViTrimAllSystemPagableMemory ();
02382 }
02383 }
02384
02385
#if defined (_X86_)
02386
HalRoutine = (
PKE_ACQUIRE_SPINLOCK) (ULONG_PTR) MiKernelVerifierOriginalCalls[VI_KE_ACQUIRE_SPINLOCK];
02387
02388
if (HalRoutine) {
02389 (*HalRoutine)(SpinLock, OldIrql);
02390
return;
02391 }
02392
#endif
02393
02394
KeAcquireSpinLock (SpinLock, OldIrql);
02395 }
02396
02397
typedef
02398
VOID
02399 (*PKE_RELEASE_SPINLOCK) (
02400 IN PKSPIN_LOCK SpinLock,
02401 IN KIRQL NewIrql
02402 );
02403
02404
THUNKED_API
02405
VOID
02406 VerifierKeReleaseSpinLock (
02407 IN PKSPIN_LOCK SpinLock,
02408 IN KIRQL NewIrql
02409 )
02410 {
02411 KIRQL CurrentIrql;
02412
PKE_RELEASE_SPINLOCK HalRoutine;
02413
02414 CurrentIrql = KeGetCurrentIrql ();
02415
02416
02417
02418
02419
02420
if (CurrentIrql !=
DISPATCH_LEVEL) {
02421
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02422 0x32,
02423 CurrentIrql,
02424 (ULONG_PTR)SpinLock,
02425 0);
02426 }
02427
02428
KfSanityCheckLowerIrql (NewIrql);
02429
02430
#if defined (_X86_)
02431
HalRoutine = (
PKE_RELEASE_SPINLOCK) (ULONG_PTR) MiKernelVerifierOriginalCalls[VI_KE_RELEASE_SPINLOCK];
02432
02433
if (HalRoutine) {
02434 (*HalRoutine)(SpinLock, NewIrql);
02435
return;
02436 }
02437
#endif
02438
02439
KeReleaseSpinLock (SpinLock, NewIrql);
02440 }
02441
02442
#if defined (_X86_)
02443
02444
typedef
02445 KIRQL
02446 (
FASTCALL *PKF_ACQUIRE_SPINLOCK) (
02447 IN PKSPIN_LOCK SpinLock
02448 );
02449
02450
THUNKED_API
02451 KIRQL
02452
FASTCALL
02453
VerifierKfAcquireSpinLock (
02454 IN PKSPIN_LOCK SpinLock
02455 )
02456 {
02457 KIRQL CurrentIrql;
02458 PKF_ACQUIRE_SPINLOCK HalRoutine;
02459
02460 CurrentIrql = KeGetCurrentIrql ();
02461
02462
KfSanityCheckRaiseIrql (DISPATCH_LEVEL);
02463
02464
MmVerifierData.AcquireSpinLocks += 1;
02465
02466
if (
MmVerifierData.Level & DRIVER_VERIFIER_FORCE_IRQL_CHECKING) {
02467
if (CurrentIrql <
DISPATCH_LEVEL) {
02468
ViTrimAllSystemPagableMemory ();
02469 }
02470 }
02471
02472
#if defined (_X86_)
02473
HalRoutine = (PKF_ACQUIRE_SPINLOCK) (ULONG_PTR) MiKernelVerifierOriginalCalls[VI_KF_ACQUIRE_SPINLOCK];
02474
02475
if (HalRoutine) {
02476
return (*HalRoutine)(SpinLock);
02477 }
02478
#endif
02479
02480 CurrentIrql = KfAcquireSpinLock (SpinLock);
02481
02482
return CurrentIrql;
02483 }
02484
02485
typedef
02486
VOID
02487 (
FASTCALL *PKF_RELEASE_SPINLOCK) (
02488 IN PKSPIN_LOCK SpinLock,
02489 IN KIRQL NewIrql
02490 );
02491
02492
THUNKED_API
02493
VOID
02494
FASTCALL
02495
VerifierKfReleaseSpinLock (
02496 IN PKSPIN_LOCK SpinLock,
02497 IN KIRQL NewIrql
02498 )
02499 {
02500 KIRQL CurrentIrql;
02501 PKF_RELEASE_SPINLOCK HalRoutine;
02502
02503 CurrentIrql = KeGetCurrentIrql ();
02504
02505
02506
02507
02508
02509
if (
KernelVerifier ==
TRUE) {
02510
if (CurrentIrql <
DISPATCH_LEVEL) {
02511
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02512 0x35,
02513 CurrentIrql,
02514 (ULONG_PTR)SpinLock,
02515 NewIrql);
02516 }
02517 }
02518
else {
02519
if (CurrentIrql !=
DISPATCH_LEVEL) {
02520
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02521 0x32,
02522 CurrentIrql,
02523 (ULONG_PTR)SpinLock,
02524 NewIrql);
02525 }
02526 }
02527
02528
KfSanityCheckLowerIrql (NewIrql);
02529
02530
#if defined (_X86_)
02531
HalRoutine = (PKF_RELEASE_SPINLOCK) (ULONG_PTR) MiKernelVerifierOriginalCalls[VI_KF_RELEASE_SPINLOCK];
02532
02533
if (HalRoutine) {
02534 (*HalRoutine)(SpinLock, NewIrql);
02535
return;
02536 }
02537
#endif
02538
02539 KfReleaseSpinLock (SpinLock, NewIrql);
02540 }
02541
02542
02543
#if !defined(NT_UP)
02544
02545
typedef
02546 KIRQL
02547 (
FASTCALL *PKE_ACQUIRE_QUEUED_SPINLOCK) (
02548 IN
KSPIN_LOCK_QUEUE_NUMBER Number
02549 );
02550
02551
THUNKED_API
02552 KIRQL
02553
FASTCALL
02554
VerifierKeAcquireQueuedSpinLock (
02555 IN KSPIN_LOCK_QUEUE_NUMBER Number
02556 )
02557 {
02558 KIRQL CurrentIrql;
02559 PKE_ACQUIRE_QUEUED_SPINLOCK HalRoutine;
02560
02561 CurrentIrql = KeGetCurrentIrql ();
02562
02563
KfSanityCheckRaiseIrql (DISPATCH_LEVEL);
02564
02565
MmVerifierData.AcquireSpinLocks += 1;
02566
02567
if (
MmVerifierData.Level & DRIVER_VERIFIER_FORCE_IRQL_CHECKING) {
02568
if (CurrentIrql <
DISPATCH_LEVEL) {
02569
ViTrimAllSystemPagableMemory ();
02570 }
02571 }
02572
02573
#if defined (_X86_)
02574
HalRoutine = (PKE_ACQUIRE_QUEUED_SPINLOCK) MiKernelVerifierOriginalCalls[VI_KE_ACQUIRE_QUEUED_SPINLOCK];
02575
02576
if (HalRoutine) {
02577
return (*HalRoutine)(Number);
02578 }
02579
#endif
02580
02581 CurrentIrql = KeAcquireQueuedSpinLock (Number);
02582
02583
return CurrentIrql;
02584 }
02585
02586
typedef
02587
VOID
02588 (
FASTCALL *PKE_RELEASE_QUEUED_SPINLOCK) (
02589 IN
KSPIN_LOCK_QUEUE_NUMBER Number,
02590 IN KIRQL OldIrql
02591 );
02592
02593
THUNKED_API
02594
VOID
02595
FASTCALL
02596
VerifierKeReleaseQueuedSpinLock (
02597 IN KSPIN_LOCK_QUEUE_NUMBER Number,
02598 IN KIRQL OldIrql
02599 )
02600 {
02601 KIRQL CurrentIrql;
02602 PKE_RELEASE_QUEUED_SPINLOCK HalRoutine;
02603
02604 CurrentIrql = KeGetCurrentIrql ();
02605
02606
if (
KernelVerifier ==
TRUE) {
02607
if (CurrentIrql <
DISPATCH_LEVEL) {
02608
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02609 0x36,
02610 CurrentIrql,
02611 (ULONG_PTR)Number,
02612 (ULONG_PTR)OldIrql);
02613 }
02614 }
02615
02616
KfSanityCheckLowerIrql (OldIrql);
02617
02618
#if defined (_X86_)
02619
HalRoutine = (PKE_RELEASE_QUEUED_SPINLOCK) MiKernelVerifierOriginalCalls[VI_KE_RELEASE_QUEUED_SPINLOCK];
02620
02621
if (HalRoutine) {
02622 (*HalRoutine)(Number, OldIrql);
02623
return;
02624 }
02625
#endif
02626
02627 KeReleaseQueuedSpinLock (Number, OldIrql);
02628 }
02629
#endif
02630
02631
typedef
02632 KIRQL
02633 (
FASTCALL *PKF_RAISE_IRQL) (
02634 IN KIRQL NewIrql
02635 );
02636
02637
THUNKED_API
02638 KIRQL
02639
FASTCALL
02640
VerifierKfRaiseIrql (
02641 IN KIRQL NewIrql
02642 )
02643 {
02644 PKF_RAISE_IRQL HalRoutine;
02645 KIRQL CurrentIrql;
02646
02647 CurrentIrql = KeGetCurrentIrql ();
02648
02649
KfSanityCheckRaiseIrql (NewIrql);
02650
02651
MmVerifierData.RaiseIrqls += 1;
02652
02653
if (
MmVerifierData.Level & DRIVER_VERIFIER_FORCE_IRQL_CHECKING) {
02654
if ((CurrentIrql < DISPATCH_LEVEL) && (NewIrql >=
DISPATCH_LEVEL)) {
02655
ViTrimAllSystemPagableMemory ();
02656 }
02657 }
02658
02659
#if defined (_X86_)
02660
HalRoutine = (PKF_RAISE_IRQL) (ULONG_PTR) MiKernelVerifierOriginalCalls[VI_KF_RAISE_IRQL];
02661
if (HalRoutine) {
02662
return (*HalRoutine)(NewIrql);
02663 }
02664
#endif
02665
02666
return KfRaiseIrql (NewIrql);
02667 }
02668
02669
typedef
02670
VOID
02671 (
FASTCALL *PKF_LOWER_IRQL) (
02672 IN KIRQL NewIrql
02673 );
02674
02675
THUNKED_API
02676
VOID
02677
FASTCALL
02678
VerifierKfLowerIrql (
02679 IN KIRQL NewIrql
02680 )
02681 {
02682 PKF_LOWER_IRQL HalRoutine;
02683
02684
KfSanityCheckLowerIrql (NewIrql);
02685
02686
#if defined (_X86_)
02687
HalRoutine = (PKF_LOWER_IRQL) (ULONG_PTR) MiKernelVerifierOriginalCalls[VI_KF_LOWER_IRQL];
02688
if (HalRoutine) {
02689 (*HalRoutine)(NewIrql);
02690
return;
02691 }
02692
#endif
02693
02694 KfLowerIrql (NewIrql);
02695 }
02696
02697
#endif
02698
02699
#if defined(_ALPHA_)
02700
THUNKED_API
02701
VOID
02702 VerifierKeAcquireSpinLockAtDpcLevel (
02703 IN PKSPIN_LOCK SpinLock
02704 )
02705 {
02706 KIRQL CurrentIrql;
02707
02708 CurrentIrql = KeGetCurrentIrql ();
02709
02710
02711
02712
02713
02714
if (CurrentIrql !=
DISPATCH_LEVEL) {
02715
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02716 0x40,
02717 CurrentIrql,
02718 (ULONG_PTR)SpinLock,
02719 0);
02720 }
02721
02722
MmVerifierData.AcquireSpinLocks += 1;
02723
02724
KeAcquireSpinLockAtDpcLevel (SpinLock);
02725 }
02726
02727
THUNKED_API
02728
VOID
02729 VerifierKeReleaseSpinLockFromDpcLevel (
02730 IN PKSPIN_LOCK SpinLock
02731 )
02732 {
02733 KIRQL CurrentIrql;
02734
02735 CurrentIrql = KeGetCurrentIrql ();
02736
02737
02738
02739
02740
02741
if (CurrentIrql !=
DISPATCH_LEVEL) {
02742
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02743 0x41,
02744 CurrentIrql,
02745 (ULONG_PTR)SpinLock,
02746 0);
02747 }
02748
02749
KeReleaseSpinLockFromDpcLevel (SpinLock);
02750 }
02751
02752
THUNKED_API
02753 KIRQL
02754 VerifierKeAcquireSpinLockRaiseToDpc (
02755 IN PKSPIN_LOCK SpinLock
02756 )
02757 {
02758 KIRQL CurrentIrql;
02759
02760 CurrentIrql = KeGetCurrentIrql ();
02761
02762
02763
02764
02765
02766
if (CurrentIrql >
DISPATCH_LEVEL) {
02767
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02768 0x42,
02769 CurrentIrql,
02770 (ULONG_PTR)SpinLock,
02771 0);
02772 }
02773
02774
MmVerifierData.AcquireSpinLocks += 1;
02775
02776
if (
MmVerifierData.Level & DRIVER_VERIFIER_FORCE_IRQL_CHECKING) {
02777
if (CurrentIrql <
DISPATCH_LEVEL) {
02778
ViTrimAllSystemPagableMemory ();
02779 }
02780 }
02781
02782
return KeAcquireSpinLockRaiseToDpc (SpinLock);
02783 }
02784
#endif
02785
02786
THUNKED_API
02787 BOOLEAN
02788
FASTCALL
02789 VerifierExTryToAcquireFastMutex (
02790 IN
PFAST_MUTEX FastMutex
02791 )
02792 {
02793 KIRQL CurrentIrql;
02794
02795 CurrentIrql = KeGetCurrentIrql ();
02796
02797
02798
02799
02800
02801
if (CurrentIrql >
APC_LEVEL) {
02802
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02803 0x33,
02804 CurrentIrql,
02805 (ULONG_PTR)FastMutex,
02806 0);
02807 }
02808
02809
return ExTryToAcquireFastMutex (FastMutex);
02810 }
02811
02812
THUNKED_API
02813
VOID
02814
FASTCALL
02815 VerifierExAcquireFastMutex (
02816 IN
PFAST_MUTEX FastMutex
02817 )
02818 {
02819 KIRQL CurrentIrql;
02820
02821 CurrentIrql = KeGetCurrentIrql ();
02822
02823
02824
02825
02826
02827
if (CurrentIrql >
APC_LEVEL) {
02828
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02829 0x33,
02830 CurrentIrql,
02831 (ULONG_PTR)FastMutex,
02832 0);
02833 }
02834
02835 ExAcquireFastMutex (FastMutex);
02836 }
02837
02838
THUNKED_API
02839
VOID
02840
FASTCALL
02841 VerifierExAcquireFastMutexUnsafe (
02842 IN
PFAST_MUTEX FastMutex
02843 )
02844 {
02845 KIRQL CurrentIrql;
02846
02847 CurrentIrql = KeGetCurrentIrql ();
02848
02849
02850
02851
02852
02853
if ((CurrentIrql !=
APC_LEVEL) &&
02854 (!
IS_SYSTEM_THREAD(
PsGetCurrentThread())) &&
02855 (
KeGetCurrentThread()->KernelApcDisable == 0)) {
02856
02857
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02858 0x39,
02859 CurrentIrql,
02860 (ULONG_PTR)(
KeGetCurrentThread()->KernelApcDisable),
02861 (ULONG_PTR)FastMutex);
02862 }
02863
02864
ExAcquireFastMutexUnsafe (FastMutex);
02865 }
02866
02867
THUNKED_API
02868
VOID
02869
FASTCALL
02870 VerifierExReleaseFastMutex (
02871 IN
PFAST_MUTEX FastMutex
02872 )
02873 {
02874 KIRQL CurrentIrql;
02875
02876 CurrentIrql = KeGetCurrentIrql ();
02877
02878
02879
02880
02881
02882
if ((CurrentIrql !=
APC_LEVEL) &&
02883 (!
IS_SYSTEM_THREAD(
PsGetCurrentThread())) &&
02884 (
KeGetCurrentThread()->KernelApcDisable == 0)) {
02885
02886
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02887 0x34,
02888 CurrentIrql,
02889 (ULONG_PTR)(
KeGetCurrentThread()->KernelApcDisable),
02890 (ULONG_PTR)FastMutex);
02891 }
02892
02893 ExReleaseFastMutex (FastMutex);
02894 }
02895
02896
THUNKED_API
02897
VOID
02898
FASTCALL
02899 VerifierExReleaseFastMutexUnsafe (
02900 IN
PFAST_MUTEX FastMutex
02901 )
02902 {
02903 KIRQL CurrentIrql;
02904
02905 CurrentIrql = KeGetCurrentIrql ();
02906
02907
02908
02909
02910
02911
if ((CurrentIrql !=
APC_LEVEL) &&
02912 (!
IS_SYSTEM_THREAD(
PsGetCurrentThread())) &&
02913 (
KeGetCurrentThread()->KernelApcDisable == 0)) {
02914
02915
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
02916 0x3A,
02917 CurrentIrql,
02918 (ULONG_PTR)(
KeGetCurrentThread()->KernelApcDisable),
02919 (ULONG_PTR)FastMutex);
02920 }
02921
02922
ExReleaseFastMutexUnsafe (FastMutex);
02923 }
02924
02925
typedef
02926
VOID
02927 (*PKE_RAISE_IRQL) (
02928 IN KIRQL NewIrql,
02929 OUT PKIRQL OldIrql
02930 );
02931
02932
THUNKED_API
02933
VOID
02934 VerifierKeRaiseIrql (
02935 IN KIRQL NewIrql,
02936 OUT PKIRQL OldIrql
02937 )
02938 {
02939
PKE_RAISE_IRQL HalRoutine;
02940
02941 *OldIrql = KeGetCurrentIrql ();
02942
02943
KfSanityCheckRaiseIrql (NewIrql);
02944
02945
MmVerifierData.RaiseIrqls += 1;
02946
02947
if (
MmVerifierData.Level & DRIVER_VERIFIER_FORCE_IRQL_CHECKING) {
02948
if ((*OldIrql < DISPATCH_LEVEL) && (NewIrql >=
DISPATCH_LEVEL)) {
02949
ViTrimAllSystemPagableMemory ();
02950 }
02951 }
02952
02953
#if defined (_X86_)
02954
HalRoutine = (
PKE_RAISE_IRQL) (ULONG_PTR) MiKernelVerifierOriginalCalls[VI_KE_RAISE_IRQL];
02955
if (HalRoutine) {
02956 (*HalRoutine)(NewIrql, OldIrql);
02957
return;
02958 }
02959
#endif
02960
02961
KeRaiseIrql (NewIrql, OldIrql);
02962 }
02963
02964
typedef
02965
VOID
02966 (*PKE_LOWER_IRQL) (
02967 IN KIRQL NewIrql
02968 );
02969
02970
THUNKED_API
02971
VOID
02972 VerifierKeLowerIrql (
02973 IN KIRQL NewIrql
02974 )
02975 {
02976
PKE_LOWER_IRQL HalRoutine;
02977
02978
KfSanityCheckLowerIrql (NewIrql);
02979
02980
#if defined (_X86_)
02981
HalRoutine = (
PKE_LOWER_IRQL) (ULONG_PTR) MiKernelVerifierOriginalCalls[VI_KE_LOWER_IRQL];
02982
if (HalRoutine) {
02983 (*HalRoutine)(NewIrql);
02984
return;
02985 }
02986
#endif
02987
02988
KeLowerIrql (NewIrql);
02989 }
02990
02991
THUNKED_API
02992 BOOLEAN
02993 VerifierSynchronizeExecution (
02994 IN
PKINTERRUPT Interrupt,
02995 IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,
02996 IN PVOID SynchronizeContext
02997 )
02998 {
02999 KIRQL OldIrql;
03000
03001 OldIrql = KeGetCurrentIrql ();
03002
03003
KfSanityCheckRaiseIrql (Interrupt->SynchronizeIrql);
03004
03005
MmVerifierData.SynchronizeExecutions += 1;
03006
03007
if (
MmVerifierData.Level & DRIVER_VERIFIER_FORCE_IRQL_CHECKING) {
03008
if ((OldIrql <
DISPATCH_LEVEL) && (Interrupt->SynchronizeIrql >=
DISPATCH_LEVEL)) {
03009
ViTrimAllSystemPagableMemory ();
03010 }
03011 }
03012
03013
return KeSynchronizeExecution (Interrupt,
03014 SynchronizeRoutine,
03015 SynchronizeContext);
03016 }
03017
03018
THUNKED_API
03019
VOID
03020 VerifierKeInitializeTimerEx(
03021 IN
PKTIMER Timer,
03022 IN TIMER_TYPE Type
03023 )
03024 {
03025
03026
03027
03028
03029
03030
if (
KiTimerTableListHead[0].Flink !=
NULL) {
03031
KeCheckForTimer(Timer,
sizeof(
KTIMER));
03032 }
03033
03034
KeInitializeTimerEx(Timer, Type);
03035 }
03036
03037
THUNKED_API
03038
VOID
03039 VerifierKeInitializeTimer(
03040 IN
PKTIMER Timer
03041 )
03042 {
03043
VerifierKeInitializeTimerEx(Timer, NotificationTimer);
03044 }
03045
03046
VOID
03047 ViInitializeEntry (
03048 IN
PMI_VERIFIER_DRIVER_ENTRY Verifier,
03049 IN LOGICAL FirstLoad
03050 )
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069
03070 {
03071 KIRQL OldIrql;
03072
03073
03074
03075
03076
03077
KeInitializeSpinLock (&Verifier->VerifierPoolLock);
03078
03079 Verifier->CurrentPagedPoolAllocations = 0;
03080 Verifier->CurrentNonPagedPoolAllocations = 0;
03081 Verifier->PeakPagedPoolAllocations = 0;
03082 Verifier->PeakNonPagedPoolAllocations = 0;
03083
03084 Verifier->PagedBytes = 0;
03085 Verifier->NonPagedBytes = 0;
03086 Verifier->PeakPagedBytes = 0;
03087 Verifier->PeakNonPagedBytes = 0;
03088
03089 Verifier->PoolHash =
NULL;
03090 Verifier->PoolHashSize = 0;
03091 Verifier->PoolHashFree =
VI_POOL_FREELIST_END;
03092 Verifier->PoolHashReserved = 0;
03093
03094 Verifier->Signature =
MI_VERIFIER_ENTRY_SIGNATURE;
03095
03096
if (FirstLoad ==
TRUE) {
03097 Verifier->Flags = 0;
03098 Verifier->Loads = 0;
03099 Verifier->Unloads = 0;
03100 }
03101
03102 ExAcquireSpinLock (&
VerifierListLock, &OldIrql);
03103 Verifier->StartAddress =
NULL;
03104 Verifier->EndAddress =
NULL;
03105 ExReleaseSpinLock (&
VerifierListLock, OldIrql);
03106 }
03107
03108 #define UNICODE_TAB 0x0009
03109 #define UNICODE_LF 0x000A
03110 #define UNICODE_CR 0x000D
03111 #define UNICODE_SPACE 0x0020
03112 #define UNICODE_CJK_SPACE 0x3000
03113
03114 #define UNICODE_WHITESPACE(_ch) (((_ch) == UNICODE_TAB) || \
03115
((_ch) == UNICODE_LF) || \
03116
((_ch) == UNICODE_CR) || \
03117
((_ch) == UNICODE_SPACE) || \
03118
((_ch) == UNICODE_CJK_SPACE))
03119
03120 LOGICAL
03121 MiInitializeDriverVerifierList (
03122 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
03123 )
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153 {
03154 ULONG i;
03155 PLIST_ENTRY NextEntry;
03156 PLDR_DATA_TABLE_ENTRY DataTableEntry;
03157 PWCHAR
Start;
03158 PWCHAR
End;
03159 PWCHAR Walk;
03160 ULONG NameLength;
03161
PMI_VERIFIER_DRIVER_ENTRY Verifier;
03162 LARGE_INTEGER CurrentTime;
03163 UNICODE_STRING KernelString;
03164 UNICODE_STRING HalString;
03165
PMI_VERIFIER_DRIVER_ENTRY KernelEntry;
03166
PMI_VERIFIER_DRIVER_ENTRY HalEntry;
03167
03168 InitializeListHead (&
MiSuspectDriverList);
03169
03170
if (
MmVerifyDriverLevel != (ULONG)-1) {
03171
if (
MmVerifyDriverLevel & DRIVER_VERIFIER_IO_CHECKING) {
03172
if (
MmVerifyDriverBufferLength == (ULONG)-1) {
03173
MmVerifyDriverBufferLength = 0;
03174 }
03175 }
03176 }
03177
03178
if (
MmVerifyDriverBufferLength == (ULONG)-1) {
03179
03180
if (
MmDontVerifyRandomDrivers ==
TRUE) {
03181
return FALSE;
03182 }
03183
03184
MmVerifyDriverBufferLength = 0;
03185
03186 CurrentTime =
KeQueryPerformanceCounter (
NULL);
03187 CurrentTime.LowPart = (CurrentTime.LowPart % 26);
03188
03189
MiVerifyRandomDrivers = (WCHAR)
'A' + (WCHAR)CurrentTime.LowPart;
03190
03191
if ((
MiVerifyRandomDrivers == (WCHAR)
'H') ||
03192 (
MiVerifyRandomDrivers == (WCHAR)
'J') ||
03193 (
MiVerifyRandomDrivers == (WCHAR)
'X') ||
03194 (
MiVerifyRandomDrivers == (WCHAR)
'Y') ||
03195 (
MiVerifyRandomDrivers == (WCHAR)
'Z')) {
03196
MiVerifyRandomDrivers = (WCHAR)
'X';
03197 }
03198 }
03199
03200
KeInitializeSpinLock (&
ViBadMapperLock);
03201
KeInitializeSpinLock (&
VerifierListLock);
03202
03203
KeInitializeSpinLock (&
VerifierPoolLock);
03204
ExInitializeFastMutex (&
VerifierPoolMutex);
03205
03206 InitializeListHead (&
MiVerifierDriverAddedThunkListHead);
03207
03208
03209
03210
03211
03212
03213
if (
MmVerifyDriverLevel == (ULONG)-1) {
03214
MmVerifierData.Level = DRIVER_VERIFIER_SPECIAL_POOLING |
03215 DRIVER_VERIFIER_FORCE_IRQL_CHECKING |
03216 DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS;
03217 }
03218
else {
03219
MmVerifierData.Level =
MmVerifyDriverLevel;
03220 }
03221
03222
VerifierModifyableOptions = (DRIVER_VERIFIER_SPECIAL_POOLING |
03223 DRIVER_VERIFIER_FORCE_IRQL_CHECKING |
03224 DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES);
03225
03226
IoVerifierInit (
MmVerifierData.Level,
IOVERIFIERINIT_PHASE0 |
03227
IOVERIFIERINIT_EVERYTHING_TRACKED |
03228
IOVERIFIERINIT_VERIFIER_DRIVER_LIST);
03229
03230 KernelEntry =
NULL;
03231 HalEntry =
NULL;
03232
03233
if (
MiVerifyRandomDrivers == (WCHAR)0) {
03234
03235
RtlInitUnicodeString (&KernelString,
L"ntoskrnl.exe");
03236
RtlInitUnicodeString (&HalString,
L"hal.dll");
03237
03238
Start =
MmVerifyDriverBuffer;
03239
End =
MmVerifyDriverBuffer + (
MmVerifyDriverBufferLength -
sizeof(WCHAR)) /
sizeof(WCHAR);
03240
03241
while (
Start <
End) {
03242
if (
UNICODE_WHITESPACE(*
Start)) {
03243
Start += 1;
03244
continue;
03245 }
03246
03247
if (*
Start == (WCHAR)
'*') {
03248
MiVerifyAllDrivers =
TRUE;
03249
break;
03250 }
03251
03252
for (Walk =
Start; Walk <
End; Walk += 1) {
03253
if (
UNICODE_WHITESPACE(*Walk)) {
03254
break;
03255 }
03256 }
03257
03258
03259
03260
03261
03262 NameLength = (ULONG)(Walk -
Start + 1) *
sizeof (WCHAR);
03263
03264 Verifier = (
PMI_VERIFIER_DRIVER_ENTRY)
ExAllocatePoolWithTag (
03265
NonPagedPool,
03266
sizeof (
MI_VERIFIER_DRIVER_ENTRY) +
03267 NameLength,
03268 'dLmM');
03269
03270
if (Verifier ==
NULL) {
03271
break;
03272 }
03273
03274 Verifier->
BaseName.Buffer = (PWSTR)((PCHAR)Verifier +
03275
sizeof (
MI_VERIFIER_DRIVER_ENTRY));
03276 Verifier->
BaseName.Length = (
USHORT)NameLength -
sizeof (UNICODE_NULL);
03277 Verifier->
BaseName.MaximumLength = (
USHORT)NameLength;
03278
03279 RtlMoveMemory (Verifier->
BaseName.Buffer,
03280
Start,
03281 NameLength - sizeof (UNICODE_NULL));
03282
03283
ViInitializeEntry (Verifier,
TRUE);
03284
03285 Verifier->
Flags |=
VI_VERIFYING_DIRECTLY;
03286
03287
ViInsertVerifierEntry (Verifier);
03288
03289
if (
RtlEqualUnicodeString (&KernelString,
03290 &Verifier->
BaseName,
03291
TRUE)) {
03292
03293
03294
03295
03296
03297
03298
MiVerifyAllDrivers =
TRUE;
03299
03300
KernelVerifier =
TRUE;
03301 KernelEntry = Verifier;
03302
03303 }
03304
else if (
RtlEqualUnicodeString (&HalString,
03305 &Verifier->
BaseName,
03306
TRUE)) {
03307 HalEntry = Verifier;
03308 }
03309
03310
Start = Walk + 1;
03311 }
03312 }
03313
03314
if (
MiTriageAddDrivers (LoaderBlock) ==
TRUE) {
03315
03316
03317
03318
03319
03320
MiVerifyRandomDrivers = (WCHAR)0;
03321 }
03322
03323
03324
03325
03326
03327 i = 0;
03328 NextEntry = LoaderBlock->LoadOrderListHead.Flink;
03329
03330
for ( ; NextEntry != &LoaderBlock->LoadOrderListHead; NextEntry = NextEntry->Flink) {
03331
03332 DataTableEntry = CONTAINING_RECORD(NextEntry,
03333 LDR_DATA_TABLE_ENTRY,
03334 InLoadOrderLinks);
03335
03336
03337
03338
03339
03340
if (i == 0) {
03341
if (KernelEntry !=
NULL) {
03342
MiApplyDriverVerifier (DataTableEntry, KernelEntry);
03343 }
03344 }
03345
else if (i == 1) {
03346
if (HalEntry !=
NULL) {
03347
MiApplyDriverVerifier (DataTableEntry, HalEntry);
03348 }
03349 }
03350
else {
03351
MiApplyDriverVerifier (DataTableEntry,
NULL);
03352 }
03353 i += 1;
03354 }
03355
03356
return TRUE;
03357 }
03358
03359
VOID
03360 ViInsertVerifierEntry (
03361 IN
PMI_VERIFIER_DRIVER_ENTRY Verifier
03362 )
03363
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383
03384
03385
03386
03387 {
03388 KIRQL OldIrql;
03389
03390 ExAcquireSpinLock (&
VerifierListLock, &OldIrql);
03391 InsertTailList (&
MiSuspectDriverList, &Verifier->Links);
03392 ExReleaseSpinLock (&
VerifierListLock, OldIrql);
03393 }
03394
03395
PMI_VERIFIER_DRIVER_ENTRY
03396 ViLocateVerifierEntry (
03397 IN PVOID SystemAddress
03398 )
03399
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412
03413
03414
03415
03416
03417
03418
03419
03420 {
03421 KIRQL OldIrql;
03422 PLIST_ENTRY NextEntry;
03423
PMI_VERIFIER_DRIVER_ENTRY Verifier;
03424
03425 ExAcquireSpinLock (&
VerifierListLock, &OldIrql);
03426
03427 NextEntry =
MiSuspectDriverList.Flink;
03428
while (NextEntry != &
MiSuspectDriverList) {
03429
03430 Verifier = CONTAINING_RECORD(NextEntry,
03431
MI_VERIFIER_DRIVER_ENTRY,
03432 Links);
03433
03434
if ((SystemAddress >= Verifier->
StartAddress) &&
03435 (SystemAddress < Verifier->
EndAddress)) {
03436
03437 ExReleaseSpinLock (&
VerifierListLock, OldIrql);
03438
return Verifier;
03439 }
03440 NextEntry = NextEntry->Flink;
03441 }
03442
03443 ExReleaseSpinLock (&
VerifierListLock, OldIrql);
03444
return NULL;
03445 }
03446
03447 LOGICAL
03448 MiApplyDriverVerifier (
03449 IN PLDR_DATA_TABLE_ENTRY DataTableEntry,
03450 IN
PMI_VERIFIER_DRIVER_ENTRY Verifier
03451 )
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480 {
03481 WCHAR FirstChar;
03482 LOGICAL Found;
03483 PLIST_ENTRY NextEntry;
03484 ULONG VerifierFlags;
03485
03486
if (Verifier !=
NULL) {
03487 Found =
TRUE;
03488 }
03489
else {
03490 Found =
FALSE;
03491 NextEntry =
MiSuspectDriverList.Flink;
03492
while (NextEntry != &
MiSuspectDriverList) {
03493
03494 Verifier = CONTAINING_RECORD(NextEntry,
03495
MI_VERIFIER_DRIVER_ENTRY,
03496 Links);
03497
03498
if (
RtlEqualUnicodeString (&Verifier->BaseName,
03499 &DataTableEntry->BaseDllName,
03500
TRUE)) {
03501
03502 Found =
TRUE;
03503
ViInitializeEntry (Verifier,
FALSE);
03504
break;
03505 }
03506 NextEntry = NextEntry->Flink;
03507 }
03508 }
03509
03510
if (Found ==
FALSE) {
03511 VerifierFlags =
VI_VERIFYING_DIRECTLY;
03512
if (
MiVerifyAllDrivers ==
TRUE) {
03513
if (
KernelVerifier ==
TRUE) {
03514 VerifierFlags =
VI_VERIFYING_INVERSELY;
03515 }
03516 Found =
TRUE;
03517 }
03518
else if (
MiVerifyRandomDrivers != (WCHAR)0) {
03519
03520
03521
03522
03523
03524 FirstChar =
RtlUpcaseUnicodeChar(DataTableEntry->BaseDllName.Buffer[0]);
03525
03526
if (
MiVerifyRandomDrivers == FirstChar) {
03527 Found =
TRUE;
03528 }
03529
else if (
MiVerifyRandomDrivers == (WCHAR)
'X') {
03530
if ((FirstChar >= (WCHAR)
'0') && (FirstChar <= (WCHAR)
'9')) {
03531 Found =
TRUE;
03532 }
03533 }
03534 }
03535
03536
if (Found ==
FALSE) {
03537
return FALSE;
03538 }
03539
03540 Verifier = (
PMI_VERIFIER_DRIVER_ENTRY)
ExAllocatePoolWithTag (
03541
NonPagedPool,
03542
sizeof (
MI_VERIFIER_DRIVER_ENTRY) +
03543 DataTableEntry->BaseDllName.MaximumLength,
03544 'dLmM');
03545
03546
if (Verifier ==
NULL) {
03547
return FALSE;
03548 }
03549
03550 Verifier->BaseName.Buffer = (PWSTR)((PCHAR)Verifier +
03551
sizeof (
MI_VERIFIER_DRIVER_ENTRY));
03552 Verifier->BaseName.Length = DataTableEntry->BaseDllName.Length;
03553 Verifier->BaseName.MaximumLength = DataTableEntry->BaseDllName.MaximumLength;
03554
03555 RtlMoveMemory (Verifier->BaseName.Buffer,
03556 DataTableEntry->BaseDllName.Buffer,
03557 DataTableEntry->BaseDllName.Length);
03558
03559
ViInitializeEntry (Verifier,
TRUE);
03560
03561 Verifier->Flags = VerifierFlags;
03562
03563
ViInsertVerifierEntry (Verifier);
03564 }
03565
03566 Verifier->StartAddress = DataTableEntry->DllBase;
03567 Verifier->EndAddress = (PVOID)((ULONG_PTR)DataTableEntry->DllBase + DataTableEntry->SizeOfImage);
03568
03569
if (
MiEnableVerifier (DataTableEntry) ==
TRUE) {
03570
03571
if (Verifier->Flags &
VI_VERIFYING_DIRECTLY) {
03572
ViPrintString (&DataTableEntry->BaseDllName);
03573 }
03574
03575
MmVerifierData.Loads += 1;
03576
03577 Verifier->Loads += 1;
03578
03579 DataTableEntry->Flags |= LDRP_IMAGE_VERIFYING;
03580
MiActiveVerifies += 1;
03581
03582
if (
MiActiveVerifies == 1) {
03583
03584
03585
03586
03587
03588
MiIoRetryLevel = (ULONG)-1;
03589
MiFaultRetries =
MiIoRetryLevel;
03590
MiUserIoRetryLevel = (ULONG)-1;
03591
MiUserFaultRetries =
MiUserIoRetryLevel;
03592
03593
#ifndef NO_POOL_CHECKS
03594
03595
03596
03597
03598
03599
03600
03601
03602
MiEnableRandomSpecialPool (
FALSE);
03603
#endif
03604
if (
MmVerifierData.Level & DRIVER_VERIFIER_FORCE_IRQL_CHECKING) {
03605
03606
03607
03608
03609
03610
03611
if (
KernelVerifier ==
FALSE) {
03612
MiVerifierStackProtectTime =
KiStackProtectTime;
03613
KiStackProtectTime = 0;
03614 }
03615 }
03616 }
03617 }
03618
03619
return Found;
03620 }
03621
03622 PUNICODE_STRING
ViBadDriver;
03623
03624
VOID
03625 MiVerifyingDriverUnloading (
03626 IN PLDR_DATA_TABLE_ENTRY DataTableEntry
03627 )
03628
03629
03630
03631
03632
03633
03634
03635
03636
03637
03638
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650
03651
03652 {
03653 KIRQL OldIrql;
03654 LOGICAL Found;
03655 PLIST_ENTRY NextEntry;
03656
PMI_VERIFIER_DRIVER_ENTRY Verifier;
03657
PVI_POOL_ENTRY OldHashTable;
03658
03659 Found =
FALSE;
03660 NextEntry =
MiSuspectDriverList.Flink;
03661
while (NextEntry != &
MiSuspectDriverList) {
03662
03663 Verifier = CONTAINING_RECORD(NextEntry,
03664
MI_VERIFIER_DRIVER_ENTRY,
03665 Links);
03666
03667
if (
RtlEqualUnicodeString (&Verifier->
BaseName,
03668 &DataTableEntry->BaseDllName,
03669
TRUE)) {
03670
03671 Found =
TRUE;
03672
break;
03673 }
03674 NextEntry = NextEntry->Flink;
03675 }
03676
03677
ASSERT (Found ==
TRUE);
03678
03679
if (
MmVerifierData.Level & DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS) {
03680
03681
03682
03683
03684
03685
03686
03687
if (Verifier->
PagedBytes) {
03688
03689
#if DBG
03690
DbgPrint (
"Driver %wZ leaked %d paged pool allocations (0x%x bytes)\n",
03691 &DataTableEntry->FullDllName,
03692 Verifier->
CurrentPagedPoolAllocations,
03693 Verifier->
PagedBytes);
03694
#endif
03695
03696
03697
03698
03699
03700
03701
03702
03703
03704
03705
03706 InterlockedIncrement ((PLONG)&
MiNoPageOnRaiseIrql);
03707 }
03708
03709
#if DBG
03710
if (Verifier->
NonPagedBytes) {
03711
DbgPrint (
"Driver %wZ leaked %d nonpaged pool allocations (0x%x bytes)\n",
03712 &DataTableEntry->FullDllName,
03713 Verifier->
CurrentNonPagedPoolAllocations,
03714 Verifier->
NonPagedBytes);
03715 }
03716
#endif
03717
03718
if (Verifier->
PagedBytes || Verifier->
NonPagedBytes) {
03719
#if 0
03720
DbgBreakPoint ();
03721 InterlockedDecrement (&
MiNoPageOnRaiseIrql);
03722
#else
03723
03724
03725
03726
03727
ViBadDriver = &Verifier->
BaseName;
03728
03729
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
03730 0x60,
03731 Verifier->
PagedBytes,
03732 Verifier->
NonPagedBytes,
03733 Verifier->
CurrentPagedPoolAllocations +
03734 Verifier->
CurrentNonPagedPoolAllocations);
03735
#endif
03736
}
03737
03738 ExAcquireSpinLock (&Verifier->
VerifierPoolLock, &OldIrql);
03739
03740
if (Verifier->
PoolHashReserved != 0) {
03741
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
03742 0x61,
03743 Verifier->
PagedBytes,
03744 Verifier->
NonPagedBytes,
03745 Verifier->
CurrentPagedPoolAllocations +
03746 Verifier->
CurrentNonPagedPoolAllocations);
03747 }
03748
03749 OldHashTable = Verifier->
PoolHash;
03750
if (OldHashTable !=
NULL) {
03751 Verifier->
PoolHashSize = 0;
03752 Verifier->
PoolHashFree =
VI_POOL_FREELIST_END;
03753 Verifier->
PoolHash =
NULL;
03754 }
03755
else {
03756
ASSERT (Verifier->
PoolHashSize == 0);
03757
ASSERT (Verifier->
PoolHashFree ==
VI_POOL_FREELIST_END);
03758 }
03759
03760 ExReleaseSpinLock (&Verifier->
VerifierPoolLock, OldIrql);
03761
03762
if (OldHashTable !=
NULL) {
03763
ExFreePool (OldHashTable);
03764 }
03765
03766
03767
03768
03769
03770
03771 ExAcquireSpinLock (&
VerifierListLock, &OldIrql);
03772 Verifier->
StartAddress =
NULL;
03773 Verifier->
EndAddress =
NULL;
03774 ExReleaseSpinLock (&
VerifierListLock, OldIrql);
03775 }
03776
03777 Verifier->
Unloads += 1;
03778
MmVerifierData.Unloads += 1;
03779
MiActiveVerifies -= 1;
03780
03781
if (
MiActiveVerifies == 0) {
03782
03783
if (
MmVerifierData.Level & DRIVER_VERIFIER_FORCE_IRQL_CHECKING) {
03784
03785
03786
03787
03788
03789
if (
KernelVerifier ==
FALSE) {
03790
KiStackProtectTime =
MiVerifierStackProtectTime;
03791 }
03792 }
03793
03794
#ifndef NO_POOL_CHECKS
03795
MiEnableRandomSpecialPool (
TRUE);
03796
#endif
03797
}
03798 }
03799
03800
NTKERNELAPI
03801 LOGICAL
03802 MmIsDriverVerifying (
03803 IN
PDRIVER_OBJECT DriverObject
03804 )
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827 {
03828 PLDR_DATA_TABLE_ENTRY DataTableEntry;
03829
03830 DataTableEntry = (PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection;
03831
03832
if (DataTableEntry ==
NULL) {
03833
return FALSE;
03834 }
03835
03836
if ((DataTableEntry->Flags & LDRP_IMAGE_VERIFYING) == 0) {
03837
return FALSE;
03838 }
03839
03840
return TRUE;
03841 }
03842
03843 #define MM_BOOT_IMAGE_SIZE (16 * 1024 * 1024)
03844
03845
NTSTATUS
03846 MmAddVerifierThunks (
03847 IN PVOID ThunkBuffer,
03848 IN ULONG ThunkBufferSize
03849 )
03850
03851
03852
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873 {
03874 ULONG i;
03875 ULONG NumberOfThunkPairs;
03876 PDRIVER_VERIFIER_THUNK_PAIRS ThunkPairs;
03877 PDRIVER_VERIFIER_THUNK_PAIRS ThunkTable;
03878
PDRIVER_SPECIFIED_VERIFIER_THUNKS ThunkTableBase;
03879 PLDR_DATA_TABLE_ENTRY DataTableEntry;
03880 PVOID DriverStartAddress;
03881 PVOID DriverEndAddress;
03882
03883
PAGED_CODE();
03884
03885
if (
MiVerifierDriverAddedThunkListHead.Flink ==
NULL) {
03886
return STATUS_NOT_SUPPORTED;
03887 }
03888
03889 ThunkPairs = (PDRIVER_VERIFIER_THUNK_PAIRS)ThunkBuffer;
03890 NumberOfThunkPairs = ThunkBufferSize /
sizeof(DRIVER_VERIFIER_THUNK_PAIRS);
03891
03892
if (NumberOfThunkPairs == 0) {
03893
return STATUS_INVALID_PARAMETER_1;
03894 }
03895
03896 ThunkTableBase = (
PDRIVER_SPECIFIED_VERIFIER_THUNKS)
ExAllocatePoolWithTag (
03897
PagedPool,
03898
sizeof (
DRIVER_SPECIFIED_VERIFIER_THUNKS) + NumberOfThunkPairs *
sizeof (DRIVER_VERIFIER_THUNK_PAIRS),
03899 'tVmM');
03900
03901
if (ThunkTableBase ==
NULL) {
03902
return STATUS_INSUFFICIENT_RESOURCES;
03903 }
03904
03905 ThunkTable = (PDRIVER_VERIFIER_THUNK_PAIRS)(ThunkTableBase + 1);
03906
03907 RtlCopyMemory (ThunkTable,
03908 ThunkPairs,
03909 NumberOfThunkPairs *
sizeof(DRIVER_VERIFIER_THUNK_PAIRS));
03910
03911
KeEnterCriticalRegion();
03912
03913
KeWaitForSingleObject (&
MmSystemLoadLock,
03914
WrVirtualMemory,
03915
KernelMode,
03916
FALSE,
03917 (PLARGE_INTEGER)
NULL);
03918
03919
03920
03921
03922
03923 DataTableEntry =
MiLookupDataTableEntry (ThunkTable->PristineRoutine,
03924
TRUE);
03925
03926
if (DataTableEntry ==
NULL) {
03927
KeReleaseMutant (&
MmSystemLoadLock, 1,
FALSE,
FALSE);
03928
KeLeaveCriticalRegion();
03929
ExFreePool (ThunkTableBase);
03930
return STATUS_INVALID_PARAMETER_2;
03931 }
03932
03933 DriverStartAddress = (PVOID)(DataTableEntry->DllBase);
03934 DriverEndAddress = (PVOID)((PCHAR)DataTableEntry->DllBase + DataTableEntry->SizeOfImage);
03935
03936
03937
03938
03939
03940
if (DriverStartAddress < (PVOID)(
KSEG0_BASE +
MM_BOOT_IMAGE_SIZE)) {
03941
KeReleaseMutant (&
MmSystemLoadLock, 1,
FALSE,
FALSE);
03942
KeLeaveCriticalRegion();
03943
ExFreePool (ThunkTableBase);
03944
return STATUS_INVALID_PARAMETER_2;
03945 }
03946
03947
for (i = 0; i < NumberOfThunkPairs; i += 1) {
03948
03949
03950
03951
03952
03953
if (((ULONG_PTR)ThunkTable->PristineRoutine < (ULONG_PTR)DriverStartAddress) ||
03954 ((ULONG_PTR)ThunkTable->PristineRoutine >= (ULONG_PTR)DriverEndAddress)) {
03955
03956
KeReleaseMutant (&
MmSystemLoadLock, 1,
FALSE,
FALSE);
03957
KeLeaveCriticalRegion();
03958
ExFreePool (ThunkTableBase);
03959
return STATUS_INVALID_PARAMETER_2;
03960 }
03961 ThunkTable += 1;
03962 }
03963
03964
03965
03966
03967
03968 ThunkTableBase->
DataTableEntry = DataTableEntry;
03969 ThunkTableBase->
NumberOfThunks = NumberOfThunkPairs;
03970
MiActiveVerifierThunks += 1;
03971
03972 InsertTailList (&
MiVerifierDriverAddedThunkListHead,
03973 &ThunkTableBase->
ListEntry);
03974
03975
KeReleaseMutant (&
MmSystemLoadLock, 1,
FALSE,
FALSE);
03976
KeLeaveCriticalRegion();
03977
03978
return STATUS_SUCCESS;
03979 }
03980
03981
VOID
03982 MiVerifierCheckThunks (
03983 IN PLDR_DATA_TABLE_ENTRY DataTableEntry
03984 )
03985
03986
03987
03988
03989
03990
03991
03992
03993
03994
03995
03996
03997
03998
03999
04000
04001
04002
04003
04004
04005
04006
04007 {
04008 PLIST_ENTRY NextEntry;
04009
PDRIVER_SPECIFIED_VERIFIER_THUNKS ThunkTableBase;
04010
04011
PAGED_CODE ();
04012
04013
04014
04015
04016
04017
04018 NextEntry =
MiVerifierDriverAddedThunkListHead.Flink;
04019
while (NextEntry != &
MiVerifierDriverAddedThunkListHead) {
04020
04021 ThunkTableBase = CONTAINING_RECORD(NextEntry,
04022
DRIVER_SPECIFIED_VERIFIER_THUNKS,
04023 ListEntry);
04024
04025
if (ThunkTableBase->
DataTableEntry == DataTableEntry) {
04026 RemoveEntryList (NextEntry);
04027 NextEntry = NextEntry->Flink;
04028
ExFreePool (ThunkTableBase);
04029
MiActiveVerifierThunks -= 1;
04030
04031
04032
04033
04034
04035
continue;
04036 }
04037
04038 NextEntry = NextEntry->Flink;
04039 }
04040 }
04041
04042 #define ROUND_UP(VALUE,ROUND) ((ULONG)(((ULONG)VALUE + \
04043
((ULONG)ROUND - 1L)) & (~((ULONG)ROUND - 1L))))
04044
04045
NTSTATUS
04046 MmGetVerifierInformation (
04047 OUT PVOID SystemInformation,
04048 IN ULONG SystemInformationLength,
04049 OUT PULONG Length
04050 )
04051
04052
04053
04054
04055
04056
04057
04058
04059
04060
04061
04062
04063
04064
04065
04066
04067
04068
04069
04070
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080 {
04081 PSYSTEM_VERIFIER_INFORMATION UserVerifyBuffer;
04082 ULONG NextEntryOffset;
04083 ULONG TotalSize;
04084
NTSTATUS Status;
04085 PLIST_ENTRY NextEntry;
04086
PMI_VERIFIER_DRIVER_ENTRY Verifier;
04087 UNICODE_STRING UserBufferDriverName;
04088
04089
PAGED_CODE();
04090
04091 NextEntryOffset = 0;
04092 TotalSize = 0;
04093
04094 *Length = 0;
04095 UserVerifyBuffer = (PSYSTEM_VERIFIER_INFORMATION)SystemInformation;
04096
04097
04098
04099
04100
04101
04102
Status = STATUS_SUCCESS;
04103
04104
KeEnterCriticalRegion();
04105
04106
KeWaitForSingleObject (&
MmSystemLoadLock,
04107
WrVirtualMemory,
04108
KernelMode,
04109
FALSE,
04110 (PLARGE_INTEGER)
NULL);
04111
04112
try {
04113
04114 NextEntry =
MiSuspectDriverList.Flink;
04115
while (NextEntry != &
MiSuspectDriverList) {
04116
04117 Verifier = CONTAINING_RECORD(NextEntry,
04118
MI_VERIFIER_DRIVER_ENTRY,
04119 Links);
04120
04121
if ((Verifier->
Flags &
VI_VERIFYING_DIRECTLY) == 0) {
04122 NextEntry = NextEntry->Flink;
04123
continue;
04124 }
04125
04126 UserVerifyBuffer = (PSYSTEM_VERIFIER_INFORMATION)(
04127 (PUCHAR)UserVerifyBuffer + NextEntryOffset);
04128 NextEntryOffset =
sizeof(SYSTEM_VERIFIER_INFORMATION);
04129 TotalSize +=
sizeof(SYSTEM_VERIFIER_INFORMATION);
04130
04131
if (TotalSize > SystemInformationLength) {
04132
ExRaiseStatus (STATUS_INFO_LENGTH_MISMATCH);
04133 }
04134
04135
04136
04137
04138
04139 UserVerifyBuffer->Level =
MmVerifierData.Level;
04140 UserVerifyBuffer->RaiseIrqls =
MmVerifierData.RaiseIrqls;
04141 UserVerifyBuffer->AcquireSpinLocks =
MmVerifierData.AcquireSpinLocks;
04142
04143 UserVerifyBuffer->UnTrackedPool =
MmVerifierData.UnTrackedPool;
04144 UserVerifyBuffer->SynchronizeExecutions =
MmVerifierData.SynchronizeExecutions;
04145
04146 UserVerifyBuffer->AllocationsAttempted =
MmVerifierData.AllocationsAttempted;
04147 UserVerifyBuffer->AllocationsSucceeded =
MmVerifierData.AllocationsSucceeded;
04148 UserVerifyBuffer->AllocationsSucceededSpecialPool =
MmVerifierData.AllocationsSucceededSpecialPool;
04149 UserVerifyBuffer->AllocationsWithNoTag =
MmVerifierData.AllocationsWithNoTag;
04150
04151 UserVerifyBuffer->TrimRequests =
MmVerifierData.TrimRequests;
04152 UserVerifyBuffer->Trims =
MmVerifierData.Trims;
04153 UserVerifyBuffer->AllocationsFailed =
MmVerifierData.AllocationsFailed;
04154 UserVerifyBuffer->AllocationsFailedDeliberately =
MmVerifierData.AllocationsFailedDeliberately;
04155
04156
04157
04158
04159
04160 UserVerifyBuffer->CurrentPagedPoolAllocations = Verifier->
CurrentPagedPoolAllocations;
04161 UserVerifyBuffer->CurrentNonPagedPoolAllocations = Verifier->
CurrentNonPagedPoolAllocations;
04162 UserVerifyBuffer->PeakPagedPoolAllocations = Verifier->
PeakPagedPoolAllocations;
04163 UserVerifyBuffer->PeakNonPagedPoolAllocations = Verifier->
PeakNonPagedPoolAllocations;
04164
04165 UserVerifyBuffer->PagedPoolUsageInBytes = Verifier->
PagedBytes;
04166 UserVerifyBuffer->NonPagedPoolUsageInBytes = Verifier->
NonPagedBytes;
04167 UserVerifyBuffer->PeakPagedPoolUsageInBytes = Verifier->
PeakPagedBytes;
04168 UserVerifyBuffer->PeakNonPagedPoolUsageInBytes = Verifier->
PeakNonPagedBytes;
04169
04170 UserVerifyBuffer->Loads = Verifier->
Loads;
04171 UserVerifyBuffer->Unloads = Verifier->
Unloads;
04172
04173
04174
04175
04176
04177
04178
04179
04180 UserBufferDriverName.Length = Verifier->
BaseName.Length;
04181 UserBufferDriverName.MaximumLength = Verifier->
BaseName.Length +
sizeof (WCHAR);
04182 UserBufferDriverName.Buffer = (PWCHAR)(UserVerifyBuffer + 1);
04183
04184 UserVerifyBuffer->DriverName = UserBufferDriverName;
04185
04186 TotalSize +=
ROUND_UP (UserBufferDriverName.MaximumLength,
04187
sizeof(ULONG));
04188 NextEntryOffset +=
ROUND_UP (UserBufferDriverName.MaximumLength,
04189
sizeof(ULONG));
04190
04191
if (TotalSize > SystemInformationLength) {
04192
ExRaiseStatus (STATUS_INFO_LENGTH_MISMATCH);
04193 }
04194
04195
04196
04197
04198
04199 RtlMoveMemory(UserBufferDriverName.Buffer,
04200 Verifier->
BaseName.Buffer,
04201 Verifier->
BaseName.Length);
04202
04203 UserBufferDriverName.Buffer[
04204 Verifier->
BaseName.Length/
sizeof(WCHAR)] = UNICODE_NULL;
04205 UserVerifyBuffer->NextEntryOffset = NextEntryOffset;
04206
04207 NextEntry = NextEntry->Flink;
04208 }
04209 } except (
EXCEPTION_EXECUTE_HANDLER) {
04210
Status = GetExceptionCode();
04211 }
04212
04213
KeReleaseMutant (&
MmSystemLoadLock, 1,
FALSE,
FALSE);
04214
04215
KeLeaveCriticalRegion();
04216
04217
if (
Status != STATUS_INFO_LENGTH_MISMATCH) {
04218 UserVerifyBuffer->NextEntryOffset = 0;
04219 *Length = TotalSize;
04220 }
04221
04222
return Status;
04223 }
04224
04225
NTSTATUS
04226 MmSetVerifierInformation (
04227 IN OUT PVOID SystemInformation,
04228 IN ULONG SystemInformationLength
04229 )
04230
04231
04232
04233
04234
04235
04236
04237
04238
04239
04240
04241
04242
04243
04244
04245
04246
04247
04248
04249
04250
04251
04252
04253
04254
04255
04256
04257 {
04258 ULONG UserFlags;
04259 ULONG NewFlags;
04260 ULONG NewFlagsOn;
04261 ULONG NewFlagsOff;
04262
NTSTATUS Status;
04263 PULONG UserVerifyBuffer;
04264
04265
PAGED_CODE();
04266
04267
if (SystemInformationLength <
sizeof (ULONG)) {
04268
ExRaiseStatus (STATUS_INFO_LENGTH_MISMATCH);
04269 }
04270
04271 UserVerifyBuffer = (PULONG)SystemInformation;
04272
04273
04274
04275
04276
04277
Status = STATUS_SUCCESS;
04278
04279
KeEnterCriticalRegion();
04280
04281
KeWaitForSingleObject (&
MmSystemLoadLock,
04282
WrVirtualMemory,
04283
KernelMode,
04284
FALSE,
04285 (PLARGE_INTEGER)
NULL);
04286
04287
try {
04288
04289 UserFlags = *UserVerifyBuffer;
04290
04291
04292
04293
04294
04295
04296 NewFlagsOn = UserFlags &
VerifierModifyableOptions;
04297
04298 NewFlags =
MmVerifierData.Level | NewFlagsOn;
04299
04300
04301
04302
04303
04304 NewFlagsOff = ((~UserFlags) &
VerifierModifyableOptions);
04305
04306 NewFlags &= ~NewFlagsOff;
04307
04308
if (NewFlags !=
MmVerifierData.Level) {
04309
VerifierOptionChanges += 1;
04310
MmVerifierData.Level = NewFlags;
04311 *UserVerifyBuffer = NewFlags;
04312 }
04313
04314 } except (
EXCEPTION_EXECUTE_HANDLER) {
04315
Status = GetExceptionCode();
04316 }
04317
04318
KeReleaseMutant (&
MmSystemLoadLock, 1,
FALSE,
FALSE);
04319
04320
KeLeaveCriticalRegion();
04321
04322
return Status;
04323 }
04324
04325 typedef struct _VERIFIER_STRING_INFO {
04326 ULONG
BuildNumber;
04327 ULONG
DriverVerifierLevel;
04328 ULONG
Flags;
04329 ULONG
Check;
04330 }
VERIFIER_STRING_INFO, *
PVERIFIER_STRING_INFO;
04331
04332 static WCHAR
Printable[] =
L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
04333 static ULONG
PrintableChars =
sizeof (
Printable) /
sizeof (
Printable[0]) - 1;
04334
04335
VOID
04336 ViPrintString (
04337 IN PUNICODE_STRING DriverName
04338 )
04339
04340
04341
04342
04343
04344
04345
04346
04347
04348
04349
04350
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360 {
04361
VERIFIER_STRING_INFO Bld;
04362 PUCHAR BufPtr;
04363 PWCHAR DriverPtr;
04364 ULONG BufLen;
04365 ULONG i;
04366 ULONG j;
04367 ULONG DriverChars;
04368 ULONG MaxChars;
04369 WCHAR OutBuf[
sizeof (
VERIFIER_STRING_INFO) * 2 + 1];
04370 UNICODE_STRING OutBufU;
04371 ULONG Rem;
04372 ULONG LastRem;
04373 LOGICAL Done;
04374
04375 Bld.
BuildNumber =
NtBuildNumber;
04376 Bld.
DriverVerifierLevel =
MmVerifierData.Level;
04377
04378
04379
04380
04381
04382 Bld.
Flags = 0;
04383
04384
04385
04386
04387
04388 Bld.
Check = ((Bld.
Flags + 1) * Bld.
BuildNumber * (Bld.
DriverVerifierLevel + 1)) * 123456789;
04389
04390 BufPtr = (PUCHAR) &Bld;
04391 BufLen =
sizeof (Bld);
04392
04393 DriverChars = DriverName->Length /
sizeof (DriverName->Buffer[0]);
04394 DriverPtr = DriverName->Buffer;
04395 MaxChars = DriverChars;
04396
04397
if (DriverChars <
sizeof (
VERIFIER_STRING_INFO)) {
04398 MaxChars =
sizeof (
VERIFIER_STRING_INFO);
04399 }
04400
04401
04402
04403
04404
04405
for (i = 0; i < MaxChars; i += 1) {
04406 BufPtr[i % BufLen] ^= (UCHAR)
RtlUpcaseUnicodeChar(DriverPtr[i % DriverChars]);
04407 }
04408
04409
04410
04411
04412
04413
04414
04415 j = 0;
04416
do {
04417 Done =
TRUE;
04418
04419
for (i = 0, LastRem = 0; i <
sizeof (
VERIFIER_STRING_INFO); i += 1) {
04420 Rem = BufPtr[i] + 256 * LastRem;
04421 BufPtr[i] = (UCHAR) (Rem /
PrintableChars);
04422 LastRem = Rem %
PrintableChars;
04423
if (BufPtr[i]) {
04424 Done =
FALSE;
04425 }
04426 }
04427 OutBuf[j++] =
Printable[LastRem];
04428
04429
if (j >=
sizeof (OutBuf) /
sizeof (OutBuf[0])) {
04430
04431
04432
04433
04434
04435
return;
04436 }
04437
04438 }
while (Done ==
FALSE);
04439
04440 OutBuf[j] =
L'\0';
04441
04442 OutBufU.Length = OutBufU.MaximumLength = (
USHORT) j *
sizeof (WCHAR);
04443 OutBufU.Buffer = OutBuf;
04444
04445
DbgPrint (
"*******************************************************************************\n");
04446
DbgPrint (
"* *\n");
04447
04448
DbgPrint (
"* This is the string to paste into your build mail\n");
04449
04450
DbgPrint (
"* Driver Verifier: Enabled for %Z on Build %ld %wZ\n",
04451 DriverName,
NtBuildNumber & 0xFFFFFFF, &OutBufU);
04452
04453
DbgPrint (
"* *\n");
04454
DbgPrint (
"*******************************************************************************\n");
04455
04456
return;
04457 }
04458
04459
04460
04461
04462
04463
04464
04465
04466
04467
04468
04469
04470
#undef KeRaiseIrql
04471
#undef KeLowerIrql
04472
#undef KeAcquireSpinLock
04473
#undef KeReleaseSpinLock
04474
#undef ExAcquireResourceExclusive
04475
04476
VOID
04477
KeRaiseIrql (
04478 IN KIRQL NewIrql,
04479 OUT PKIRQL OldIrql
04480 );
04481
04482
VOID
04483
KeLowerIrql (
04484 IN KIRQL NewIrql
04485 );
04486
04487
VOID
04488
KeAcquireSpinLock (
04489 IN PKSPIN_LOCK SpinLock,
04490 OUT PKIRQL OldIrql
04491 );
04492
04493
VOID
04494
KeReleaseSpinLock (
04495 IN PKSPIN_LOCK SpinLock,
04496 IN KIRQL NewIrql
04497 );
04498
04499 BOOLEAN
04500
ExAcquireResourceExclusive (
04501 IN
PERESOURCE Resource,
04502 IN BOOLEAN Wait
04503 );
04504
04505
#if defined(_X86_)
04506
#define X86_HAL_ROUTINE 1
04507
#else
04508 #define X86_HAL_ROUTINE 0
04509
#endif
04510
04511 #define POOL_ROUTINE 2
04512
04513 #define VERIFIER_THUNK_IN_HAL(Flag) (Flag & X86_HAL_ROUTINE)
04514 #define VERIFIER_POOL_ROUTINE(Flag) (Flag & POOL_ROUTINE)
04515
04516 VERIFIER_THUNKS MiVerifierThunks[] = {
04517
04518 (PDRIVER_VERIFIER_THUNK_ROUTINE)
ExAllocatePool,
04519 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierAllocatePool,
04520
POOL_ROUTINE,
04521
04522 (PDRIVER_VERIFIER_THUNK_ROUTINE)
ExAllocatePoolWithQuota,
04523 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierAllocatePoolWithQuota,
04524
POOL_ROUTINE,
04525
04526 (PDRIVER_VERIFIER_THUNK_ROUTINE)
ExAllocatePoolWithQuotaTag,
04527 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierAllocatePoolWithQuotaTag,
04528
POOL_ROUTINE,
04529
04530 (PDRIVER_VERIFIER_THUNK_ROUTINE)
ExAllocatePoolWithTag,
04531 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierAllocatePoolWithTag,
04532
POOL_ROUTINE,
04533
04534 (PDRIVER_VERIFIER_THUNK_ROUTINE)
ExAllocatePoolWithTagPriority,
04535 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierAllocatePoolWithTagPriority,
04536
POOL_ROUTINE,
04537
04538 (PDRIVER_VERIFIER_THUNK_ROUTINE)
ExFreePool,
04539 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierFreePool,
04540
POOL_ROUTINE,
04541
04542 (PDRIVER_VERIFIER_THUNK_ROUTINE)
ExFreePoolWithTag,
04543 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierFreePoolWithTag,
04544
POOL_ROUTINE,
04545
04546 (PDRIVER_VERIFIER_THUNK_ROUTINE)
KeSetEvent,
04547 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierSetEvent,
04548 0,
04549
04550 (PDRIVER_VERIFIER_THUNK_ROUTINE)
ExAcquireFastMutexUnsafe,
04551 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierExAcquireFastMutexUnsafe,
04552 0,
04553
04554 (PDRIVER_VERIFIER_THUNK_ROUTINE)
ExReleaseFastMutexUnsafe,
04555 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierExReleaseFastMutexUnsafe,
04556 0,
04557
04558
#if 0
04559
04560
04561
04562 (PDRIVER_VERIFIER_THUNK_ROUTINE)
ExAcquireResourceExclusive,
04563 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierExAcquireResourceExclusive,
04564 0,
04565
#endif
04566
04567 (PDRIVER_VERIFIER_THUNK_ROUTINE)
ExAcquireResourceExclusiveLite,
04568 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierExAcquireResourceExclusive,
04569 0,
04570
04571 (PDRIVER_VERIFIER_THUNK_ROUTINE)
ExReleaseResourceLite,
04572 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierExReleaseResource,
04573 0,
04574
04575 (PDRIVER_VERIFIER_THUNK_ROUTINE)
MmProbeAndLockPages,
04576 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierProbeAndLockPages,
04577 0,
04578
04579 (PDRIVER_VERIFIER_THUNK_ROUTINE)
MmProbeAndLockProcessPages,
04580 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierProbeAndLockProcessPages,
04581 0,
04582
04583 (PDRIVER_VERIFIER_THUNK_ROUTINE)
MmMapIoSpace,
04584 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierMapIoSpace,
04585 0,
04586
04587 (PDRIVER_VERIFIER_THUNK_ROUTINE)
MmMapLockedPages,
04588 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierMapLockedPages,
04589 0,
04590
04591 (PDRIVER_VERIFIER_THUNK_ROUTINE)
MmMapLockedPagesSpecifyCache,
04592 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierMapLockedPagesSpecifyCache,
04593 0,
04594
04595 (PDRIVER_VERIFIER_THUNK_ROUTINE)
MmUnlockPages,
04596 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierUnlockPages,
04597 0,
04598
04599 (PDRIVER_VERIFIER_THUNK_ROUTINE)
MmUnmapLockedPages,
04600 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierUnmapLockedPages,
04601 0,
04602
04603 (PDRIVER_VERIFIER_THUNK_ROUTINE)
MmUnmapIoSpace,
04604 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierUnmapIoSpace,
04605 0,
04606
04607
04608
04609
04610
04611
04612 (PDRIVER_VERIFIER_THUNK_ROUTINE)ExAcquireFastMutex,
04613 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierExAcquireFastMutex,
04614
X86_HAL_ROUTINE,
04615
04616 (PDRIVER_VERIFIER_THUNK_ROUTINE)ExTryToAcquireFastMutex,
04617 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierExTryToAcquireFastMutex,
04618
X86_HAL_ROUTINE,
04619
04620 (PDRIVER_VERIFIER_THUNK_ROUTINE)ExReleaseFastMutex,
04621 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierExReleaseFastMutex,
04622
X86_HAL_ROUTINE,
04623
04624 (PDRIVER_VERIFIER_THUNK_ROUTINE)
KeRaiseIrql,
04625 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKeRaiseIrql,
04626
X86_HAL_ROUTINE,
04627
04628 (PDRIVER_VERIFIER_THUNK_ROUTINE)
KeLowerIrql,
04629 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKeLowerIrql,
04630
X86_HAL_ROUTINE,
04631
04632 (PDRIVER_VERIFIER_THUNK_ROUTINE)
KeAcquireSpinLock,
04633 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKeAcquireSpinLock,
04634
X86_HAL_ROUTINE,
04635
04636 (PDRIVER_VERIFIER_THUNK_ROUTINE)
KeReleaseSpinLock,
04637 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKeReleaseSpinLock,
04638
X86_HAL_ROUTINE,
04639
04640 (PDRIVER_VERIFIER_THUNK_ROUTINE)
KeSynchronizeExecution,
04641 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierSynchronizeExecution,
04642 0,
04643
04644 (PDRIVER_VERIFIER_THUNK_ROUTINE)
KeInitializeTimerEx,
04645 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKeInitializeTimerEx,
04646 0,
04647
04648 (PDRIVER_VERIFIER_THUNK_ROUTINE)
KeInitializeTimer,
04649 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKeInitializeTimer,
04650 0,
04651
04652
#if defined(_X86_)
04653
04654 (PDRIVER_VERIFIER_THUNK_ROUTINE)KfRaiseIrql,
04655 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKfRaiseIrql,
04656
X86_HAL_ROUTINE,
04657
04658 (PDRIVER_VERIFIER_THUNK_ROUTINE)KfLowerIrql,
04659 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKfLowerIrql,
04660
X86_HAL_ROUTINE,
04661
04662 (PDRIVER_VERIFIER_THUNK_ROUTINE)KfAcquireSpinLock,
04663 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKfAcquireSpinLock,
04664
X86_HAL_ROUTINE,
04665
04666 (PDRIVER_VERIFIER_THUNK_ROUTINE)KfReleaseSpinLock,
04667 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKfReleaseSpinLock,
04668
X86_HAL_ROUTINE,
04669
04670
#endif
04671
04672
#if defined(_ALPHA_)
04673
04674 (PDRIVER_VERIFIER_THUNK_ROUTINE)
KeAcquireSpinLockAtDpcLevel,
04675 (PDRIVER_VERIFIER_THUNK_ROUTINE)VerifierKeAcquireSpinLockAtDpcLevel,
04676 0,
04677
04678 (PDRIVER_VERIFIER_THUNK_ROUTINE)
KeReleaseSpinLockFromDpcLevel,
04679 (PDRIVER_VERIFIER_THUNK_ROUTINE)VerifierKeReleaseSpinLockFromDpcLevel,
04680 0,
04681
04682 (PDRIVER_VERIFIER_THUNK_ROUTINE)
KeAcquireSpinLockRaiseToDpc,
04683 (PDRIVER_VERIFIER_THUNK_ROUTINE)VerifierKeAcquireSpinLockRaiseToDpc,
04684 0,
04685
04686
#endif
04687
04688 (PDRIVER_VERIFIER_THUNK_ROUTINE)
IoFreeIrp,
04689 (PDRIVER_VERIFIER_THUNK_ROUTINE)
IovFreeIrp,
04690 0,
04691
04692 (PDRIVER_VERIFIER_THUNK_ROUTINE)
IofCallDriver,
04693 (PDRIVER_VERIFIER_THUNK_ROUTINE)
IovCallDriver,
04694 0,
04695 (PDRIVER_VERIFIER_THUNK_ROUTINE)
IofCompleteRequest,
04696 (PDRIVER_VERIFIER_THUNK_ROUTINE)
IovCompleteRequest,
04697 0,
04698 (PDRIVER_VERIFIER_THUNK_ROUTINE)
IoBuildDeviceIoControlRequest,
04699 (PDRIVER_VERIFIER_THUNK_ROUTINE)
IovBuildDeviceIoControlRequest,
04700 0,
04701
04702 (PDRIVER_VERIFIER_THUNK_ROUTINE)
IoBuildAsynchronousFsdRequest,
04703 (PDRIVER_VERIFIER_THUNK_ROUTINE)
IovBuildAsynchronousFsdRequest,
04704 0,
04705
04706 (PDRIVER_VERIFIER_THUNK_ROUTINE)
IoInitializeTimer,
04707 (PDRIVER_VERIFIER_THUNK_ROUTINE)
IovInitializeTimer,
04708 0
04709 };
04710
04711 LOGICAL
04712 MiEnableVerifier (
04713 IN PLDR_DATA_TABLE_ENTRY DataTableEntry
04714 )
04715
04716
04717
04718
04719
04720
04721
04722
04723
04724
04725
04726
04727
04728
04729
04730
04731
04732
04733
04734
04735
04736
04737
04738 {
04739 ULONG i;
04740 ULONG j;
04741 PULONG_PTR ImportThunk;
04742 ULONG ImportSize;
04743
PVERIFIER_THUNKS VerifierThunk;
04744 ULONG ThunkCount;
04745 LOGICAL Found;
04746 ULONG_PTR RealRoutine;
04747 PULONG_PTR PointerRealRoutine;
04748 PLIST_ENTRY NextEntry;
04749 PDRIVER_VERIFIER_THUNK_PAIRS ThunkTable;
04750
PDRIVER_SPECIFIED_VERIFIER_THUNKS ThunkTableBase;
04751
04752 ImportThunk = (PULONG_PTR)
RtlImageDirectoryEntryToData(
04753 DataTableEntry->DllBase,
04754
TRUE,
04755 IMAGE_DIRECTORY_ENTRY_IAT,
04756 &ImportSize);
04757
04758
if (ImportThunk ==
NULL) {
04759
return FALSE;
04760 }
04761
04762 ImportSize /=
sizeof(PULONG_PTR);
04763
04764
for (i = 0; i < ImportSize; i += 1, ImportThunk += 1) {
04765
04766 Found =
FALSE;
04767
04768 VerifierThunk =
MiVerifierThunks;
04769
04770
for (ThunkCount = 0; ThunkCount <
sizeof (
MiVerifierThunks) /
sizeof (
VERIFIER_THUNKS); ThunkCount += 1) {
04771
04772
if (
KernelVerifier ==
TRUE) {
04773
if (
VERIFIER_POOL_ROUTINE (VerifierThunk->
Flag) == 0) {
04774 VerifierThunk += 1;
04775
continue;
04776 }
04777 }
04778
04779
if (
VERIFIER_THUNK_IN_HAL (VerifierThunk->
Flag) == 0) {
04780 RealRoutine = (ULONG_PTR)VerifierThunk->
PristineRoutine;
04781 }
04782
else {
04783
04784
04785
04786
04787
04788
04789
04790 PointerRealRoutine = (PULONG_PTR)*((PULONG_PTR)((PCHAR)VerifierThunk->
PristineRoutine + 2));
04791 RealRoutine = *PointerRealRoutine;
04792 }
04793
04794
if (*ImportThunk == RealRoutine) {
04795 *ImportThunk = (ULONG_PTR)(VerifierThunk->
NewRoutine);
04796 Found =
TRUE;
04797
break;
04798 }
04799 VerifierThunk += 1;
04800 }
04801
04802
if (Found ==
FALSE) {
04803
04804 NextEntry =
MiVerifierDriverAddedThunkListHead.Flink;
04805
while (NextEntry != &
MiVerifierDriverAddedThunkListHead) {
04806
04807 ThunkTableBase = CONTAINING_RECORD(NextEntry,
04808
DRIVER_SPECIFIED_VERIFIER_THUNKS,
04809 ListEntry);
04810
04811 ThunkTable = (PDRIVER_VERIFIER_THUNK_PAIRS)(ThunkTableBase + 1);
04812
04813
for (j = 0; j < ThunkTableBase->
NumberOfThunks; j += 1) {
04814
04815
if (*ImportThunk == (ULONG_PTR)ThunkTable->PristineRoutine) {
04816 *ImportThunk = (ULONG_PTR)(ThunkTable->NewRoutine);
04817 Found =
TRUE;
04818
break;
04819 }
04820 ThunkTable += 1;
04821 }
04822
04823
if (Found ==
TRUE) {
04824
break;
04825 }
04826
04827 NextEntry = NextEntry->Flink;
04828 }
04829 }
04830 }
04831
return TRUE;
04832 }
04833
04834
#if defined(_X86_)
04835
04836 DRIVER_VERIFIER_THUNK_PAIRS MiKernelVerifierThunks[] = {
04837
04838 (PDRIVER_VERIFIER_THUNK_ROUTINE)
KeRaiseIrql,
04839 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKeRaiseIrql,
04840
04841 (PDRIVER_VERIFIER_THUNK_ROUTINE)
KeLowerIrql,
04842 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKeLowerIrql,
04843
04844 (PDRIVER_VERIFIER_THUNK_ROUTINE)
KeAcquireSpinLock,
04845 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKeAcquireSpinLock,
04846
04847 (PDRIVER_VERIFIER_THUNK_ROUTINE)
KeReleaseSpinLock,
04848 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKeReleaseSpinLock,
04849
04850 (PDRIVER_VERIFIER_THUNK_ROUTINE)KfRaiseIrql,
04851 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKfRaiseIrql,
04852
04853 (PDRIVER_VERIFIER_THUNK_ROUTINE)KfLowerIrql,
04854 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKfLowerIrql,
04855
04856 (PDRIVER_VERIFIER_THUNK_ROUTINE)KfAcquireSpinLock,
04857 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKfAcquireSpinLock,
04858
04859 (PDRIVER_VERIFIER_THUNK_ROUTINE)KfReleaseSpinLock,
04860 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKfReleaseSpinLock,
04861
04862
#if !defined(NT_UP)
04863
(PDRIVER_VERIFIER_THUNK_ROUTINE)KeAcquireQueuedSpinLock,
04864 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKeAcquireQueuedSpinLock,
04865
04866 (PDRIVER_VERIFIER_THUNK_ROUTINE)KeReleaseQueuedSpinLock,
04867 (PDRIVER_VERIFIER_THUNK_ROUTINE)
VerifierKeReleaseQueuedSpinLock,
04868
#endif
04869
};
04870
04871
VOID
04872
MiEnableKernelVerifier (
04873 VOID
04874 )
04875
04876
04877
04878
04879
04880
04881
04882
04883
04884
04885
04886
04887
04888
04889
04890
04891
04892
04893
04894
04895
04896
04897 {
04898 ULONG i;
04899 PULONG_PTR ImportThunk;
04900 ULONG ImportSize;
04901 PDRIVER_VERIFIER_THUNK_PAIRS VerifierThunk;
04902 ULONG ThunkCount;
04903 ULONG_PTR RealRoutine;
04904 PULONG_PTR PointerRealRoutine;
04905
04906
if (
KernelVerifier ==
FALSE) {
04907
return;
04908 }
04909
04910 ImportThunk = (PULONG_PTR)
RtlImageDirectoryEntryToData(
04911 PsNtosImageBase,
04912 TRUE,
04913 IMAGE_DIRECTORY_ENTRY_IAT,
04914 &ImportSize);
04915
04916
if (ImportThunk ==
NULL) {
04917
return;
04918 }
04919
04920 ImportSize /=
sizeof(PULONG_PTR);
04921
04922
for (i = 0; i < ImportSize; i += 1, ImportThunk += 1) {
04923
04924 VerifierThunk = MiKernelVerifierThunks;
04925
04926
for (ThunkCount = 0; ThunkCount <
sizeof (MiKernelVerifierThunks) /
sizeof (DRIVER_VERIFIER_THUNK_PAIRS); ThunkCount += 1) {
04927
04928
04929
04930
04931
04932
04933
04934 PointerRealRoutine = (PULONG_PTR)*((PULONG_PTR)((PCHAR)VerifierThunk->PristineRoutine + 2));
04935 RealRoutine = *PointerRealRoutine;
04936
04937
if (*ImportThunk == RealRoutine) {
04938
04939
04940
04941
04942
04943
if (MiKernelVerifierOriginalCalls[ThunkCount] ==
NULL) {
04944 MiKernelVerifierOriginalCalls[ThunkCount] = (PVOID)RealRoutine;
04945 }
04946
04947 *ImportThunk = (ULONG_PTR)(VerifierThunk->NewRoutine);
04948
04949
break;
04950 }
04951 VerifierThunk += 1;
04952 }
04953 }
04954
return;
04955 }
04956
#endif
04957
04958
04959
04960
04961
04962
04963
04964
04965
04966