ReactOS 0.4.17-dev-1281-g065abb3
kse.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Kernel Shim Engine implementation
5 * COPYRIGHT: Copyright 2020 Hervé Poussineau <hpoussin@reactos.org>
6 * Copyright 2020-2026 Mark Jansen <mark.jansen@reactos.org>
7 */
8
9#include <ntoskrnl.h>
10
11#define NDEBUG
12#include <debug.h>
13
14// http://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/kshim/ksecore/index.htm
15
16#define KSE_MAX_SHIMS_PER_DRIVER 10
17
18
19typedef struct _KSE_PROVIDER
20{
24
25
27{
32
33
35{
40
42{
44 KSE_FLAGS_GROUPPOLICY_OK = (1 << 1), // 0x0002
45 KSE_FLAGS_DRV_SHIMS_ACTIVE = (1 << 11), // 0x0800
46 KSE_FLAGS_DEV_SHIMS_ACTIVE = (1 << 12), // 0x1000
48
52
53typedef struct _KSE_ENGINE
54{
58 LIST_ENTRY ProvidersListHead; // list of KSE_PROVIDER
65
67
68
72{
74 if (Ptr)
75 return Ptr;
76
77 DPRINT1("KSE: Unable to allocated %u bytes\n", NumberOfBytes);
78 return NULL;
79}
80
84{
85 PKSE_PROVIDER ProviderEntry;
86 PLIST_ENTRY ListEntry;
87 UNICODE_STRING ShimName;
88
89 for (ListEntry = KseEngine.ProvidersListHead.Flink;
90 ListEntry != &KseEngine.ProvidersListHead;
91 ListEntry = ListEntry->Flink)
92 {
93 ProviderEntry = CONTAINING_RECORD(ListEntry, KSE_PROVIDER, ProviderList);
94 if (!ProviderEntry->Shim->ShimName)
95 continue;
96
97 RtlInitUnicodeString(&ShimName, ProviderEntry->Shim->ShimName);
98 if (RtlEqualUnicodeString(&ShimName, Name, TRUE))
99 return ProviderEntry->Shim;
100 }
101
102 return NULL;
103}
104
105/* Add the named shim to the shims of a driver, unless it is already there */
109 _Inout_ PKSE_SHIM* Shims,
110 _Inout_ PULONG NumberOfShims)
111{
113 ULONG n;
114
116 if (!Shim)
117 {
118 DPRINT1("KSE: Shim %wZ not found\n", Name);
119 return;
120 }
121
122 for (n = 0; n < *NumberOfShims; n++)
123 {
124 if (Shims[n] == Shim)
125 return;
126 }
127
128 if (*NumberOfShims >= KSE_MAX_SHIMS_PER_DRIVER)
129 {
130 DPRINT1("KSE: Too many shims, ignoring %wZ\n", Name);
131 return;
132 }
133
134 Shims[(*NumberOfShims)++] = Shim;
135}
136
137static VOID NTAPI
139 _In_ PKEY_VALUE_FULL_INFORMATION KeyValueInformation,
140 _Inout_ PKSE_SHIM* Shims,
141 _Inout_ PULONG NumberOfShims)
142{
144 UNICODE_STRING ShimName;
146
147 Current = (PWCHAR)((ULONG_PTR)KeyValueInformation + KeyValueInformation->DataOffset);
148 End = (PWCHAR)((ULONG_PTR)Current + KeyValueInformation->DataLength);
149
150 while (Current < End && *Current)
151 {
152 /* Find the end of this string, without running past the data */
153 for (Length = 0; Current + Length < End && Current[Length]; Length++)
154 ;
155
156 ShimName.Buffer = Current;
157 ShimName.Length = ShimName.MaximumLength = (USHORT)(Length * sizeof(WCHAR));
158 KsepAddShimByName(&ShimName, Shims, NumberOfShims);
159
160 Current += Length + 1;
161 }
162}
163
164static NTSTATUS NTAPI
167 _Inout_ PKSE_SHIM* Shims,
168 _Inout_ PULONG NumberOfShims)
169{
170 static const UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"Shims");
171 WCHAR KeyNameBuffer[256];
174 PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
175 ULONG KeyValueSize = 0x800;
178
179 RtlInitEmptyUnicodeString(&KeyName, KeyNameBuffer, sizeof(KeyNameBuffer));
180 Status = RtlAppendUnicodeToString(&KeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Compatibility\\Driver\\");
181 if (NT_SUCCESS(Status))
182 Status = RtlAppendUnicodeStringToString(&KeyName, &LdrEntry->BaseDllName);
183 if (!NT_SUCCESS(Status))
184 return Status;
185
187 &KeyName,
189 NULL,
190 NULL);
192 if (!NT_SUCCESS(Status))
193 return Status;
194
195 KeyValueInformation = ExAllocatePoolWithTag(PagedPool, KeyValueSize, TAG_KSE_REGISTRY);
196 if (!KeyValueInformation)
197 {
200 }
201
202 Status = ZwQueryValueKey(KeyHandle,
205 KeyValueInformation,
206 KeyValueSize,
207 &KeyValueSize);
209
210 if (NT_SUCCESS(Status))
211 {
212 if (KeyValueInformation->Type == REG_MULTI_SZ && KeyValueInformation->DataLength)
213 KsepMultiSzToShims(KeyValueInformation, Shims, NumberOfShims);
214 else
216 }
217
218 ExFreePoolWithTag(KeyValueInformation, TAG_KSE_REGISTRY);
219 return Status;
220}
221
222static NTSTATUS NTAPI
225 _Out_ PKSE_SHIM* Shims,
226 _Out_ PULONG NumberOfShims)
227{
228 *NumberOfShims = 0;
229
230 /* Shims from the driver database (drvmain.sdb), and from the registry */
231 KseDbGetShimsForDriver(LdrEntry, Shims, NumberOfShims);
232 KsepGetShimsFromRegistry(LdrEntry, Shims, NumberOfShims);
233
234 return *NumberOfShims ? STATUS_SUCCESS : STATUS_NOT_FOUND;
235}
236
237
238static NTSTATUS NTAPI
241 _Out_ PKSE_DRIVER_IO_CALLBACKS pIoCallbacks)
242{
244 ULONG NumberOfShims, n;
245 PKSE_HOOK_COLLECTION HookCollection;
246 PKSE_HOOK Hook;
248
249 RtlZeroMemory(pIoCallbacks, sizeof(*pIoCallbacks));
250
251 Status = KsepGetShimsForDriver(LdrEntry, Shims, &NumberOfShims);
252 if (!NT_SUCCESS(Status))
253 {
254 DPRINT("KSE: No Shim found for %wZ\n", &LdrEntry->BaseDllName);
255 return Status;
256 }
257
258 for (n = 0; n < NumberOfShims; n++)
259 {
260 for (HookCollection = Shims[n]->HookCollectionsArray;
261 HookCollection->Type != KseCollectionInvalid;
262 HookCollection++)
263 {
264 if (HookCollection->Type != KseCollectionCallback)
265 continue;
266
267 for (Hook = HookCollection->HookArray; Hook->Type != KseHookInvalid; Hook++)
268 {
269 if (Hook->Type != KseHookIRPCallback)
270 continue;
271
273 {
274 pIoCallbacks->DriverInit = Hook->HookFunction;
275 }
277 {
278 pIoCallbacks->DriverStartIo = Hook->HookFunction;
279 }
280 else if (Hook->CallbackId == KseHookCallbackDriverUnload)
281 {
282 pIoCallbacks->DriverUnload = Hook->HookFunction;
283 }
284 else if (Hook->CallbackId == KseHookCallbackAddDevice)
285 {
286 pIoCallbacks->AddDevice = Hook->HookFunction;
287 }
288 else if (Hook->CallbackId >= KseHookCallbackMajorFunction &&
290 {
291 pIoCallbacks->MajorFunction[Hook->CallbackId - KseHookCallbackMajorFunction] = Hook->HookFunction;
292 }
293 }
294 }
295 }
296 return STATUS_SUCCESS;
297}
298
300NTAPI
303{
304 KSE_DRIVER_IO_CALLBACKS IoCallbacks;
305 PKSE_DRIVER_IO_CALLBACKS KseCallbacks;
306 PLDR_DATA_TABLE_ENTRY LdrEntry;
307 BOOLEAN InKernel;
308 ULONG i;
310 DPRINT("KseShimDriverIoCallbacks(%wZ)\n", &DriverObject->DriverName);
311
313 return STATUS_SUCCESS;
314
315 if (!KiPcToFileHeader(DriverObject->DriverStart, &LdrEntry, FALSE, &InKernel))
316 return STATUS_NOT_FOUND;
317
318 Status = KsepGetShimCallbacksForDriver(LdrEntry, &IoCallbacks);
319 if (!NT_SUCCESS(Status))
320 return Status;
321
322 KseCallbacks = KsepPoolAllocateNonPaged(sizeof(*KseCallbacks));
323 if (!KseCallbacks)
324 return STATUS_NO_MEMORY;
325
326 RtlZeroMemory(KseCallbacks, sizeof(*KseCallbacks));
327 if (DriverObject->DriverInit && IoCallbacks.DriverInit)
328 {
329 KseCallbacks->DriverInit = DriverObject->DriverInit;
330 DriverObject->DriverInit = IoCallbacks.DriverInit;
331 }
332 if (DriverObject->DriverStartIo && IoCallbacks.DriverStartIo)
333 {
334 KseCallbacks->DriverStartIo = DriverObject->DriverStartIo;
335 DriverObject->DriverStartIo = IoCallbacks.DriverStartIo;
336 }
337 if (DriverObject->DriverUnload && IoCallbacks.DriverUnload)
338 {
339 KseCallbacks->DriverUnload = DriverObject->DriverUnload;
340 DriverObject->DriverUnload = IoCallbacks.DriverUnload;
341 }
342 if (DriverObject->DriverExtension->AddDevice && IoCallbacks.AddDevice)
343 {
344 KseCallbacks->AddDevice = DriverObject->DriverExtension->AddDevice;
345 DriverObject->DriverExtension->AddDevice = IoCallbacks.AddDevice;
346 }
347
348 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
349 {
350 if (DriverObject->MajorFunction[i] && IoCallbacks.MajorFunction[i])
351 {
352 KseCallbacks->MajorFunction[i] = DriverObject->MajorFunction[i];
353 DriverObject->MajorFunction[i] = IoCallbacks.MajorFunction[i];
354 }
355 }
356 IoGetDrvObjExtension(DriverObject)->KseCallbacks = KseCallbacks;
357
358 return STATUS_SUCCESS;
359}
360
361static CODE_SEG("INIT") NTSTATUS NTAPI
362KseShimDatabaseBootInitialize(
363 _In_ PLOADER_PARAMETER_EXTENSION LoaderExtension)
364{
366
367 /* Without a usable database, shims can still be applied through the registry */
368 Status = KseDbInitialize(LoaderExtension->DrvDBImage, LoaderExtension->DrvDBSize);
369 if (!NT_SUCCESS(Status))
370 DPRINT1("KSE: Unable to load the driver database (0x%08lx)\n", Status);
371
372 return STATUS_SUCCESS;
373}
374
375static CODE_SEG("INIT") NTSTATUS NTAPI
376KsepMatchInitMachineInfo(VOID)
377{
378 //UNIMPLEMENTED_ONCE;
379
380 return STATUS_SUCCESS;
381}
382
386{
387 return IoGetDrvObjExtension(DriverObject)->KseCallbacks;
388}
389
390static NTSTATUS NTAPI
393 _In_ PIRP Irp,
396{
398}
399
400CODE_SEG("INIT")
402NTAPI
404 _In_ ULONG BootPhase,
405 _In_ PLOADER_PARAMETER_BLOCK LoaderBlock)
406{
407 PLOADER_PARAMETER_EXTENSION LoaderExtension;
409 ULONG Flags;
410
411 if (BootPhase == 0)
412 {
413 if (InitSafeBootMode != 0 || /* Safe Boot enabled */
414 NT_SUCCESS(MmIsVerifierEnabled(&Flags))) /* Driver Verifier enabled */
415 {
416 DPRINT("KSE: Not initializing (verifier or safe boot)\n");
417 return STATUS_SUCCESS;
418 }
419
420 LoaderExtension = LoaderBlock->Extension;
421 if (!LoaderExtension || /* No loader extension */
422 LoaderExtension->Size < FIELD_OFFSET(LOADER_PARAMETER_EXTENSION, NetworkLoaderBlock) || /* Too small loader extension */
423 !LoaderExtension->DrvDBImage) /* No driver database */
424 {
425 DPRINT("KSE: Not initializing (invalid DB)\n");
426 return STATUS_SUCCESS;
427 }
428
429 /* Temp mark us as initialized, so providers can be registered */
435 Status = KseShimDatabaseBootInitialize(LoaderExtension);
436 if (NT_SUCCESS(Status))
437 {
438 Status = KsepMatchInitMachineInfo();
439 if (NT_SUCCESS(Status))
440 {
442 }
443 }
444 /* We are not done yet! */
446 }
447 else if (BootPhase == 1)
448 {
449 /* Phase 0 bailed out */
451 return STATUS_SUCCESS;
452
453 /* Done initializing, so register the remainder of the shims */
455 /* A shim that fails to register does not prevent the others from working */
459 }
460
461 DPRINT1("KseInitialize(BootPhase %ld) => %08lx\n", BootPhase, Status);
462 return Status;
463}
464
466NTAPI
469 _In_ PVOID Ignored,
471{
472 return KseRegisterShimEx(Shim, Ignored, Flags, NULL);
473}
474
476NTAPI
479 _In_ PVOID Ignored,
482{
483 PKSE_PROVIDER ProviderEntry;
484 PLIST_ENTRY ListEntry;
485 PLDR_DATA_TABLE_ENTRY DataTableEntry;
486 PKSE_HOOK_COLLECTION HookCollection;
487 PKSE_HOOK Hook;
488 BOOLEAN InKernel;
489
490 UNREFERENCED_PARAMETER(Ignored);
491
492 if (!Shim || !Shim->ShimGuid)
493 {
494 DPRINT1("KSE: Unable to register empty shim or shim without guid\n");
496 }
497
499 {
500 DPRINT1("KSE: Unable to register shim 0x%08x before engine is initialized\n", Shim->ShimGuid->Data1);
501 return STATUS_UNSUCCESSFUL;
502 }
503
504 /* Search the loaded module associated to caller */
505 if (!KiPcToFileHeader(_ReturnAddress(), &DataTableEntry, FALSE, &InKernel))
506 return STATUS_NOT_FOUND;
507
508 /* Check if all shim functions belong to caller */
509 for (HookCollection = Shim->HookCollectionsArray; HookCollection->Type != KseCollectionInvalid; HookCollection++)
510 {
511 for (Hook = HookCollection->HookArray; Hook->Type != KseHookInvalid; Hook++)
512 {
513 if (Hook->HookFunction < DataTableEntry->DllBase)
514 return STATUS_UNSUCCESSFUL;
515 if ((ULONG_PTR)Hook->HookFunction - (ULONG_PTR)DataTableEntry->DllBase >= DataTableEntry->SizeOfImage)
516 return STATUS_UNSUCCESSFUL;
517 }
518 }
519
520 /* Search if shim is already loaded */
521 for (ListEntry = KseEngine.ProvidersListHead.Flink;
522 ListEntry != &KseEngine.ProvidersListHead;
523 ListEntry = ListEntry->Flink)
524 {
525 ProviderEntry = CONTAINING_RECORD(ListEntry, KSE_PROVIDER, ProviderList);
526 if (IsEqualGUID(ProviderEntry->Shim->ShimGuid, Shim->ShimGuid))
527 {
528 DPRINT1("KSE: GUID already registered\n");
530 }
531 }
532
533 /* Allocate a new entry for this shim */
534 ProviderEntry = ExAllocatePoolWithTag(PagedPool, sizeof(*ProviderEntry), TAG_KSE_PROVIDER);
535 if (!ProviderEntry)
536 return STATUS_NO_MEMORY;
537
538 ProviderEntry->Shim = Shim;
540
541 /* Now, update the shim */
542 Shim->KseCallbackRoutines = &KseEngine.KseCallbackRoutines;
543
544 if (DriverObject)
546
547 DPRINT1("KSE: Registered shim %S\n", Shim->ShimName);
548
549 return STATUS_SUCCESS;
550}
551
553NTAPI
556 _In_ PVOID Unknown1,
557 _In_ PVOID Unknown2)
558{
561}
562
563
564static BOOLEAN
566 _In_ PCSTR ImportName,
568{
569 while (*ImportName && *ModuleName)
570 {
572 return FALSE;
573 ImportName++;
574 ModuleName++;
575 }
576 return (*ImportName == ANSI_NULL && *ModuleName == UNICODE_NULL);
577}
578
581 _In_ PKSE_HOOK_COLLECTION HookCollection,
583{
584 PLIST_ENTRY ListEntry;
585 PLDR_DATA_TABLE_ENTRY LdrEntry;
586 UNICODE_STRING ExportDriverName;
587
588 /* The kernel is always the first loaded module, the HAL the second one */
589 switch (HookCollection->Type)
590 {
592 *ModuleName = L"ntoskrnl.exe";
593 ListEntry = PsLoadedModuleList.Flink;
594 return CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
595
597 *ModuleName = L"hal.dll";
598 ListEntry = PsLoadedModuleList.Flink->Flink;
599 return CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
600
602 if (!HookCollection->ExportDriverName)
603 return NULL;
604
605 *ModuleName = HookCollection->ExportDriverName;
606 RtlInitUnicodeString(&ExportDriverName, HookCollection->ExportDriverName);
607 for (ListEntry = PsLoadedModuleList.Flink;
608 ListEntry != &PsLoadedModuleList;
609 ListEntry = ListEntry->Flink)
610 {
611 LdrEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
612 if (RtlEqualUnicodeString(&LdrEntry->BaseDllName, &ExportDriverName, TRUE))
613 return LdrEntry;
614 }
615 return NULL;
616
617 default:
618 return NULL;
619 }
620}
621
622/* Write an import address table entry. The table can already be write-protected
623 * (for example for boot drivers), so write through a temporary mapping. */
624static NTSTATUS
627 _In_ PVOID NewFunction)
628{
629 PMDL Mdl;
630 PIMAGE_THUNK_DATA MappedThunk;
632
633 Mdl = IoAllocateMdl(Thunk, sizeof(*Thunk), FALSE, FALSE, NULL);
634 if (!Mdl)
636
638 {
640 }
642 {
644 }
645 _SEH2_END;
646
647 if (!NT_SUCCESS(Status))
648 {
649 IoFreeMdl(Mdl);
650 return Status;
651 }
652
654 if (MappedThunk)
655 {
656 InterlockedExchangePointer((PVOID*)&MappedThunk->u1.Function, NewFunction);
657 MmUnmapLockedPages(MappedThunk, Mdl);
658 }
659 else
660 {
662 }
663
665 IoFreeMdl(Mdl);
666 return Status;
667}
668
669static VOID
672 _In_ PKSE_HOOK_COLLECTION HookCollection)
673{
674 PUCHAR DllBase = LdrEntry->DllBase;
675 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
676 PIMAGE_THUNK_DATA OriginalThunk, FirstThunk;
677 PIMAGE_IMPORT_BY_NAME ImportByName;
678 PLDR_DATA_TABLE_ENTRY ExportEntry;
680 PKSE_HOOK Hook;
681 BOOLEAN Match;
682 ULONG Size;
684
685 ExportEntry = KsepFindExportingModule(HookCollection, &ModuleName);
686 if (!ExportEntry)
687 {
688 DPRINT1("KSE: Exporting module for collection type %lu not found\n", HookCollection->Type);
689 return;
690 }
691
692 /* Resolve the original functions. They are the same for every shimmed driver. */
693 for (Hook = HookCollection->HookArray; Hook->Type != KseHookInvalid; Hook++)
694 {
695 if (Hook->Type != KseHookFunction || Hook->OriginalFunction)
696 continue;
697
699 if (!Hook->OriginalFunction)
700 DPRINT1("KSE: %s not exported by %S\n", Hook->FunctionName, ModuleName);
701 }
702
704 if (!ImportDescriptor)
705 return;
706
707 for (; ImportDescriptor->Name && ImportDescriptor->FirstThunk; ImportDescriptor++)
708 {
709 if (ImportDescriptor->Name >= LdrEntry->SizeOfImage ||
710 !KsepIsImportFromModule((PCSTR)(DllBase + ImportDescriptor->Name), ModuleName))
711 {
712 continue;
713 }
714
715 FirstThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->FirstThunk);
716 OriginalThunk = ImportDescriptor->OriginalFirstThunk ?
717 (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->OriginalFirstThunk) : NULL;
718
719 for (; FirstThunk->u1.Function; FirstThunk++, OriginalThunk = OriginalThunk ? OriginalThunk + 1 : NULL)
720 {
721 /* Without a name table, match on the address the import was bound to */
722 ImportByName = NULL;
723 if (OriginalThunk &&
724 !IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Ordinal) &&
725 OriginalThunk->u1.AddressOfData < LdrEntry->SizeOfImage)
726 {
727 ImportByName = (PIMAGE_IMPORT_BY_NAME)(DllBase + OriginalThunk->u1.AddressOfData);
728 }
729
730 for (Hook = HookCollection->HookArray; Hook->Type != KseHookInvalid; Hook++)
731 {
732 if (Hook->Type != KseHookFunction || !Hook->OriginalFunction)
733 continue;
734
735 if (ImportByName)
736 Match = !strcmp((PCSTR)ImportByName->Name, Hook->FunctionName);
737 else
738 Match = (FirstThunk->u1.Function == (ULONG_PTR)Hook->OriginalFunction);
739
740 if (!Match)
741 continue;
742
743 /* FIXME: When two shims hook the same function, the last one wins */
744 Status = KsepWriteImportEntry(FirstThunk, Hook->HookFunction);
745 if (NT_SUCCESS(Status))
746 DPRINT1("KSE: Hooked %S!%s in %wZ\n", ModuleName, Hook->FunctionName, &LdrEntry->BaseDllName);
747 else
748 DPRINT1("KSE: Unable to hook %S!%s in %wZ (0x%08lx)\n", ModuleName, Hook->FunctionName, &LdrEntry->BaseDllName, Status);
749 break;
750 }
751 }
752 }
753}
754
755static VOID
759{
760 PKSE_HOOK_COLLECTION HookCollection;
761
762 for (HookCollection = Shim->HookCollectionsArray;
763 HookCollection->Type != KseCollectionInvalid;
764 HookCollection++)
765 {
766 /* Callbacks are applied when the driver object is initialized */
767 if (HookCollection->Type == KseCollectionCallback)
768 continue;
769
770 KsepHookImports(LdrEntry, HookCollection);
771 }
772}
773
775NTAPI
778{
780 ULONG NumberOfShims, n;
782
784 return STATUS_SUCCESS;
785
786 Status = KsepGetShimsForDriver(LdrEntry, Shims, &NumberOfShims);
787 if (!NT_SUCCESS(Status))
788 {
789 DPRINT("KSE: No Shim found for %wZ\n", &LdrEntry->BaseDllName);
790 return STATUS_SUCCESS;
791 }
792
793 for (n = 0; n < NumberOfShims; n++)
794 {
795 DPRINT1("KSE: Applying shim %S (0x%08lx) to %wZ\n",
796 Shims[n]->ShimName, Shims[n]->ShimGuid->Data1, &LdrEntry->BaseDllName);
797
798 KsepApplyShimToDriver(Shims[n], LdrEntry);
799
800 if (Shims[n]->ShimmedDriverTargetedNotification)
801 {
802 PIMAGE_NT_HEADERS NtHeaders = RtlImageNtHeader(LdrEntry->DllBase);
803
804 Shims[n]->ShimmedDriverTargetedNotification(&LdrEntry->BaseDllName,
805 LdrEntry->DllBase,
806 LdrEntry->SizeOfImage,
807 NtHeaders ? NtHeaders->FileHeader.TimeDateStamp : 0,
808 LdrEntry->CheckSum);
809 }
810 }
811
812 return STATUS_SUCCESS;
813}
#define CODE_SEG(...)
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1280
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
RtlInitEmptyUnicodeString(SymbolicLinkName, NULL, 0)
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: d3dkmdt.h:46
PUCHAR End
Definition: desccheck.cpp:2229
LPWSTR Name
Definition: desk.c:124
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG Flags
Definition: dispmprt.h:245
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define RtlImageNtHeader
Definition: compat.h:806
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3324
#define L(x)
Definition: resources.c:13
PULONG InitSafeBootMode
Definition: init.c:75
#define ULONG_PTR
Definition: config.h:101
NTSTATUS NTAPI MmIsVerifierEnabled(OUT PULONG VerifierFlags)
Definition: drvmgmt.c:233
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define InsertTailList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PagedPool
Definition: env_spec_w32.h:308
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
Status
Definition: gdiplustypes.h:24
GLdouble n
Definition: glext.h:7729
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
return ZwOpenKey(Handle, KEY_READ, &Attributes)
HubUxdSettings Current
ZwClose(Handle)
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define _ReturnAddress()
Definition: intrin_arm.h:35
#define C_ASSERT(e)
Definition: intsafe.h:73
NTSTATUS NTAPI IoSetCompletionRoutineEx(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_COMPLETION_ROUTINE CompletionRoutine, IN PVOID Context, IN BOOLEAN InvokeOnSuccess, IN BOOLEAN InvokeOnError, IN BOOLEAN InvokeOnCancel)
Definition: iocomp.c:220
NTSTATUS NTAPI KseInitialize(_In_ ULONG BootPhase, _In_ PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: kse.c:403
static VOID KsepHookImports(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry, _In_ PKSE_HOOK_COLLECTION HookCollection)
Definition: kse.c:670
static PKSE_DRIVER_IO_CALLBACKS NTAPI KseGetIoCallbacks(_In_ PDRIVER_OBJECT DriverObject)
Definition: kse.c:384
static NTSTATUS NTAPI KsepGetShimCallbacksForDriver(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry, _Out_ PKSE_DRIVER_IO_CALLBACKS pIoCallbacks)
Definition: kse.c:239
struct _KSE_PROVIDER KSE_PROVIDER
PKSE_SHIM NTAPI KsepFindShim(_In_ PCUNICODE_STRING Name)
Definition: kse.c:82
static KSE_ENGINE KseEngine
Definition: kse.c:66
static VOID NTAPI KsepMultiSzToShims(_In_ PKEY_VALUE_FULL_INFORMATION KeyValueInformation, _Inout_ PKSE_SHIM *Shims, _Inout_ PULONG NumberOfShims)
Definition: kse.c:138
struct _KSE_ENGINE * PKSE_ENGINE
VOID NTAPI KsepAddShimByName(_In_ PCUNICODE_STRING Name, _Inout_ PKSE_SHIM *Shims, _Inout_ PULONG NumberOfShims)
Definition: kse.c:107
static PLDR_DATA_TABLE_ENTRY KsepFindExportingModule(_In_ PKSE_HOOK_COLLECTION HookCollection, _Out_ PCWSTR *ModuleName)
Definition: kse.c:580
NTSTATUS NTAPI KseDriverLoadImage(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: kse.c:776
static NTSTATUS NTAPI KsepGetShimsForDriver(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry, _Out_ PKSE_SHIM *Shims, _Out_ PULONG NumberOfShims)
Definition: kse.c:223
static NTSTATUS NTAPI KsepGetShimsFromRegistry(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry, _Inout_ PKSE_SHIM *Shims, _Inout_ PULONG NumberOfShims)
Definition: kse.c:165
_KSE_DISABLE_FLAGS
Definition: kse.c:27
@ KSE_DISABLE_NONE
Definition: kse.c:28
@ KSE_DISABLE_DEVICE_SHIMS
Definition: kse.c:30
@ KSE_DISABLE_DRIVER_SHIMS
Definition: kse.c:29
static VOID KsepApplyShimToDriver(_In_ PKSE_SHIM Shim, _In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: kse.c:756
struct _KSE_ENGINE KSE_ENGINE
static BOOLEAN KsepIsImportFromModule(_In_ PCSTR ImportName, _In_ PCWSTR ModuleName)
Definition: kse.c:565
_KSE_ENGINE_STATE
Definition: kse.c:35
@ KSE_STATE_INITIALIZED
Definition: kse.c:38
@ KSE_STATE_UNINITIALIZED
Definition: kse.c:36
@ KSE_STATE_INITIALIZING
Definition: kse.c:37
static NTSTATUS NTAPI KseSetCompletionHook(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ PIO_COMPLETION_ROUTINE CompletionRoutine, _In_ PVOID Context)
Definition: kse.c:391
NTSTATUS NTAPI KseRegisterShimEx(_In_ PKSE_SHIM Shim, _In_ PVOID Ignored, _In_ ULONG Flags, _In_opt_ PVOID DriverObject)
Definition: kse.c:477
enum _KSE_DISABLE_FLAGS KSE_DISABLE_FLAGS
struct _KSE_PROVIDER * PKSE_PROVIDER
NTSTATUS NTAPI KseShimDriverIoCallbacks(_In_ PDRIVER_OBJECT DriverObject)
Definition: kse.c:301
#define KSE_MAX_SHIMS_PER_DRIVER
Definition: kse.c:16
static NTSTATUS KsepWriteImportEntry(_In_ PIMAGE_THUNK_DATA Thunk, _In_ PVOID NewFunction)
Definition: kse.c:625
enum _KSE_ENGINE_STATE KSE_ENGINE_STATE
NTSTATUS NTAPI KseUnregisterShim(_In_ PKSE_SHIM Shim, _In_ PVOID Unknown1, _In_ PVOID Unknown2)
Definition: kse.c:554
_KSE_ENGINE_FLAGS
Definition: kse.c:42
@ KSE_FLAGS_GROUPPOLICY_OK
Definition: kse.c:44
@ KSE_FLAGS_DEV_SHIMS_ACTIVE
Definition: kse.c:46
@ KSE_FLAGS_DRV_SHIMS_ACTIVE
Definition: kse.c:45
@ KSE_FLAGS_NONE
Definition: kse.c:43
enum _KSE_ENGINE_FLAGS KSE_ENGINE_FLAGS
NTSTATUS NTAPI KseRegisterShim(_In_ PKSE_SHIM Shim, _In_ PVOID Ignored, _In_ ULONG Flags)
Definition: kse.c:467
PVOID NTAPI KsepPoolAllocateNonPaged(_In_ SIZE_T NumberOfBytes)
Definition: kse.c:70
#define KseCollectionDriverExport
Definition: kse.h:36
NTSTATUS NTAPI KseVersionLieInitialize(VOID)
Definition: versionlie.c:120
NTSTATUS NTAPI KseIgnoreFreePoolTagInitialize(VOID)
Definition: ignorepooltag.c:59
_In_ PIRP Irp
Definition: kse.h:79
#define KseHookCallbackDriverInit
Definition: kse.h:15
#define KseCollectionHalExport
Definition: kse.h:35
VOID NTAPI KseDbGetShimsForDriver(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry, _Inout_ PKSE_SHIM *Shims, _Inout_ PULONG NumberOfShims)
Definition: ksedb.c:199
#define KseHookCallbackAddDevice
Definition: kse.h:18
NTSTATUS NTAPI KseDbInitialize(_In_ PVOID DatabaseImage, _In_ ULONG DatabaseSize)
Definition: ksedb.c:92
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
#define KseHookCallbackDriverUnload
Definition: kse.h:17
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE CompletionRoutine
Definition: kse.h:80
#define KseCollectionInvalid
Definition: kse.h:38
#define KseHookCallbackDriverStartIo
Definition: kse.h:16
#define KseCollectionCallback
Definition: kse.h:37
#define KseHookCallbackMajorFunction
Definition: kse.h:19
NTSTATUS NTAPI KseDriverScopeInitialize(VOID)
Definition: driverscope.c:353
#define KseHookInvalid
Definition: kse.h:13
#define KseCollectionNtExport
Definition: kse.h:34
#define KseHookFunction
Definition: kse.h:11
#define KseHookIRPCallback
Definition: kse.h:12
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:928
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1432
PVOID NTAPI MmMapLockedPagesSpecifyCache(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN MEMORY_CACHING_TYPE CacheType, IN PVOID BaseAddress, IN ULONG BugCheckOnFailure, IN ULONG Priority)
Definition: mdlsup.c:659
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:834
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
@ NormalPagePriority
Definition: imports.h:54
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
#define KernelMode
Definition: asm.h:38
WCHAR NTAPI RtlUpcaseUnicodeChar(_In_ WCHAR Source)
Definition: nlsboot.c:177
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
@ KeyValueFullInformation
Definition: nt_native.h:1184
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define KEY_READ
Definition: nt_native.h:1026
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define REG_MULTI_SZ
Definition: nt_native.h:1504
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define ANSI_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define IMAGE_SNAP_BY_ORDINAL(Ordinal)
Definition: ntimage.h:567
PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA
Definition: ntimage.h:566
#define IoGetDrvObjExtension(DriverObject)
Definition: io.h:135
PVOID NTAPI KiPcToFileHeader(IN PVOID Pc, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry, IN BOOLEAN DriversOnly, OUT PBOOLEAN InKernel)
Definition: bug.c:44
PVOID NTAPI RtlFindExportedRoutineByName(_In_ PVOID ImageBase, _In_ PCSTR ExportName)
Finds the address of a given named exported routine in a loaded image. Note that this function does n...
Definition: sysldr.c:432
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
short WCHAR
Definition: pedump.c:58
struct _IMAGE_IMPORT_BY_NAME * PIMAGE_IMPORT_BY_NAME
unsigned short USHORT
Definition: pedump.c:61
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define DPRINT
Definition: sndvol32.h:73
Definition: xml2sdb.h:89
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
union _IMAGE_THUNK_DATA32::@2594 u1
PKSE_GET_IO_CALLBACKS KseGetIoCallbacksRoutine
Definition: kse.h:87
PKSE_SET_COMPLETION_HOOK KseSetCompletionHookRoutine
Definition: kse.h:88
PDRIVER_UNLOAD DriverUnload
Definition: kse.h:65
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: kse.h:67
PDRIVER_ADD_DEVICE AddDevice
Definition: kse.h:66
PDRIVER_STARTIO DriverStartIo
Definition: kse.h:64
PDRIVER_INITIALIZE DriverInit
Definition: kse.h:63
KSE_DISABLE_FLAGS DisableFlags
Definition: kse.c:55
PVOID DeviceInfoCache
Definition: kse.c:61
KSE_CALLBACK_ROUTINES KseCallbackRoutines
Definition: kse.c:60
PVOID ShimmedDriverHint
Definition: kse.c:63
KSE_ENGINE_FLAGS Flags
Definition: kse.c:57
LIST_ENTRY ShimmedDriversListHead
Definition: kse.c:59
PVOID HardwareIdCache
Definition: kse.c:62
KSE_ENGINE_STATE State
Definition: kse.c:56
LIST_ENTRY ProvidersListHead
Definition: kse.c:58
PKSE_HOOK HookArray
Definition: kse.h:44
Definition: kse.h:22
PCHAR FunctionName
Definition: kse.h:26
ULONG CallbackId
Definition: kse.h:27
PVOID OriginalFunction
Definition: kse.h:30
ULONG Type
Definition: kse.h:23
PVOID HookFunction
Definition: kse.h:29
PKSE_SHIM Shim
Definition: kse.c:22
LIST_ENTRY ProviderList
Definition: kse.c:21
Definition: kse.h:92
const GUID * ShimGuid
Definition: kse.h:94
PWCHAR ShimName
Definition: kse.h:95
PKSE_HOOK_DRIVER_TARGETED ShimmedDriverTargetedNotification
Definition: kse.h:97
Definition: btrfs_drv.h:1876
ULONG SizeOfImage
Definition: ldrtypes.h:147
PVOID DllBase
Definition: btrfs_drv.h:1880
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:149
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TAG_KSE_PROVIDER
Definition: tag.h:131
#define TAG_KSE_REGISTRY
Definition: tag.h:132
#define TAG_KSE_CALLBACKS
Definition: tag.h:129
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char UCHAR
Definition: typedefs.h:53
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
const char * PCSTR
Definition: typedefs.h:52
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2705
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
IO_COMPLETION_ROUTINE * PIO_COMPLETION_ROUTINE
Definition: iotypes.h:2850
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1036
#define IRP_MJ_MAXIMUM_FUNCTION
@ IoReadAccess
Definition: ketypes.h:931
@ MmCached
Definition: mmtypes.h:130
#define ObReferenceObject
Definition: obfuncs.h:204