Welcome to mirror list, hosted at ThFree Co, Russian Federation.

shv.c - github.com/ionescu007/SimpleVisor.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/shv.c
blob: e10973cbafda0668ba24fc6ddf2d3dc5bc6669c4 (plain)
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;
}