ReactOS 0.4.17-dev-1164-g974a446
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{
143 PWCHAR Current, End;
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);
191 Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
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 */
456 }
457
458 DPRINT1("KseInitialize(BootPhase %ld) => %08lx\n", BootPhase, Status);
459 return Status;
460}
461
463NTAPI
466 _In_ PVOID Ignored,
468{
469 return KseRegisterShimEx(Shim, Ignored, Flags, NULL);
470}
471
473NTAPI
476 _In_ PVOID Ignored,
479{
480 PKSE_PROVIDER ProviderEntry;
481 PLIST_ENTRY ListEntry;
482 PLDR_DATA_TABLE_ENTRY DataTableEntry;
483 PKSE_HOOK_COLLECTION HookCollection;
484 PKSE_HOOK Hook;
485 BOOLEAN InKernel;
486
487 UNREFERENCED_PARAMETER(Ignored);
488
489 if (!Shim || !Shim->ShimGuid)
490 {
491 DPRINT1("KSE: Unable to register empty shim or shim without guid\n");
493 }
494
496 {
497 DPRINT1("KSE: Unable to register shim 0x%08x before engine is initialized\n", Shim->ShimGuid->Data1);
498 return STATUS_UNSUCCESSFUL;
499 }
500
501 /* Search the loaded module associated to caller */
502 if (!KiPcToFileHeader(_ReturnAddress(), &DataTableEntry, FALSE, &InKernel))
503 return STATUS_NOT_FOUND;
504
505 /* Check if all shim functions belong to caller */
506 for (HookCollection = Shim->HookCollectionsArray; HookCollection->Type != KseCollectionInvalid; HookCollection++)
507 {
508 for (Hook = HookCollection->HookArray; Hook->Type != KseHookInvalid; Hook++)
509 {
510 if (Hook->HookFunction < DataTableEntry->DllBase)
511 return STATUS_UNSUCCESSFUL;
512 if ((ULONG_PTR)Hook->HookFunction - (ULONG_PTR)DataTableEntry->DllBase >= DataTableEntry->SizeOfImage)
513 return STATUS_UNSUCCESSFUL;
514 }
515 }
516
517 /* Search if shim is already loaded */
518 for (ListEntry = KseEngine.ProvidersListHead.Flink;
519 ListEntry != &KseEngine.ProvidersListHead;
520 ListEntry = ListEntry->Flink)
521 {
522 ProviderEntry = CONTAINING_RECORD(ListEntry, KSE_PROVIDER, ProviderList);
523 if (IsEqualGUID(ProviderEntry->Shim->ShimGuid, Shim->ShimGuid))
524 {
525 DPRINT1("KSE: GUID already registered\n");
527 }
528 }
529
530 /* Allocate a new entry for this shim */
531 ProviderEntry = ExAllocatePoolWithTag(PagedPool, sizeof(*ProviderEntry), TAG_KSE_PROVIDER);
532 if (!ProviderEntry)
533 return STATUS_NO_MEMORY;
534
535 ProviderEntry->Shim = Shim;
537
538 /* Now, update the shim */
539 Shim->KseCallbackRoutines = &KseEngine.KseCallbackRoutines;
540
541 if (DriverObject)
543
544 DPRINT1("KSE: Registered shim %S\n", Shim->ShimName);
545
546 return STATUS_SUCCESS;
547}
548
550NTAPI
553 _In_ PVOID Unknown1,
554 _In_ PVOID Unknown2)
555{
558}
559
560
561static BOOLEAN
563 _In_ PCSTR ImportName,
565{
566 while (*ImportName && *ModuleName)
567 {
569 return FALSE;
570 ImportName++;
571 ModuleName++;
572 }
573 return (*ImportName == ANSI_NULL && *ModuleName == UNICODE_NULL);
574}
575
578 _In_ PKSE_HOOK_COLLECTION HookCollection,
580{
581 PLIST_ENTRY ListEntry;
582 PLDR_DATA_TABLE_ENTRY LdrEntry;
583 UNICODE_STRING ExportDriverName;
584
585 /* The kernel is always the first loaded module, the HAL the second one */
586 switch (HookCollection->Type)
587 {
589 *ModuleName = L"ntoskrnl.exe";
590 ListEntry = PsLoadedModuleList.Flink;
591 return CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
592
594 *ModuleName = L"hal.dll";
595 ListEntry = PsLoadedModuleList.Flink->Flink;
596 return CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
597
599 if (!HookCollection->ExportDriverName)
600 return NULL;
601
602 *ModuleName = HookCollection->ExportDriverName;
603 RtlInitUnicodeString(&ExportDriverName, HookCollection->ExportDriverName);
604 for (ListEntry = PsLoadedModuleList.Flink;
605 ListEntry != &PsLoadedModuleList;
606 ListEntry = ListEntry->Flink)
607 {
608 LdrEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
609 if (RtlEqualUnicodeString(&LdrEntry->BaseDllName, &ExportDriverName, TRUE))
610 return LdrEntry;
611 }
612 return NULL;
613
614 default:
615 return NULL;
616 }
617}
618
619/* Write an import address table entry. The table can already be write-protected
620 * (for example for boot drivers), so write through a temporary mapping. */
621static NTSTATUS
624 _In_ PVOID NewFunction)
625{
626 PMDL Mdl;
627 PIMAGE_THUNK_DATA MappedThunk;
629
630 Mdl = IoAllocateMdl(Thunk, sizeof(*Thunk), FALSE, FALSE, NULL);
631 if (!Mdl)
633
635 {
637 }
639 {
641 }
642 _SEH2_END;
643
644 if (!NT_SUCCESS(Status))
645 {
646 IoFreeMdl(Mdl);
647 return Status;
648 }
649
651 if (MappedThunk)
652 {
653 InterlockedExchangePointer((PVOID*)&MappedThunk->u1.Function, NewFunction);
654 MmUnmapLockedPages(MappedThunk, Mdl);
655 }
656 else
657 {
659 }
660
662 IoFreeMdl(Mdl);
663 return Status;
664}
665
666static VOID
669 _In_ PKSE_HOOK_COLLECTION HookCollection)
670{
671 PUCHAR DllBase = LdrEntry->DllBase;
672 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
673 PIMAGE_THUNK_DATA OriginalThunk, FirstThunk;
674 PIMAGE_IMPORT_BY_NAME ImportByName;
675 PLDR_DATA_TABLE_ENTRY ExportEntry;
677 PKSE_HOOK Hook;
678 BOOLEAN Match;
679 ULONG Size;
681
682 ExportEntry = KsepFindExportingModule(HookCollection, &ModuleName);
683 if (!ExportEntry)
684 {
685 DPRINT1("KSE: Exporting module for collection type %lu not found\n", HookCollection->Type);
686 return;
687 }
688
689 /* Resolve the original functions. They are the same for every shimmed driver. */
690 for (Hook = HookCollection->HookArray; Hook->Type != KseHookInvalid; Hook++)
691 {
692 if (Hook->Type != KseHookFunction || Hook->OriginalFunction)
693 continue;
694
696 if (!Hook->OriginalFunction)
697 DPRINT1("KSE: %s not exported by %S\n", Hook->FunctionName, ModuleName);
698 }
699
701 if (!ImportDescriptor)
702 return;
703
704 for (; ImportDescriptor->Name && ImportDescriptor->FirstThunk; ImportDescriptor++)
705 {
706 if (ImportDescriptor->Name >= LdrEntry->SizeOfImage ||
707 !KsepIsImportFromModule((PCSTR)(DllBase + ImportDescriptor->Name), ModuleName))
708 {
709 continue;
710 }
711
712 FirstThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->FirstThunk);
713 OriginalThunk = ImportDescriptor->OriginalFirstThunk ?
714 (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->OriginalFirstThunk) : NULL;
715
716 for (; FirstThunk->u1.Function; FirstThunk++, OriginalThunk = OriginalThunk ? OriginalThunk + 1 : NULL)
717 {
718 /* Without a name table, match on the address the import was bound to */
719 ImportByName = NULL;
720 if (OriginalThunk &&
721 !IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Ordinal) &&
722 OriginalThunk->u1.AddressOfData < LdrEntry->SizeOfImage)
723 {
724 ImportByName = (PIMAGE_IMPORT_BY_NAME)(DllBase + OriginalThunk->u1.AddressOfData);
725 }
726
727 for (Hook = HookCollection->HookArray; Hook->Type != KseHookInvalid; Hook++)
728 {
729 if (Hook->Type != KseHookFunction || !Hook->OriginalFunction)
730 continue;
731
732 if (ImportByName)
733 Match = !strcmp((PCSTR)ImportByName->Name, Hook->FunctionName);
734 else
735 Match = (FirstThunk->u1.Function == (ULONG_PTR)Hook->OriginalFunction);
736
737 if (!Match)
738 continue;
739
740 /* FIXME: When two shims hook the same function, the last one wins */
741 Status = KsepWriteImportEntry(FirstThunk, Hook->HookFunction);
742 if (NT_SUCCESS(Status))
743 DPRINT1("KSE: Hooked %S!%s in %wZ\n", ModuleName, Hook->FunctionName, &LdrEntry->BaseDllName);
744 else
745 DPRINT1("KSE: Unable to hook %S!%s in %wZ (0x%08lx)\n", ModuleName, Hook->FunctionName, &LdrEntry->BaseDllName, Status);
746 break;
747 }
748 }
749 }
750}
751
752static VOID
756{
757 PKSE_HOOK_COLLECTION HookCollection;
758
759 for (HookCollection = Shim->HookCollectionsArray;
760 HookCollection->Type != KseCollectionInvalid;
761 HookCollection++)
762 {
763 /* Callbacks are applied when the driver object is initialized */
764 if (HookCollection->Type == KseCollectionCallback)
765 continue;
766
767 KsepHookImports(LdrEntry, HookCollection);
768 }
769}
770
772NTAPI
775{
777 ULONG NumberOfShims, n;
779
781 return STATUS_SUCCESS;
782
783 Status = KsepGetShimsForDriver(LdrEntry, Shims, &NumberOfShims);
784 if (!NT_SUCCESS(Status))
785 {
786 DPRINT("KSE: No Shim found for %wZ\n", &LdrEntry->BaseDllName);
787 return STATUS_SUCCESS;
788 }
789
790 for (n = 0; n < NumberOfShims; n++)
791 {
792 DPRINT1("KSE: Applying shim %S (0x%08lx) to %wZ\n",
793 Shims[n]->ShimName, Shims[n]->ShimGuid->Data1, &LdrEntry->BaseDllName);
794
795 KsepApplyShimToDriver(Shims[n], LdrEntry);
796
797 if (Shims[n]->ShimmedDriverTargetedNotification)
798 {
799 PIMAGE_NT_HEADERS NtHeaders = RtlImageNtHeader(LdrEntry->DllBase);
800
801 Shims[n]->ShimmedDriverTargetedNotification(&LdrEntry->BaseDllName,
802 LdrEntry->DllBase,
803 LdrEntry->SizeOfImage,
804 NtHeaders ? NtHeaders->FileHeader.TimeDateStamp : 0,
805 LdrEntry->CheckSum);
806 }
807 }
808
809 return STATUS_SUCCESS;
810}
#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
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
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
#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:667
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:577
NTSTATUS NTAPI KseDriverLoadImage(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: kse.c:773
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:753
struct _KSE_ENGINE KSE_ENGINE
static BOOLEAN KsepIsImportFromModule(_In_ PCSTR ImportName, _In_ PCWSTR ModuleName)
Definition: kse.c:562
_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:474
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:622
enum _KSE_ENGINE_STATE KSE_ENGINE_STATE
NTSTATUS NTAPI KseUnregisterShim(_In_ PKSE_SHIM Shim, _In_ PVOID Unknown1, _In_ PVOID Unknown2)
Definition: kse.c:551
_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:464
PVOID NTAPI KsepPoolAllocateNonPaged(_In_ SIZE_T NumberOfBytes)
Definition: kse.c:70
#define KseCollectionDriverExport
Definition: kse.h:36
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
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
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::@2584 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