1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
/*++
Copyright (c) Alex Ionescu. All rights reserved.
Module Name:
shv.c
Abstract:
This module implements the Driver Entry/Unload for the Simple Hyper Visor.
Author:
Alex Ionescu (@aionescu) 16-Mar-2016 - Initial version
Environment:
Kernel mode only.
--*/
#include "shv.h"
VOID
ShvUnload (
_In_ PDRIVER_OBJECT DriverObject
)
{
SHV_DPC_CONTEXT dpcContext;
UNREFERENCED_PARAMETER(DriverObject);
//
// Attempt to exit VMX root mode on all logical processors. This will
// broadcast a DPC interrupt which will execute the callback routine in
// parallel on the LPs. Send the callback routine a NULL context in order
// to indicate that this is the unload, not load, path.
//
// Note that if SHV is not loaded on any of the LPs, this routine will not
// perform any work, but will not fail in any way.
//
dpcContext.Cr3 = 0;
KeGenericCallDpc(ShvVpCallbackDpc, &dpcContext);
//
// Indicate unload
//
DbgPrintEx(77, 0, "The SHV has been uninstalled.\n");
}
NTSTATUS
ShvInitialize (
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
SHV_DPC_CONTEXT dpcContext;
UNREFERENCED_PARAMETER(RegistryPath);
//
// Attempt to enter VMX root mode on all logical processors. This will
// broadcast a DPC interrupt which will execute the callback routine in
// parallel on the LPs. Send the callback routine the physical address of
// the PML4 of the system process, which is what this driver entrypoint
// should be executing in.
//
NT_ASSERT(PsGetCurrentProcess() == PsInitialSystemProcess);
dpcContext.Cr3 = __readcr3();
dpcContext.FailureStatus = STATUS_SUCCESS;
dpcContext.FailedCpu = -1;
dpcContext.InitCount = 0;
KeGenericCallDpc(ShvVpCallbackDpc, &dpcContext);
//
// Check if all LPs are now hypervised. Return the failure code of at least
// one of them.
//
// Note that each VP is responsible for freeing its VP data on failure.
//
if (dpcContext.InitCount != KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS))
{
DbgPrintEx(77, 0, "The SHV failed to initialize (0x%lX) Failed CPU: %d\n",
dpcContext.FailureStatus, dpcContext.FailedCpu);
NT_ASSERT(dpcContext.FailureStatus != STATUS_SUCCESS);
return dpcContext.FailureStatus;
}
//
// Make the driver (and SHV itself) unloadable, and indicate success.
//
DriverObject->DriverUnload = ShvUnload;
DbgPrintEx(77, 0, "The SHV has been installed.\n");
return STATUS_SUCCESS;
}
|