Hiding Debuggers via Intel MSR_LSTAR Hooking

Durum
Üzgünüz bu konu cevaplar için kapatılmıştır...
Üye
Katılım
23 Eyl 2020
Mesajlar
36
Tepki puanı
27
Driver

C:
#pragma once


#ifdef _WIN64
#define CHECK_SIZE(str, size64, size32) static_assert(sizeof(str) == (size64), "Invalid " #str " size")
#define CHECK_SIZE_SAME(str, size) CHECK_SIZE(str, size, size)
#else
#define CHECK_SIZE(str, size64, size32) static_assert(sizeof(str) == (size32), "Invalid " #str " size")
#define CHECK_SIZE_SAME(str, size) CHECK_SIZE(str, size, size)
#endif

typedef struct _KSERVICE_TABLE_DESCRIPTOR
{
    LONG   *ServiceTable;
    PVOID  *CounterTable;
    ULONG  ServiceLimit;
    PUCHAR ArgumentTable;
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
//CHECK_SIZE(SYSTEM_SERVICE_TABLE, 0x4 + (0x3 * sizeof(PVOID)));

typedef enum _SYSTEM_INFORMATION_CLASS
{
    SystemBasicInformation = 0x0,
    SystemProcessorInformation = 0x1,
    SystemPerformanceInformation = 0x2,
    SystemTimeOfDayInformation = 0x3,
    SystemPathInformation = 0x4,
    SystemProcessInformation = 0x5,
    SystemCallCountInformation = 0x6,
    SystemDeviceInformation = 0x7,
    SystemProcessorPerformanceInformation = 0x8,
    SystemFlagsInformation = 0x9,
    SystemCallTimeInformation = 0xa,
    SystemModuleInformation = 0xb,
    SystemLocksInformation = 0xc,
    SystemStackTraceInformation = 0xd,
    SystemPagedPoolInformation = 0xe,
    SystemNonPagedPoolInformation = 0xf,
    SystemHandleInformation = 0x10,
    SystemObjectInformation = 0x11,
    SystemPageFileInformation = 0x12,
    SystemVdmInstemulInformation = 0x13,
    SystemVdmBopInformation = 0x14,
    SystemFileCacheInformation = 0x15,
    SystemPoolTagInformation = 0x16,
    SystemInterruptInformation = 0x17,
    SystemDpcBehaviorInformation = 0x18,
    SystemFullMemoryInformation = 0x19,
    SystemLoadGdiDriverInformation = 0x1a,
    SystemUnloadGdiDriverInformation = 0x1b,
    SystemTimeAdjustmentInformation = 0x1c,
    SystemSummaryMemoryInformation = 0x1d,
    SystemMirrorMemoryInformation = 0x1e,
    SystemPerformanceTraceInformation = 0x1f,
    SystemObsolete0 = 0x20,
    SystemExceptionInformation = 0x21,
    SystemCrashDumpStateInformation = 0x22,
    SystemKernelDebuggerInformation = 0x23,
    SystemContextSwitchInformation = 0x24,
    SystemRegistryQuotaInformation = 0x25,
    SystemExtendServiceTableInformation = 0x26,
    SystemPrioritySeperation = 0x27,
    SystemVerifierAddDriverInformation = 0x28,
    SystemVerifierRemoveDriverInformation = 0x29,
    SystemProcessorIdleInformation = 0x2a,
    SystemLegacyDriverInformation = 0x2b,
    SystemCurrentTimeZoneInformation = 0x2c,
    SystemLookasideInformation = 0x2d,
    SystemTimeSlipNotification = 0x2e,
    SystemSessionCreate = 0x2f,
    SystemSessionDetach = 0x30,
    SystemSessionInformation = 0x31,
    SystemRangeStartInformation = 0x32,
    SystemVerifierInformation = 0x33,
    SystemVerifierThunkExtend = 0x34,
    SystemSessionProcessInformation = 0x35,
    SystemLoadGdiDriverInSystemSpace = 0x36,
    SystemNumaProcessorMap = 0x37,
    SystemPrefetcherInformation = 0x38,
    SystemExtendedProcessInformation = 0x39,
    SystemRecommendedSharedDataAlignment = 0x3a,
    SystemComPlusPackage = 0x3b,
    SystemNumaAvailableMemory = 0x3c,
    SystemProcessorPowerInformation = 0x3d,
    SystemEmulationBasicInformation = 0x3e,
    SystemEmulationProcessorInformation = 0x3f,
    SystemExtendedHandleInformation = 0x40,
    SystemLostDelayedWriteInformation = 0x41,
    SystemBigPoolInformation = 0x42,
    SystemSessionPoolTagInformation = 0x43,
    SystemSessionMappedViewInformation = 0x44,
    SystemHotpatchInformation = 0x45,
    SystemObjectSecurityMode = 0x46,
    SystemWatchdogTimerHandler = 0x47,
    SystemWatchdogTimerInformation = 0x48,
    SystemLogicalProcessorInformation = 0x49,
    SystemWow64SharedInformationObsolete = 0x4a,
    SystemRegisterFirmwareTableInformationHandler = 0x4b,
    SystemFirmwareTableInformation = 0x4c,
    SystemModuleInformationEx = 0x4d,
    SystemVerifierTriageInformation = 0x4e,
    SystemSuperfetchInformation = 0x4f,
    SystemMemoryListInformation = 0x50,
    SystemFileCacheInformationEx = 0x51,
    SystemThreadPriorityClientIdInformation = 0x52,
    SystemProcessorIdleCycleTimeInformation = 0x53,
    SystemVerifierCancellationInformation = 0x54,
    SystemProcessorPowerInformationEx = 0x55,
    SystemRefTraceInformation = 0x56,
    SystemSpecialPoolInformation = 0x57,
    SystemProcessIdInformation = 0x58,
    SystemErrorPortInformation = 0x59,
    SystemBootEnvironmentInformation = 0x5a,
    SystemHypervisorInformation = 0x5b,
    SystemVerifierInformationEx = 0x5c,
    SystemTimeZoneInformation = 0x5d,
    SystemImageFileExecutionOptionsInformation = 0x5e,
    SystemCoverageInformation = 0x5f,
    SystemPrefetchPatchInformation = 0x60,
    SystemVerifierFaultsInformation = 0x61,
    SystemSystemPartitionInformation = 0x62,
    SystemSystemDiskInformation = 0x63,
    SystemProcessorPerformanceDistribution = 0x64,
    SystemNumaProximityNodeInformation = 0x65,
    SystemDynamicTimeZoneInformation = 0x66,
    SystemCodeIntegrityInformation = 0x67,
    SystemProcessorMicrocodeUpdateInformation = 0x68,
    SystemProcessorBrandString = 0x69,
    SystemVirtualAddressInformation = 0x6a,
    SystemLogicalProcessorAndGroupInformation = 0x6b,
    SystemProcessorCycleTimeInformation = 0x6c,
    SystemStoreInformation = 0x6d,
    SystemRegistryAppendString = 0x6e,
    SystemAitSamplingValue = 0x6f,
    SystemVhdBootInformation = 0x70,
    SystemCpuQuotaInformation = 0x71,
    SystemNativeBasicInformation = 0x72,
    SystemErrorPortTimeouts = 0x73,
    SystemLowPriorityIoInformation = 0x74,
    SystemBootEntropyInformation = 0x75,
    SystemVerifierCountersInformation = 0x76,
    SystemPagedPoolInformationEx = 0x77,
    SystemSystemPtesInformationEx = 0x78,
    SystemNodeDistanceInformation = 0x79,
    SystemAcpiAuditInformation = 0x7a,
    SystemBasicPerformanceInformation = 0x7b,
    SystemQueryPerformanceCounterInformation = 0x7c,
    SystemSessionBigPoolInformation = 0x7d,
    SystemBootGraphicsInformation = 0x7e,
    SystemScrubPhysicalMemoryInformation = 0x7f,
    SystemBadPageInformation = 0x80,
    SystemProcessorProfileControlArea = 0x81,
    SystemCombinePhysicalMemoryInformation = 0x82,
    SystemEntropyInterruptTimingInformation = 0x83,
    SystemConsoleInformation = 0x84,
    SystemPlatformBinaryInformation = 0x85,
    SystemThrottleNotificationInformation = 0x86,
    SystemHypervisorProcessorCountInformation = 0x87,
    SystemDeviceDataInformation = 0x88,
    SystemDeviceDataEnumerationInformation = 0x89,
    SystemMemoryTopologyInformation = 0x8a,
    SystemMemoryChannelInformation = 0x8b,
    SystemBootLogoInformation = 0x8c,
    SystemProcessorPerformanceInformationEx = 0x8d,
    SystemSpare0 = 0x8e,
    SystemSecureBootPolicyInformation = 0x8f,
    SystemPageFileInformationEx = 0x90,
    SystemSecureBootInformation = 0x91,
    SystemEntropyInterruptTimingRawInformation = 0x92,
    SystemPortableWorkspaceEfiLauncherInformation = 0x93,
    SystemFullProcessInformation = 0x94,
    SystemKernelDebuggerInformationEx = 0x95,
    SystemBootMetadataInformation = 0x96,
    SystemSoftRebootInformation = 0x97,
    SystemElamCertificateInformation = 0x98,
    SystemOfflineDumpConfigInformation = 0x99,
    SystemProcessorFeaturesInformation = 0x9a,
    SystemRegistryReconciliationInformation = 0x9b,
    MaxSystemInfoClass = 0x9c,
} SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS;

typedef enum _OBJECT_INFORMATION_CLASS_UNDOC
{
    // ObjectBasicInformation,
    ObjectNameInformation,
    // ObjectTypeInformation,
    ObjectTypesInformation,
    ObjectHandleFlagInformation,
    ObjectSessionInformation,
    MaxObjectInfoClass,
} OBJECT_INFORMATION_CLASS_UNDOC;

typedef enum _DEBUG_CONTROL_CODE
{
    SysDbgQueryModuleInformation = 0,
    SysDbgQueryTraceInformation = 1,
    SysDbgSetTracePoint = 2,
    SysDbgSetSpecialCall = 3,
    SysDbgClearSpecialCalls = 4,
    SysDbgQuerySpecialCalls = 5,
    SysDbgBreakPoint = 6,
    SysDbgQueryVersion = 7,
    SysDbgReadVirtual = 8,
    SysDbgWriteVirtual = 9,
    SysDbgReadPhysical = 10,
    SysDbgWritePhysical = 11,
    SysDbgReadControlSpace = 12,
    SysDbgWriteControlSpace = 13,
    SysDbgReadIoSpace = 14,
    SysDbgWriteIoSpace = 15,
    SysDbgReadMsr = 16,
    SysDbgWriteMsr = 17,
    SysDbgReadBusData = 18,
    SysDbgWriteBusData = 19,
    SysDbgCheckLowMemory = 20,
    SysDbgEnableKernelDebugger = 21,
    SysDbgDisableKernelDebugger = 22,
    SysDbgGetAutoKdEnable = 23,
    SysDbgSetAutoKdEnable = 24,
    SysDbgGetPrintBufferSize = 25,
    SysDbgSetPrintBufferSize = 26,
    SysDbgGetKdUmExceptionEnable = 27,
    SysDbgSetKdUmExceptionEnable = 28,
    SysDbgGetTriageDump = 29,
    SysDbgGetKdBlockEnable = 30,
    SysDbgSetKdBlockEnable = 31
} DEBUG_CONTROL_CODE;

typedef enum _THREAD_STATE
{
    StateInitialized,
    StateReady,
    StateRunning,
    StateStandby,
    StateTerminated,
    StateWait,
    StateTransition,
    StateUnknown
} THREAD_STATE;

// ************************ //
// NtQuerySystemInformation //
// ************************ //

#pragma warning(disable:4200)

// 5
typedef struct _SYSTEM_THREAD
{
    LARGE_INTEGER   KernelTime;
    LARGE_INTEGER   UserTime;
    LARGE_INTEGER   CreateTime;
    ULONG           WaitTime;
    PVOID           StartAddress;
    CLIENT_ID       ClientId;
    ULONG           Priority;
    LONG            BasePriority;
    ULONG           ContextSwitchCount;
    THREAD_STATE    State;
    ULONG           WaitReason;
} SYSTEM_THREAD, *PSYSTEM_THREAD;

typedef struct _SYSTEM_PROCESS_INFORMATION
{
    ULONG           NextEntryOffset;
    ULONG           NumberOfThreads;
    LARGE_INTEGER   Reserved[3];
    LARGE_INTEGER   CreateTime;
    LARGE_INTEGER   UserTime;
    LARGE_INTEGER   KernelTime;
    UNICODE_STRING  ImageName;
    ULONG           BasePriority;
    HANDLE          ProcessId;
    HANDLE          ParentProcessId;
    ULONG           HandleCount;
    ULONG           Reserved2[2];
    VM_COUNTERS     VMCounters;
    IO_COUNTERS     IOCounters;
    SYSTEM_THREAD   Threads[0];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;

// 11
typedef struct _SYSTEM_MODULE
{
    HANDLE Section;
    PVOID MappedBase;
    PVOID ImageBase;
    ULONG ImageSize;
    ULONG Flags;
    USHORT LoadOrderIndex;
    USHORT InitOrderIndex;
    USHORT LoadCount;
    USHORT OffsetToFileName;
    UCHAR FullPathName[256];
} SYSTEM_MODULE, *PSYSTEM_MODULE;
CHECK_SIZE(SYSTEM_MODULE, 0x128, 0x120);

typedef struct _SYSTEM_MODULE_INFORMATION
{
    ULONG                ModulesCount;
    SYSTEM_MODULE        Modules[0];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
CHECK_SIZE(SYSTEM_MODULE_INFORMATION, 0x8, 0x4);

// 35
typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION
{
    BOOLEAN DebuggerEnabled;
    BOOLEAN DebuggerNotPresent;
} SYSTEM_KERNEL_DEBUGGER_INFORMATION, *PSYSTEM_KERNEL_DEBUGGER_INFORMATION;
CHECK_SIZE_SAME(SYSTEM_KERNEL_DEBUGGER_INFORMATION, 0x2);

// 53
typedef struct _SYSTEM_SESSION_PROCESS_INFORMATION
{
    ULONG SessionId;
    ULONG BufferLength;
    PVOID Buffer;
} SYSTEM_SESSION_PROCESS_INFORMATION, *PSYSTEM_SESSION_PROCESS_INFORMATION;
CHECK_SIZE(SYSTEM_SESSION_PROCESS_INFORMATION, 0x10, 0xC);

// 88
typedef struct _SYSTEM_PROCESS_ID_INFORMATION
{
    HANDLE ProcessId;
    UNICODE_STRING ImageName;
} SYSTEM_PROCESS_ID_INFORMATION, *PSYSTEM_PROCESS_ID_INFORMATION;
CHECK_SIZE(SYSTEM_PROCESS_ID_INFORMATION, 0x8 + sizeof(UNICODE_STRING), 0x4 + sizeof(UNICODE_STRING));

// 149
typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX
{
    BOOLEAN BootedDebug;
    BOOLEAN DebuggerEnabled;
    BOOLEAN DebuggerPresent;
} SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX, *PSYSTEM_KERNEL_DEBUGGER_INFORMATION_EX;
CHECK_SIZE_SAME(SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX, 0x3);

// ************************ //
// NtQueryObject            //
// ************************ //

typedef struct _OBJECT_TYPE_INFORMATION
{
    UNICODE_STRING Name;
    ULONG TotalNumberOfObjects;
    ULONG TotalNumberOfHandles;
    ULONG TotalPagedPoolUsage;
    ULONG TotalNonPagedPoolUsage;
    ULONG TotalNamePoolUsage;
    ULONG TotalHandleTableUsage;
    ULONG HighWaterNumberOfObjects;
    ULONG HighWaterNumberOfHandles;
    ULONG HighWaterPagedPoolUsage;
    ULONG HighWaterNonPagedPoolUsage;
    ULONG HighWaterNamePoolUsage;
    ULONG HighWaterHandleTableUsage;
    ULONG InvalidAttributes;
    GENERIC_MAPPING GenericMapping;
    ULONG ValidAccess;
    BOOLEAN SecurityRequired;
    BOOLEAN MaintainHandleCount;
    USHORT MaintainTypeList;
    POOL_TYPE PoolType;
    ULONG PagedPoolUsage;
    ULONG NonPagedPoolUsage;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
CHECK_SIZE_SAME(OBJECT_TYPE_INFORMATION, 0x58 + sizeof(UNICODE_STRING));

typedef struct _OBJECT_ALL_TYPES_INFORMATION
{
    ULONG NumberOfTypes;
    OBJECT_TYPE_INFORMATION TypeInformation[0];
} OBJECT_ALL_TYPES_INFORMATION, *POBJECT_ALL_TYPES_INFORMATION;
CHECK_SIZE(OBJECT_ALL_TYPES_INFORMATION, 0x8, 0x4);

namespace Nt
{
    extern UNICODE_STRING DebugObjectName;

    NTSTATUS Initialize();
    NTSTATUS QuerySyscallIndexes();

    NTSTATUS NTAPI NtClose(HANDLE Handle);
    NTSTATUS NTAPI NtQueryInformationProcess(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
    NTSTATUS NTAPI NtQueryObject(HANDLE Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength);
    NTSTATUS NTAPI NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);
    NTSTATUS NTAPI NtReadVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, SIZE_T NumberOfBytesToRead, PSIZE_T NumberOfBytesRead);
    NTSTATUS NTAPI NtSetInformationThread(HANDLE ThreadHandle, THREADINFOCLASS ThreadInformationClass, PVOID ThreadInformation, ULONG ThreadInformationLength);
    NTSTATUS NTAPI NtSystemDebugControl(DEBUG_CONTROL_CODE ControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength, PULONG ReturnLength);
}
C:
#pragma once

#include <ntifs.h>
#include <ntimage.h>

#define PE_ERROR_VALUE ((ULONG_PTR)-1)

ULONG_PTR PeRvaToOffset(PIMAGE_NT_HEADERS NtHeaders, ULONG_PTR RVA, SIZE_T FileSize);
ULONG_PTR PeGetExportOffset(ULONG_PTR FileData, SIZE_T FileSize, const char *ExportName);

C:
#pragma once

NTSTATUS NTAPI hk_NtClose(HANDLE Handle);
NTSTATUS NTAPI hk_NtQueryInformationProcess(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
NTSTATUS NTAPI hk_NtQueryObject(HANDLE Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength);
NTSTATUS NTAPI hk_NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);
NTSTATUS NTAPI hk_NtReadVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, SIZE_T NumberOfBytesToRead, PSIZE_T NumberOfBytesRead);
NTSTATUS NTAPI hk_NtSetInformationThread(HANDLE ThreadHandle, THREADINFOCLASS ThreadInformationClass, PVOID ThreadInformation, ULONG ThreadInformationLength);
NTSTATUS NTAPI hk_NtSystemDebugControl(DEBUG_CONTROL_CODE ControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength, PULONG ReturnLength);

C:
#pragma once

ULONG_PTR GetNtoskrnlBase();
ULONG_PTR GetSSDTBase();
ULONG_PTR GetSSDTEntry(ULONG TableIndex);
NTSTATUS GetSSDTIndex(ULONG_PTR ImageBase, SIZE_T ImageSize, const char *FunctionName, PUINT32 Index);

NTSTATUS RemoveProcessFromSysProcessInfo(PVOID SystemInformation, ULONG SystemInformationLength);
NTSTATUS RemoveDriverFromSysModuleInfo(PVOID SystemInformation, ULONG SystemInformationLength, PULONG OutLength);
NTSTATUS RemoveDebugObjectInfo(PVOID ObjectInformation, ULONG ObjectInformationLength);
NTSTATUS RemoveSingleDebugObjectInfo(OBJECT_TYPE_INFORMATION *Information);
NTSTATUS InitializeSegmentSelector(PSEGMENT_SELECTOR SegmentSelector, USHORT Selector, PUCHAR GdtBase);
ULONG AdjustControls(ULONG Ctl, ULONG Msr);
NTSTATUS FillGuestSelectorData(PVOID GdtBase, ULONG Segreg, USHORT Selector);


C:
#pragma once

#ifdef __cplusplus
extern "C"
{
#endif
    extern ULONG64 NtSyscallHandler;
    extern ULONG64 GuestSyscallHandler;

    extern ULONG64 NtKernelBase;
    extern ULONG64 NtKernelSSDT;
#ifdef __cplusplus
}
#endif

NTSTATUS ServiceCallInitialize();

C:
#include <ntifs.h>
#include <Aux_klib.h>
#include "Nt.h"
#include "Hook.h"
#include "SSDT.h"
#include "Utility.h"

C++:
#pragma once

#include <ntifs.h>
#include "VM/stdafx.h"
#include "Syscall/stdafx.h"

extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
extern "C" VOID DriverUnload(PDRIVER_OBJECT DriverObject);

NTSTATUS DispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);

Kod:
[CODE=cpp

ULONG_PTR PeRvaToOffset(PIMAGE_NT_HEADERS NtHeaders, ULONG_PTR RVA, SIZE_T FileSize)
{
    PIMAGE_SECTION_HEADER sectionHeader = IMAGE_FIRST_SECTION(NtHeaders);

    for (int i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
    {
        ULONG_PTR virtualAddr = sectionHeader->VirtualAddress;
        ULONG_PTR virtualSize = sectionHeader->Misc.VirtualSize;

        if (virtualAddr <= RVA)
        {
            if ((virtualAddr + virtualSize) > RVA)
            {
                RVA -= virtualAddr;
                RVA += virtualSize;

                return (RVA < FileSize) ? RVA : PE_ERROR_VALUE;
            }
        }

        sectionHeader++;
    }

    return PE_ERROR_VALUE;
}

ULONG_PTR PeGetExportOffset(ULONG_PTR FileData, SIZE_T FileSize, const char *ExportName)
{
    PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)FileData;

    if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
        return PE_ERROR_VALUE;

    PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(FileData + dosHeader->e_lfanew);

    if (ntHeaders->Signature != IMAGE_NT_SIGNATURE)
        return PE_ERROR_VALUE;

    PIMAGE_DATA_DIRECTORY pdd    = ntHeaders->OptionalHeader.DataDirectory;
    ULONG_PTR exportDirRva        = pdd[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
    ULONG_PTR exportDirSize        = pdd[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
    ULONG_PTR exportDirOffset    = PeRvaToOffset(ntHeaders, exportDirRva, FileSize);

    if (exportDirOffset == PE_ERROR_VALUE)
        return PE_ERROR_VALUE;

    PIMAGE_EXPORT_DIRECTORY exportDir        = (PIMAGE_EXPORT_DIRECTORY)(FileData + exportDirOffset);
    ULONG_PTR addressOfFunctionsOffset        = PeRvaToOffset(ntHeaders, exportDir->AddressOfFunctions, FileSize);
    ULONG_PTR addressOfNameOrdinalsOffset    = PeRvaToOffset(ntHeaders, exportDir->AddressOfNameOrdinals, FileSize);
    ULONG_PTR addressOfNamesOffset            = PeRvaToOffset(ntHeaders, exportDir->AddressOfNames, FileSize);

    if (addressOfFunctionsOffset == PE_ERROR_VALUE ||
        addressOfNameOrdinalsOffset == PE_ERROR_VALUE ||
        addressOfNamesOffset == PE_ERROR_VALUE)
        return PE_ERROR_VALUE;

    PULONG addressOfFunctions        = (PULONG)(FileData + addressOfFunctionsOffset);
    PUSHORT addressOfNameOrdinals    = (PUSHORT)(FileData + addressOfNameOrdinalsOffset);
    PULONG addressOfNames            = (PULONG)(FileData + addressOfNamesOffset);

    for (ULONG i = 0; i < exportDir->NumberOfNames; i++)
    {
        ULONG_PTR currentNameOffset = PeRvaToOffset(ntHeaders, addressOfNames[i], FileSize);

        if (currentNameOffset == PE_ERROR_VALUE)
            continue;
      
        const char* currentName            = (const char *)(FileData + currentNameOffset);
        ULONG_PTR currentFunctionRva    = addressOfFunctions[addressOfNameOrdinals[i]];

        if (currentFunctionRva >= exportDirRva && currentFunctionRva < exportDirRva + exportDirSize)
            continue;

        if (_stricmp(currentName, ExportName) == 0)
            return PeRvaToOffset(ntHeaders, currentFunctionRva, FileSize);
    }

    return PE_ERROR_VALUE;
}

Kod:
));

                    pidInfo->ImageName.Length = 0;
                }
              
                return STATUS_INVALID_PARAMETER;
            }
        }
        else if (SystemInformationClass == SystemKernelDebuggerInformationEx)
        {
            PSYSTEM_KERNEL_DEBUGGER_INFORMATION_EX debugInfoEx = (PSYSTEM_KERNEL_DEBUGGER_INFORMATION_EX)SystemInformation;

            debugInfoEx->BootedDebug        = FALSE;
            debugInfoEx->DebuggerEnabled    = FALSE;
            debugInfoEx->DebuggerPresent    = FALSE;
        }

        SEH_END()
        SEH_EXCEPT(){ status = GetExceptionCode(); }
    }

    return status;
}

NTSTATUS NTAPI hk_NtReadVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, SIZE_T NumberOfBytesToRead, PSIZE_T NumberOfBytesRead)
{
    return Nt::NtReadVirtualMemory(ProcessHandle, BaseAddress, Buffer, NumberOfBytesToRead, NumberOfBytesRead);
}

NTSTATUS NTAPI hk_NtSetInformationThread(HANDLE ThreadHandle, THREADINFOCLASS ThreadInformationClass, PVOID ThreadInformation, ULONG ThreadInformationLength)
{
    if (ThreadInformationClass == ThreadHideFromDebugger)
    {
        PKTHREAD object = NULL;
        NTSTATUS status = ObReferenceObjectByHandle(ThreadHandle, 0, *PsThreadType, ExGetPreviousMode(), (PVOID *)&object, NULL);
      
        if (NT_SUCCESS(status))
        {
            ObDereferenceObject(object);
            return STATUS_SUCCESS;
        }
    }

    return Nt::NtSetInformationThread(ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength);
}

NTSTATUS NTAPI hk_NtSystemDebugControl(DEBUG_CONTROL_CODE ControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength, PULONG ReturnLength)
{
    return Nt::NtSystemDebugControl(ControlCode, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, ReturnLength);
}

Kod:
.BasicInfo.ImageBase;
            ULONG_PTR moduleEnd        = (ULONG_PTR)moduleStart + modules[i].ImageSize;

            if (symbolAddress >= moduleStart && moduleStart < moduleEnd)
                moduleBase = moduleStart;
        }
    }

    ExFreePoolWithTag(modules, 'KLIB');
    return moduleBase;
}

ULONG_PTR GetSSDTBase()
{
    UNICODE_STRING routineName;
    RtlInitUnicodeString(&routineName, L"KeAddSystemServiceTable");

    PVOID KeAddSystemServiceTable = MmGetSystemRoutineAddress(&routineName);

    if (!KeAddSystemServiceTable)
        return 0;

    UCHAR functionData[1024];
    ULONG functionSize = 0;
    RtlCopyMemory(functionData, KeAddSystemServiceTable, sizeof(functionData));

    for (ULONG i = 0; i < sizeof(functionData); i++)
    {
        if (functionData[i] == 0xC3)
        {
            functionSize = i + 1;
            break;
        }
    }

    if (functionSize <= 0)
        return 0;

    ULONG rva = 0;

    for (ULONG i = 0; i < functionSize; i++)
    {
        //
        // 48 83 BC 18 80 4A 35 00 00       cmp qword ptr [rax+rbx+354A80h], 0
        //
        if (memcmp(&functionData[i], "\x48\x83\xBC", 3) == 0)
        {
            if (functionData[i + 8] == 0x00)
            {
                rva = *(ULONG *)&functionData[i + 4];
                break;
            }
        }
    }

    ULONG_PTR ssdtAddress = NtKernelBase + rva;

    if (!MmIsAddressValid((PVOID)ssdtAddress))
        return 0;

    return ssdtAddress;
}

ULONG_PTR GetSSDTEntry(ULONG TableIndex)
{
    PKSERVICE_TABLE_DESCRIPTOR ssdt = (PKSERVICE_TABLE_DESCRIPTOR)NtKernelSSDT;

#ifdef _WIN64
    ULONG_PTR entry = (ULONG_PTR)ssdt->ServiceTable + (ssdt->ServiceTable[TableIndex] >> 4);
#else
    ULONG_PTR entry = (ULONG_PTR)ssdt->ServiceTable[TableIndex];
#endif

    if (!MmIsAddressValid((PVOID)entry))
    {
        return 0;
    }

    return entry;
}

NTSTATUS GetSSDTIndex(ULONG_PTR ImageBase, SIZE_T ImageSize, const char *FunctionName, PUINT32 Index)
{
    ULONG_PTR function = PeGetExportOffset(ImageBase, ImageSize, FunctionName);

    if (function == PE_ERROR_VALUE)
        return STATUS_NOT_FOUND;

    // 8B XX XX XX XX        MOV EAX, XXXXXXXX
    // 0F 05                SYSCALL
    // 0F 34                SYSENTER
    // C2/C3                RET(N)
    for (PUCHAR i = (PUCHAR)function; i < (PUCHAR)(function + 32); i++)
    {
        switch (i[0])
        {
        // MOV EAX
        case 0xB8:
            *Index = (*(UINT32 *)&i[1]);
            return STATUS_SUCCESS;

        case 0x0F:
            if (i[1] == 0x05 || i[1] == 0x34)
                return STATUS_NOT_FOUND;
            continue;

        // ret(n) -> error
        case 0xC2:
        case 0xC3: // 0xC3 <-- retn opcode
            return STATUS_NOT_FOUND;
        }
    }

    return STATUS_NOT_FOUND;
}

#define IS_IN_BOUNDS(var, start, size) (((ULONG_PTR)(var)) < ((ULONG_PTR)start + (size)))

NTSTATUS RemoveProcessFromSysProcessInfo(PVOID SystemInformation, ULONG SystemInformationLength)
{
    if (SystemInformationLength < sizeof(SYSTEM_PROCESS_INFORMATION))
        return STATUS_INFO_LENGTH_MISMATCH;

    PSYSTEM_PROCESS_INFORMATION moduleInfo = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;
    PSYSTEM_PROCESS_INFORMATION prevPointer = NULL;
    PSYSTEM_PROCESS_INFORMATION currPointer = NULL;
    PSYSTEM_PROCESS_INFORMATION nextPointer = NULL;

    for (;;)
    {
        if (moduleInfo->ProcessId == (HANDLE)3108)
            currPointer = moduleInfo;

        if (moduleInfo->NextEntryOffset == 0)
            break;

        ULONG_PTR nextIndex = (ULONG_PTR)moduleInfo + moduleInfo->NextEntryOffset;
        ULONG_PTR maxOffset = (ULONG_PTR)FIELD_OFFSET(SYSTEM_PROCESS_INFORMATION, ParentProcessId);

        if (!IS_IN_BOUNDS(nextIndex + maxOffset, SystemInformation, SystemInformationLength))
            break;

        if (currPointer)
        {
            nextPointer = (PSYSTEM_PROCESS_INFORMATION)nextIndex;
            break;
        }

        prevPointer = moduleInfo;
        moduleInfo    = (PSYSTEM_PROCESS_INFORMATION)nextIndex;
    }

    if (!currPointer)
        return STATUS_NOT_FOUND;
  
    if (prevPointer)
    {
        if (nextPointer)
            prevPointer->NextEntryOffset = (ULONG)((ULONG_PTR)nextPointer - (ULONG_PTR)prevPointer);
        else
            prevPointer->NextEntryOffset = 0;
    }

    SIZE_T zeroLength = 0;

    if (nextPointer)
    {
        zeroLength = (ULONG_PTR)nextPointer - (ULONG_PTR)currPointer;
    }
    else
    {
        zeroLength = ((ULONG_PTR)SystemInformation + SystemInformationLength) - (ULONG_PTR)currPointer;
    }

    RtlSecureZeroMemory(currPointer, zeroLength);
    return STATUS_SUCCESS;
}

NTSTATUS RemoveDriverFromSysModuleInfo(PVOID SystemInformation, ULONG SystemInformationLength, PULONG OutLength)
{
    if (SystemInformationLength <= sizeof(SYSTEM_MODULE_INFORMATION))
        return STATUS_INFO_LENGTH_MISMATCH;

    SystemInformationLength -= sizeof(SYSTEM_MODULE_INFORMATION);
    ULONG entryCount = SystemInformationLength / sizeof(SYSTEM_MODULE);
    PSYSTEM_MODULE_INFORMATION moduleInfo = (PSYSTEM_MODULE_INFORMATION)SystemInformation;
    PSYSTEM_MODULE startPointer = NULL;
    PSYSTEM_MODULE copyPointer    = NULL;
    ULONG remainderBytes        = 0;

    for (ULONG i = 0; i < entryCount; i++)
    {
        if (moduleInfo->Modules[i].ImageBase == (PVOID)0xfffff80010834000)
        {
            startPointer    = &moduleInfo->Modules[i];
            copyPointer        = &moduleInfo->Modules[i + 1];
            remainderBytes    = (entryCount - (i + 1)) * sizeof(SYSTEM_MODULE);

            break;
        }
    }

    if (!startPointer || !copyPointer)
        return STATUS_NOT_FOUND;

    ULONG modifiedLength = (SystemInformationLength - sizeof(SYSTEM_MODULE));

    if (remainderBytes > 0)
        RtlMoveMemory(startPointer, copyPointer, remainderBytes);

    RtlSecureZeroMemory((PUCHAR)SystemInformation + modifiedLength, sizeof(SYSTEM_MODULE));

    if (OutLength)
        *OutLength = modifiedLength;

    moduleInfo->ModulesCount -= 1;
    return STATUS_SUCCESS;
}

NTSTATUS RemoveDebugObjectInfo(PVOID ObjectInformation, ULONG ObjectInformationLength)
{
    if (ObjectInformationLength < (sizeof(OBJECT_ALL_TYPES_INFORMATION) + sizeof(OBJECT_TYPE_INFORMATION)))
        return STATUS_INFO_LENGTH_MISMATCH;

    POBJECT_ALL_TYPES_INFORMATION typesInfo = (POBJECT_ALL_TYPES_INFORMATION)ObjectInformation;
    POBJECT_TYPE_INFORMATION typeInfo        = typesInfo->TypeInformation;

    for (ULONG i = 0; i < typesInfo->NumberOfTypes; i++)
    {
        if (NT_SUCCESS(RemoveSingleDebugObjectInfo(typeInfo)))
            return STATUS_SUCCESS;

        ULONG_PTR nextType = ((ULONG_PTR)typeInfo->Name.Buffer + typeInfo->Name.Length) & 0xFFFFFFFC;

        if (nextType >= ((ULONG_PTR)ObjectInformation + ObjectInformationLength))
            break;

        typeInfo = (POBJECT_TYPE_INFORMATION)nextType;
    }

    return STATUS_NOT_FOUND;
}

NTSTATUS RemoveSingleDebugObjectInfo(OBJECT_TYPE_INFORMATION *Information)
{
    if (RtlEqualUnicodeString(&Information->Name, &Nt::DebugObjectName, FALSE))
    {
        Information->TotalNumberOfObjects = 0;
        Information->TotalNumberOfHandles = 0;

        return STATUS_SUCCESS;
    }

    return STATUS_NOT_FOUND;
}

Kod:
;
    CHAR SyscallParamTable[4096];
    PVOID SyscallPointerTable[4096];
    VOID SyscallEntryPoint();
}

NTSTATUS AddServiceCallHook(ULONG Index, UCHAR ParameterCount, PVOID Function)
{
    if (Index >= ARRAYSIZE(SyscallHookEnabled))
        return STATUS_INVALID_PARAMETER_1;

    if (ParameterCount > 15)
        return STATUS_INVALID_PARAMETER_2;

    KIRQL irql = KeGetCurrentIrql();

    if (irql < DISPATCH_LEVEL)
        irql = KeRaiseIrqlToDpcLevel();

    InterlockedExchange8(&SyscallHookEnabled[Index], FALSE);

    SyscallParamTable[Index]    = ParameterCount;
    SyscallPointerTable[Index]    = Function;

    if (Function)
        InterlockedExchange8(&SyscallHookEnabled[Index], TRUE);

    if (KeGetCurrentIrql() > irql)
        KeLowerIrql(irql);

    return STATUS_SUCCESS;
}

NTSTATUS RemoveServiceCallHook(ULONG Index)
{
    return AddServiceCallHook(Index, 0, NULL);
}

NTSTATUS ServiceCallInitialize()
{
    NTSTATUS status = AuxKlibInitialize();

    if (!NT_SUCCESS(status))
        return status;

    NtKernelBase = GetNtoskrnlBase();
    NtKernelSSDT = GetSSDTBase();

    if (!NtKernelBase || !NtKernelSSDT)
        return STATUS_UNSUCCESSFUL;

    NtSyscallHandler    = (ULONG64)__readmsr(MSR_LSTAR);
    GuestSyscallHandler = (ULONG64)&SyscallEntryPoint;
    RtlSecureZeroMemory(SyscallHookEnabled, sizeof(SyscallHookEnabled));
    RtlSecureZeroMemory(SyscallParamTable, sizeof(SyscallParamTable));
    RtlSecureZeroMemory(SyscallPointerTable, sizeof(SyscallPointerTable));
    status = Nt::Initialize();

    if (!NT_SUCCESS(status))
        return status;

    AddServiceCallHook(0x3E, 5, (PVOID)&hk_NtReadVirtualMemory);
    return STATUS_SUCCESS;
}

Kod:
[CODE=cpp

#define WINNT_DEVICE_NAME L"\\Device\\l33tHide"
#define MSDOS_DEVICE_NAME L"\\DosDevices\\l33tHide"

UNICODE_STRING usDriverName;
UNICODE_STRING usDosDeviceName;

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    UNREFERENCED_PARAMETER(RegistryPath);
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoControl;
    DriverObject->DriverUnload = DriverUnload;
    RtlInitUnicodeString(&usDriverName, WINNT_DEVICE_NAME);
    RtlInitUnicodeString(&usDosDeviceName, MSDOS_DEVICE_NAME);
    PDEVICE_OBJECT deviceObject;
    NTSTATUS status = IoCreateDevice(DriverObject, 0, &usDriverName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &deviceObject);

    if (!NT_SUCCESS(status))
        return status;

    IoCreateSymbolicLink(&usDosDeviceName, &usDriverName);
    ServiceCallInitialize();
    HANDLE thread;
    status = PsCreateSystemThread(&thread, THREAD_ALL_ACCESS, NULL, NULL, NULL, VmStart, NULL);

    if (!NT_SUCCESS(status))
        return status;

    ZwClose(thread);

    return STATUS_SUCCESS;
}

VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
    UNREFERENCED_PARAMETER(DriverObject);
    IoDeleteSymbolicLink(&usDosDeviceName);
    IoDeleteDevice(DriverObject->DeviceObject);
}

Hypervisor
C:
#ifndef AMD64_H
#define AMD64_H

#pragma warning(disable: 4201)
#pragma warning(disable: 4214)

#define KGDT64_NULL (0 * 16)
#define KGDT64_R0_CODE (1 * 16)
#define KGDT64_R0_DATA (1 * 16) + 8
#define KGDT64_R3_CMCODE (2 * 16)
#define KGDT64_R3_DATA (2 * 16) + 8
#define KGDT64_R3_CODE (3 * 16)
#define KGDT64_SYS_TSS (4 * 16)
#define KGDT64_R3_CMTEB (5 * 16)
#define KGDT64_R0_CMCODE (6 * 16)

#pragma pack (push, 1)

typedef union
{
  USHORT UCHARs;
  struct
  {
    USHORT type:4;              /* 0;  Bit 40-43 */
    USHORT s:1;                 /* 4;  Bit 44 */
    USHORT dpl:2;               /* 5;  Bit 45-46 */
    USHORT p:1;                 /* 7;  Bit 47 */
    // gap!     
    USHORT avl:1;               /* 8;  Bit 52 */
    USHORT l:1;                 /* 9;  Bit 53 */
    USHORT db:1;                /* 10; Bit 54 */
    USHORT g:1;                 /* 11; Bit 55 */
    USHORT Gap:4;
  } fields;
} SEGMENT_ATTRIBUTES;

typedef struct _TSS64
{
  ULONG Reserved0;
  PVOID RSP0;
  PVOID RSP1;
  PVOID RSP2;
  ULONG64 Reserved1;
  PVOID IST1;
  PVOID IST2;
  PVOID IST3;
  PVOID IST4;
  PVOID IST5;
  PVOID IST6;
  PVOID IST7;
  ULONG64 Reserved2;
  USHORT Reserved3;
  USHORT IOMapBaseAddress;
} TSS64, *PTSS64;

typedef struct _SEGMENT_SELECTOR
{
  USHORT sel;
  SEGMENT_ATTRIBUTES attributes;
  ULONG32 limit;
  ULONG64 base;
} SEGMENT_SELECTOR, *PSEGMENT_SELECTOR;

typedef struct _SEGMENT_DESCRIPTOR
{
  USHORT limit0;
  USHORT base0;
  UCHAR base1;
  UCHAR attr0;
  UCHAR limit1attr1;
  UCHAR base2;
} SEGMENT_DESCRIPTOR, *PSEGMENT_DESCRIPTOR;

typedef struct _INTERRUPT_GATE_DESCRIPTOR
{
  USHORT TargetOffset1500;
  USHORT TargetSelector;
  UCHAR InterruptStackTable;
  UCHAR Attributes;
  USHORT TargetOffset3116;
  ULONG32 TargetOffset6332;
  ULONG32 Reserved;
} INTERRUPT_GATE_DESCRIPTOR,
*PINTERRUPT_GATE_DESCRIPTOR;

#pragma pack (pop)

#define LA_ACCESSED        0x01
#define LA_READABLE        0x02    // for code segments
#define LA_WRITABLE        0x02    // for data segments
#define LA_CONFORMING    0x04    // for code segments
#define LA_EXPANDDOWN    0x04    // for data segments
#define LA_CODE            0x08
#define LA_STANDARD        0x10
#define LA_DPL_0        0x00
#define LA_DPL_1        0x20
#define LA_DPL_2        0x40
#define LA_DPL_3        0x60
#define LA_PRESENT        0x80

#define LA_LDT64        0x02
#define LA_ATSS64        0x09
#define LA_BTSS64        0x0b
#define LA_CALLGATE64    0x0c
#define LA_INTGATE64    0x0e
#define LA_TRAPGATE64    0x0f

#define HA_AVAILABLE    0x01
#define HA_LONG            0x02
#define HA_DB            0x04
#define HA_GRANULARITY    0x08

typedef enum SEGREGS
{
  ES = 0,
  CS,
  SS,
  DS,
  FS,
  GS,
  LDTR,
  TR
};

#define EFER_LME     (1<<8)
#define EFER_LMA     (1<<10)
#define X86_CR0_PE              0x00000001      /* Enable Protected Mode    (RW) */
#define X86_CR0_MP              0x00000002      /* Monitor Coprocessor      (RW) */
#define X86_CR0_EM              0x00000004      /* Require FPU Emulation    (RO) */
#define X86_CR0_TS              0x00000008      /* Task Switched            (RW) */
#define X86_CR0_ET              0x00000010      /* Extension type           (RO) */
#define X86_CR0_NE              0x00000020      /* Numeric Error Reporting  (RW) */
#define X86_CR0_WP              0x00010000      /* Supervisor Write Protect (RW) */
#define X86_CR0_AM              0x00040000      /* Alignment Checking       (RW) */
#define X86_CR0_NW              0x20000000      /* Not Write-Through        (RW) */
#define X86_CR0_CD              0x40000000      /* Cache Disable            (RW) */
#define X86_CR0_PG              0x80000000      /* Paging                   (RW) */

/*
* Intel CPU features in CR4
*/
#define X86_CR4_VME        0x0001  /* enable vm86 extensions */
#define X86_CR4_PVI        0x0002  /* virtual interrupts flag enable */
#define X86_CR4_TSD        0x0004  /* disable time stamp at ipl 3 */
#define X86_CR4_DE        0x0008  /* enable debugging extensions */
#define X86_CR4_PSE        0x0010  /* enable page size extensions */
#define X86_CR4_PAE        0x0020  /* enable physical address extensions */
#define X86_CR4_MCE        0x0040  /* Machine check enable */
#define X86_CR4_PGE        0x0080  /* enable global pages */
#define X86_CR4_PCE        0x0100  /* enable performance counters at ipl 3 */
#define X86_CR4_OSFXSR        0x0200  /* enable fast FPU save and restore */
#define X86_CR4_OSXMMEXCPT    0x0400  /* enable unmasked SSE exceptions */
#define X86_CR4_VMXE        0x2000  /* enable VMX */

/*
* Intel CPU  MSR
*/

/* MSRs & bits used for VMX enabling */

#define MSR_IA32_VMX_BASIC           0x480
#define MSR_IA32_FEATURE_CONTROL         0x03a
#define MSR_IA32_VMX_PINBASED_CTLS        0x481
#define MSR_IA32_VMX_PROCBASED_CTLS        0x482
#define MSR_IA32_VMX_PROCBASED_CTLS2    0x48b
#define MSR_IA32_VMX_EXIT_CTLS        0x483
#define MSR_IA32_VMX_ENTRY_CTLS        0x484

#define MSR_IA32_SYSENTER_CS        0x174
#define MSR_IA32_SYSENTER_ESP        0x175
#define MSR_IA32_SYSENTER_EIP        0x176
#define MSR_IA32_DEBUGCTL            0x1d9

/* x86-64 MSR */

#define MSR_EFER 0xc0000080           /* extended feature register */
#define MSR_STAR 0xc0000081           /* legacy mode SYSCALL target */
#define MSR_LSTAR 0xc0000082          /* long mode SYSCALL target */
#define MSR_CSTAR 0xc0000083          /* compatibility mode SYSCALL target */
#define MSR_SYSCALL_MASK 0xc0000084   /* EFLAGS mask for syscall */
#define MSR_FS_BASE 0xc0000100                /* 64bit FS base */
#define MSR_GS_BASE 0xc0000101                /* 64bit GS base */
#define MSR_SHADOW_GS_BASE  0xc0000102        /* SwapGS GS shadow */

#define CR0 0
#define CR3 3
#define CR4 4
#define CR8 8

#define RAX 0
#define RCX 1
#define RDX 2
#define RBX 3
#define RSP 4
#define RBP 5
#define RSI 6
#define RDI 7
#define R8 8
#define R9 9
#define R10 10
#define R11 11
#define R12 12
#define R13 13
#define R14 14
#define R15 15

//
// Used by the cpuid instruction when eax=1
//

typedef struct _VMX_FEATURES {
    unsigned SSE3        :1;        // SSE3 Extensions
    unsigned RES1        :2;
    unsigned MONITOR     :1;        // MONITOR/WAIT
    unsigned DS_CPL      :1;        // CPL qualified Debug Store
    unsigned VMX         :1;        // Virtual Machine Technology
    unsigned RES2        :1;
    unsigned EST         :1;        // Enhanced Intel© Speedstep Technology
    unsigned TM2         :1;        // Thermal monitor 2
    unsigned SSSE3       :1;        // SSSE3 extensions
    unsigned CID         :1;        // L1 context ID
    unsigned RES3        :2;
    unsigned CX16        :1;        // CMPXCHG16B
    unsigned xTPR        :1;        // Update control
    unsigned PDCM        :1;        // Performance/Debug capability MSR
    unsigned RES4        :2;
    unsigned DCA         :1;
    unsigned RES5        :13;
} VMX_FEATURES;

typedef struct _IA32_FEATURE_CONTROL_MSR
{
    unsigned Lock : 1;            // Bit 0 is the lock bit - cannot be
                                // modified once lock is set, controlled by BIOS
    unsigned VmxonInSmx : 1;
    unsigned EnableVmxon : 1;
    unsigned Reserved2 : 29;
    unsigned Reserved3 : 32;
} IA32_FEATURE_CONTROL_MSR;

typedef struct _CR0_REG
{
    union
    {
        struct
        {

            unsigned PE : 1;            // Protected Mode Enabled [Bit 0]
            unsigned MP : 1;            // Monitor Coprocessor FLAG
            unsigned EM : 1;            // Emulate FLAG
            unsigned TS : 1;            // Task Switched FLAG
            unsigned ET : 1;            // Extension Type FLAG
            unsigned NE : 1;            // Numeric Error
            unsigned Reserved1 : 10;    // 
            unsigned WP : 1;            // Write Protect
            unsigned Reserved2 : 1;        // 
            unsigned AM : 1;            // Alignment Mask
            unsigned Reserved3 : 10;    // 
            unsigned NW : 1;            // Not Write-Through
            unsigned CD : 1;            // Cache Disable
            unsigned PG : 1;            // Paging Enabled
        };

        ULONG64 all;
    };
} CR0_REG;

typedef struct _CR4_REG
{
    union
    {
        struct
        {
            unsigned VME : 1;            // Virtual Mode Extensions
            unsigned PVI : 1;            // Protected-Mode Virtual Interrupts
            unsigned TSD : 1;            // Time Stamp Disable
            unsigned DE : 1;            // Debugging Extensions
            unsigned PSE : 1;            // Page Size Extensions
            unsigned PAE : 1;            // Physical Address Extension
            unsigned MCE : 1;            // Machine-Check Enable
            unsigned PGE : 1;            // Page Global Enable
            unsigned PCE : 1;            // Performance-Monitoring Counter Enable
            unsigned OSFXSR : 1;            // OS Support for FXSAVE/FXRSTOR
            unsigned OSXMMEXCPT : 1;            // OS Support for Unmasked SIMD Floating-Point Exceptions
            unsigned Reserved1 : 2;            //
            unsigned VMXE : 1;            // Virtual Machine Extensions Enabled
            unsigned Reserved2 : 18;           //
        };

        ULONG64 all;
    };
} CR4_REG, *PCR4_REG;

typedef struct _RFLAGS {
    unsigned CF:1;
    unsigned Reserved1:1;
    unsigned PF:1;
    unsigned Reserved2:1;
    unsigned AF:1;
    unsigned Reserved3:1;
    unsigned ZF:1;
    unsigned SF:1;
    unsigned TF:1;
    unsigned IF:1;
    unsigned DF:1;
    unsigned OF:1;
    unsigned IOPL:2;
    unsigned NT:1;
    unsigned Reserved4:1;
    unsigned RF:1;
    unsigned VM:1;
    unsigned AC:1;
    unsigned VIF:1;
    unsigned VIP:1;
    unsigned ID:1;
    unsigned Reserved5:10;
} RFLAGS, *PRFLAGS;

#define TF 0x100

typedef union _DR6 {
    ULONG Value;
    struct {
        unsigned B0:1;
        unsigned B1:1;
        unsigned B2:1;
        unsigned B3:1;
        unsigned Reserved1:10;
        unsigned BD:1;
        unsigned BS:1;
        unsigned BT:1;
        unsigned Reserved2:16;
    };
} DR6, *PDR6;

typedef union _DR7 {
    ULONG Value;
    struct {
        unsigned L0:1;
        unsigned G0:1;
        unsigned L1:1;
        unsigned G1:1;
        unsigned L2:1;
        unsigned G2:1;
        unsigned L3:1;
        unsigned G3:1;
        unsigned LE:1;
        unsigned GE:1;
        unsigned Reserved1:3;
        unsigned GD:1;
        unsigned Reserved2:2;
        unsigned RW0:2;
        unsigned LEN0:2;
        unsigned RW1:2;
        unsigned LEN1:2;
        unsigned RW2:2;
        unsigned LEN2:2;
        unsigned RW3:2;
        unsigned LEN3:2;
    };
} DR7, *PDR7;

typedef union _IA32_DEBUGCTL_MSR
{
    ULONG Value;
    struct {
        unsigned LBR:1;
        unsigned BTF:1;
        unsigned Reserved1:4;
        unsigned TR:1;
        unsigned BTS:1;
        unsigned BTINT:1;
        unsigned BTS_OFF_OS:1;
        unsigned BTS_OFF_USR:1;
        unsigned FREEZE_LBRS_ON_PMI:1;
        unsigned FREEZE_PERFMON_ON_PMI:1;
        unsigned Reserved2:1;
        unsigned FREEZE_WHILE_SMM_EN:1;
    };
} IA32_DEBUGCTL_MSR, *PIA32_DEBUGCTL_MSR;

typedef struct _MSR {
    ULONG Lo;
    ULONG Hi;
} MSR, *PMSR;

typedef struct _VMX_BASIC_MSR {
    unsigned RevId:32;
    unsigned szVmxOnRegion:12;
    unsigned ClearBit:1;
    unsigned Reserved:3;
    unsigned PhysicalWidth:1;
    unsigned DualMonitor:1;
    unsigned MemoryType:4;
    unsigned VmExitInformation:1;
    unsigned Reserved2:9;
} VMX_BASIC_MSR, *PVMX_BASIC_MSR;

typedef struct _GUEST_REGS
{
  ULONG64 rax;
  ULONG64 rcx;
  ULONG64 rdx;
  ULONG64 rbx;
  ULONG64 rsp;
  ULONG64 rbp;
  ULONG64 rsi;
  ULONG64 rdi;
  ULONG64 r8;
  ULONG64 r9;
  ULONG64 r10;
  ULONG64 r11;
  ULONG64 r12;
  ULONG64 r13;
  ULONG64 r14;
  ULONG64 r15;
} GUEST_REGS, *PGUEST_REGS;

USHORT _Cs();
USHORT _Ds();
USHORT _Es();
USHORT _Ss();
USHORT _Fs();
USHORT _Gs();

ULONG64 _Rflags();
ULONG64 _Rsp();

ULONG64 _IdtBase();
USHORT _IdtLimit();
ULONG64 _GdtBase();
USHORT _GdtLimit();
USHORT _Ldtr();

USHORT _TrSelector();

FORCEINLINE size_t __readvmx(ULONG Type)
{
    size_t val = 0;
    __vmx_vmread(Type, &val);

    return val;
}

VOID __writecr2(unsigned __int64 Data);

VOID __invd();

#endif
C:
#pragma once

NTSTATUS _StartVirtualization();
VOID _StopVirtualization();
CHAR _QueryVirtualization();
VOID _GuestEntry();
VOID _ExitHandler();
VOID _GuestExit();

C:
#pragma once

extern LONG            CpuControlAreaCount;
extern LONG            CpuControlAreaSize;
extern PVIRT_CPU    *CpuControlArea;

NTSTATUS ControlAreaInitialize(LONG ProcessorCount);
NTSTATUS ControlAreaInitializeProcessor(LONG ProcessorNumber);
NTSTATUS AllocateVmxProcessorData(PVOID *VirtualAddress, PHYSICAL_ADDRESS *PhysicalAddress, SIZE_T *Size);
NTSTATUS FreeVmxProcessorData(PVOID VirtualAddress);

C:
#pragma once

typedef struct _VIRT_CPU
{
    PVOID                Self;

    ULONG32                ProcessorId;
    ULONG32                ThreadId;

    PVOID                VmxonVa;
    PHYSICAL_ADDRESS    VmxonPa;
    SIZE_T                VmxonSize;

    PVOID                VmcsVa;
    PHYSICAL_ADDRESS    VmcsPa;         
    SIZE_T                VmcsSize;

    PVOID                MSRBitmapVa; 
    PHYSICAL_ADDRESS    MSRBitmapPa; 
    SIZE_T                MSRBitmapSize; 

    PVOID                HostStackBase;
    SIZE_T                HostStackSize;

    ULONG64                ExitReason; 
    KIRQL                ExitIRQL;     
    KIRQL                PreviousIRQL; 

    ULONG64                rip;         
    ULONG64                rflags;         

    union
    {
        struct
        {
            ULONG64 rax;
            ULONG64 rcx;
            ULONG64 rdx;
            ULONG64 rbx;
            ULONG64 rsp;
            ULONG64 rbp;
            ULONG64 rsi;
            ULONG64 rdi;
            ULONG64 r8;
            ULONG64 r9;
            ULONG64 r10;
            ULONG64 r11;
            ULONG64 r12;
            ULONG64 r13;
            ULONG64 r14;
            ULONG64 r15;
        };

        ULONG64 Registers[16];
    };

} VIRT_CPU, *PVIRT_CPU;

#define CHECK_REGISTER_OFFSET(reg, val) \
        static_assert((offsetof(VIRT_CPU, reg) - offsetof(VIRT_CPU, rax)) == (val * sizeof(PVOID)), "VIRT_CPU::" #reg " != " #val);

CHECK_REGISTER_OFFSET(rax, RAX);
CHECK_REGISTER_OFFSET(rcx, RCX);
CHECK_REGISTER_OFFSET(rdx, RDX);
CHECK_REGISTER_OFFSET(rbx, RBX);
CHECK_REGISTER_OFFSET(rsp, RSP);
CHECK_REGISTER_OFFSET(rbp, RBP);
CHECK_REGISTER_OFFSET(rsi, RSI);
CHECK_REGISTER_OFFSET(rdi, RDI);
CHECK_REGISTER_OFFSET(r8, R8);
CHECK_REGISTER_OFFSET(r9, R9);
CHECK_REGISTER_OFFSET(r10, R10);
CHECK_REGISTER_OFFSET(r11, R11);
CHECK_REGISTER_OFFSET(r12, R12);
CHECK_REGISTER_OFFSET(r13, R13);
CHECK_REGISTER_OFFSET(r14, R14);
CHECK_REGISTER_OFFSET(r15, R15);

FORCEINLINE VOID CpuSetRegister(PVIRT_CPU Cpu, ULONG Index, ULONG64 Value)
{
#ifdef _DEBUG
    if (Index >= ARRAYSIZE(Cpu->Registers))
        __debugbreak();
#endif

    Cpu->Registers[Index] = Value;
}

FORCEINLINE ULONG64 CpuGetRegister(PVIRT_CPU Cpu, ULONG Index)
{
#ifdef _DEBUG
    if (Index >= ARRAYSIZE(Cpu->Registers))
        __debugbreak();
#endif

    return Cpu->Registers[Index];
}

VOID CpuDumpRegisters(PVIRT_CPU Cpu);
VOID CpuPrepareExit(PVIRT_CPU Cpu);
VOID CpuPrepareEntry(PVIRT_CPU Cpu);
VOID CpuUpdateState(PVIRT_CPU Cpu, PGUEST_REGS GuestRegisters);
VOID CpuSyncState(PVIRT_CPU Cpu, PGUEST_REGS GuestRegisters);
VOID CpuSetupVMCS(PVIRT_CPU Cpu, PVOID GuestRsp);
NTSTATUS Virtualize(PVIRT_CPU Cpu);

C:
#pragma once

VOID VmStart(PVOID StartContext);
CHAR VmIsActive();
NTSTATUS StartVirtualization(PVOID GuestRsp);

C:
#pragma once

typedef NTSTATUS (NTAPI * VmExitCallback)(PVIRT_CPU Cpu, ULONG InstructionLength);
VOID HandleVmExit(PVIRT_CPU Cpu, PGUEST_REGS GuestRegs);

C:
#pragma once

NTSTATUS NTAPI HandleUnimplemented(PVIRT_CPU Cpu, ULONG InstructionLength);
NTSTATUS NTAPI HandleCpuid(PVIRT_CPU Cpu, ULONG InstructionLength);
NTSTATUS NTAPI HandleException(PVIRT_CPU Cpu, ULONG InstructionLength);
NTSTATUS NTAPI HandleInvd(PVIRT_CPU Cpu, ULONG InstructionLength);
NTSTATUS NTAPI HandleRdpmc(PVIRT_CPU Cpu, ULONG InstructionLength);
NTSTATUS NTAPI HandleRdtsc(PVIRT_CPU Cpu, ULONG InstructionLength);
NTSTATUS NTAPI HandleVmCall(PVIRT_CPU Cpu, ULONG InstructionLength);
NTSTATUS NTAPI HandleVmInstruction(PVIRT_CPU Cpu, ULONG InstructionLength);
NTSTATUS NTAPI HandleCrAccess(PVIRT_CPU Cpu, ULONG InstructionLength);
NTSTATUS NTAPI HandleDrAccess(PVIRT_CPU Cpu, ULONG InstructionLength);
NTSTATUS NTAPI HandleMsrRead(PVIRT_CPU Cpu, ULONG InstructionLength);
NTSTATUS NTAPI HandleMsrWrite(PVIRT_CPU Cpu, ULONG InstructionLength);
NTSTATUS NTAPI HandleRdtscp(PVIRT_CPU Cpu, ULONG InstructionLength);
NTSTATUS NTAPI HandleXsetbv(PVIRT_CPU Cpu, ULONG InstructionLength);

C:
#define VECTOR_DIVIDE_ERROR_EXCEPTION               0
#define VECTOR_DEBUG_EXCEPTION                      1
#define VECTOR_NMI_INTERRUPT                        2
#define VECTOR_BREAKPOINT_EXCEPTION                 3
#define VECTOR_OVERFLOW_EXCEPTION                   4
#define VECTOR_BOUND_EXCEPTION                      5
#define VECTOR_INVALID_OPCODE_EXCEPTION             6
#define VECTOR_DEVICE_NOT_AVAILABLE_EXCEPTION       7
#define VECTOR_DOUBLE_FAULT_EXCEPTION               8
#define VECTOR_COPROCESSOR_SEGMENT_OVERRUN          9
#define VECTOR_INVALID_TSS_EXCEPTION                10
#define VECTOR_SEGMENT_NOT_PRESENT                  11
#define VECTOR_STACK_FAULT_EXCEPTION                12
#define VECTOR_GENERAL_PROTECTION_EXCEPTION         13
#define VECTOR_PAGE_FAULT_EXCEPTION                 14
#define VECTOR_X87_FLOATING_POINT_ERROR             16
#define VECTOR_ALIGNMENT_CHECK_EXCEPTION            17
#define VECTOR_MACHINE_CHECK_EXCEPTION              18
#define VECTOR_SIMD_FLOATING_POINT_EXCEPTION        19
#define VECTOR_VIRTUALIZATION_EXCEPTION             20
#define INTERRUPT_EXTERNAL                           0
#define INTERRUPT_RESERVED                           1
#define INTERRUPT_NMI                                2
#define INTERRUPT_HARDWARE_EXCEPTION                 3
#define INTERRUPT_SOFTWARE                           4
#define INTERRUPT_PRIVILEGED_SOFTWARE_EXCEPTION      5
#define INTERRUPT_SOFTWARE_EXCEPTION                 6
#define INTERRUPT_OTHER_EVENT                        7

typedef struct _INTERRUPT_INFO_FIELD
{
    unsigned Vector : 8;
    unsigned InterruptionType : 3;
    unsigned ErrorCodeValid : 1;
    unsigned NMIUnblocking : 1;
    unsigned Reserved : 18;
    unsigned Valid : 1;

} INTERRUPT_INFO_FIELD, * PINTERRUPT_INFO_FIELD;



typedef struct _INTERRUPT_INJECT_INFO_FIELD
{
    unsigned Vector : 8;
    unsigned InterruptionType : 3;
    unsigned DeliverErrorCode : 1;
    unsigned Reserved : 19;
    unsigned Valid : 1;

} INTERRUPT_INJECT_INFO_FIELD, * PINTERRUPT_INJECT_INFO_FIELD;

VOID VmInjectInterrupt(ULONG InterruptType, ULONG Vector, ULONG WriteLength);

C:
#ifndef _VIRTDBG_VMX_H
#define _VIRTDBG_VMX_H
#include <ntddk.h>
#include "amd64.h"
#include "misc.h"

# define VMX_CONTROL_REG_ACCESS_TYPE_MOV_TO_CR   0
# define VMX_CONTROL_REG_ACCESS_TYPE_MOV_FROM_CR 1
# define VMX_CONTROL_REG_ACCESS_TYPE_CLTS        2
# define VMX_CONTROL_REG_ACCESS_TYPE_LMSW        3
#define VMX_EXIT_REASONS_FAILED_VMENTRY 0x80000000
#define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES    0x00000001
#define SECONDARY_EXEC_ENABLE_EPT                0x00000002
#define SECONDARY_EXEC_RDTSCP                    0x00000008
#define SECONDARY_EXEC_ENABLE_VPID                0x00000020
#define SECONDARY_EXEC_WBINVD_EXITING            0x00000040
#define SECONDARY_EXEC_UNRESTRICTED_GUEST        0x00000080
#define SECONDARY_EXEC_PAUSE_LOOP_EXITING        0x00000400
#define CPU_BASED_VIRTUAL_INTR_PENDING        0x00000004
#define CPU_BASED_USE_TSC_OFFSETING           0x00000008
#define CPU_BASED_HLT_EXITING                 0x00000080
#define CPU_BASED_INVLPG_EXITING              0x00000200
#define CPU_BASED_MWAIT_EXITING               0x00000400
#define CPU_BASED_RDPMC_EXITING               0x00000800
#define CPU_BASED_RDTSC_EXITING               0x00001000
#define CPU_BASED_CR3_LOAD_EXITING            0x00008000
#define CPU_BASED_CR3_STORE_EXITING           0x00010000
#define CPU_BASED_CR8_LOAD_EXITING            0x00080000
#define CPU_BASED_CR8_STORE_EXITING           0x00100000
#define CPU_BASED_TPR_SHADOW                  0x00200000
#define CPU_BASED_VIRTUAL_NMI_PENDING         0x00400000
#define CPU_BASED_MOV_DR_EXITING              0x00800000
#define CPU_BASED_UNCOND_IO_EXITING           0x01000000
#define CPU_BASED_ACTIVATE_IO_BITMAP          0x02000000
#define CPU_BASED_MONITOR_TRAP_FLAG           0x08000000
#define CPU_BASED_ACTIVATE_MSR_BITMAP         0x10000000
#define CPU_BASED_MONITOR_EXITING             0x20000000
#define CPU_BASED_PAUSE_EXITING               0x40000000
#define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS 0x80000000

enum VM_EXIT_REASON
{
    EXIT_REASON_EXCEPTION_NMI       = 0,
    EXIT_REASON_EXTERNAL_INTERRUPT  = 1,
    EXIT_REASON_TRIPLE_FAULT        = 2,
    EXIT_REASON_INIT                = 3,
    EXIT_REASON_SIPI                = 4,
    EXIT_REASON_IO_SMI              = 5,
    EXIT_REASON_OTHER_SMI           = 6,
    EXIT_REASON_PENDING_VIRT_INTR   = 7,
    EXIT_REASON_PENDING_VIRT_NMI    = 8,
    EXIT_REASON_TASK_SWITCH         = 9,
    EXIT_REASON_CPUID               = 10,
    EXIT_REASON_GETSEC              = 11,
    EXIT_REASON_HLT                 = 12,
    EXIT_REASON_INVD                = 13,
    EXIT_REASON_INVLPG              = 14,
    EXIT_REASON_RDPMC               = 15,
    EXIT_REASON_RDTSC               = 16,
    EXIT_REASON_RSM                 = 17,
    EXIT_REASON_VMCALL              = 18,
    EXIT_REASON_VMCLEAR             = 19,
    EXIT_REASON_VMLAUNCH            = 20,
    EXIT_REASON_VMPTRLD             = 21,
    EXIT_REASON_VMPTRST             = 22,
    EXIT_REASON_VMREAD              = 23,
    EXIT_REASON_VMRESUME            = 24,
    EXIT_REASON_VMWRITE             = 25,
    EXIT_REASON_VMXOFF              = 26,
    EXIT_REASON_VMXON               = 27,
    EXIT_REASON_CR_ACCESS           = 28,
    EXIT_REASON_DR_ACCESS           = 29,
    EXIT_REASON_IO_INSTRUCTION      = 30,
    EXIT_REASON_MSR_READ            = 31,
    EXIT_REASON_MSR_WRITE           = 32,
    EXIT_REASON_INVALID_GUEST_STATE = 33,
    EXIT_REASON_MSR_LOADING         = 34,
    EXIT_REASON_UNDEFINED_1         = 35,
    EXIT_REASON_MWAIT_INSTRUCTION   = 36,
    EXIT_REASON_MONITOR_TRAP_FLAG   = 37,
    EXIT_REASON_UNDEFINED_2         = 38,
    EXIT_REASON_MONITOR_INSTRUCTION = 39,
    EXIT_REASON_PAUSE_INSTRUCTION   = 40,
    EXIT_REASON_MCE_DURING_VMENTRY  = 41,
    EXIT_REASON_UNDEFINED_3         = 42,
    EXIT_REASON_TPR_BELOW_THRESHOLD = 43,
    EXIT_REASON_APIC_ACCESS         = 44,
    EXIT_REASON_EOI_INDUCED         = 45,
    EXIT_REASON_ACCESS_GDTR_OR_IDTR = 46,
    EXIT_REASON_ACCESS_LDTR_OR_TR   = 47,
    EXIT_REASON_EPT_VIOLATION       = 48,
    EXIT_REASON_EPT_MISCONFIG       = 49,
    EXIT_REASON_INVEPT              = 50,
    EXIT_REASON_RDTSCP              = 51,
    EXIT_REASON_VMX_PREEMPTION_TIMER_EXPIRED = 52,
    EXIT_REASON_INVVPID             = 53,
    EXIT_REASON_WBINVD              = 54,
    EXIT_REASON_XSETBV              = 55,
    EXIT_REASON_APIC_WRITE          = 56,
    EXIT_REASON_RDRAND              = 57,
    EXIT_REASON_INVPCID             = 58,
    EXIT_REASON_VMFUNC              = 59,
    EXIT_REASON_UNDEFINED_4         = 60,
    EXIT_REASON_RDSEED              = 61,
    EXIT_REASON_UNDEFINED_5         = 62,
    EXIT_REASON_XSAVES              = 63,
    EXIT_REASON_XRSTORS             = 64,
    VMX_MAX_GUEST_VMEXIT,
};

typedef struct _MOV_CR_QUALIFICATION
{
    unsigned ControlRegister:4;
    unsigned AccessType:2;
    unsigned LMSWOperandType:1;
    unsigned Reserved1:1;
    unsigned Register:4;
    unsigned Reserved2:4;
    unsigned LMSWSourceData:16;
    unsigned Reserved3:32;
} MOV_CR_QUALIFICATION, *PMOV_CR_QUALIFICATION;

typedef struct _MOV_DR_QUALIFICATION
{
    unsigned DebugRegister        : 3;
    unsigned Reserved1            : 1;
    unsigned AccessDirection    : 1;
    unsigned Reserved2            : 3;
    unsigned Register            : 4;
    UINT64 Reserved3            : 52;
} MOV_DR_QUALIFICATION, *PMOV_DR_QUALIFICATION;

typedef struct _DEBUG_EXIT_QUALIFICATION {
    unsigned B0:1;
    unsigned B1:1;
    unsigned B2:1;
    unsigned B3:1;
    unsigned Reserved:9;
    unsigned BD:1;
    unsigned BS:1;
    unsigned Reserved2:17;
    unsigned Reserved3:32;
} DEBUG_EXIT_QUALIFICATION, *PDEBUG_EXIT_QUALIFICATION;

#define PIN_BASED_EXT_INTR_MASK         0x00000001
#define PIN_BASED_NMI_EXITING           0x00000008

#define VM_EXIT_IA32E_MODE              0x00000200
#define VM_EXIT_ACK_INTR_ON_EXIT        0x00008000

#define VM_ENTRY_IA32E_MODE             0x00000200
#define VM_ENTRY_SMM                    0x00000400
#define VM_ENTRY_DEACT_DUAL_MONITOR     0x00000800

enum VMCS_ENCODING
{
    GUEST_ES_SELECTOR = 0x00000800,
    GUEST_CS_SELECTOR = 0x00000802,
    GUEST_SS_SELECTOR = 0x00000804,
    GUEST_DS_SELECTOR = 0x00000806,
    GUEST_FS_SELECTOR = 0x00000808,
    GUEST_GS_SELECTOR = 0x0000080a,
    GUEST_LDTR_SELECTOR = 0x0000080c,
    GUEST_TR_SELECTOR = 0x0000080e,
    HOST_ES_SELECTOR = 0x00000c00,
    HOST_CS_SELECTOR = 0x00000c02,
    HOST_SS_SELECTOR = 0x00000c04,
    HOST_DS_SELECTOR = 0x00000c06,
    HOST_FS_SELECTOR = 0x00000c08,
    HOST_GS_SELECTOR = 0x00000c0a,
    HOST_TR_SELECTOR = 0x00000c0c,
    IO_BITMAP_A = 0x00002000,
    IO_BITMAP_A_HIGH = 0x00002001,
    IO_BITMAP_B = 0x00002002,
    IO_BITMAP_B_HIGH = 0x00002003,
    MSR_BITMAP = 0x00002004,
    MSR_BITMAP_HIGH = 0x00002005,
    VM_EXIT_MSR_STORE_ADDR = 0x00002006,
    VM_EXIT_MSR_STORE_ADDR_HIGH = 0x00002007,
    VM_EXIT_MSR_LOAD_ADDR = 0x00002008,
    VM_EXIT_MSR_LOAD_ADDR_HIGH = 0x00002009,
    VM_ENTRY_MSR_LOAD_ADDR = 0x0000200a,
    VM_ENTRY_MSR_LOAD_ADDR_HIGH = 0x0000200b,
    TSC_OFFSET = 0x00002010,
    TSC_OFFSET_HIGH = 0x00002011,
    VIRTUAL_APIC_PAGE_ADDR = 0x00002012,
    VIRTUAL_APIC_PAGE_ADDR_HIGH = 0x00002013,
    VMCS_LINK_POINTER = 0x00002800,
    VMCS_LINK_POINTER_HIGH = 0x00002801,
    GUEST_IA32_DEBUGCTL = 0x00002802,
    GUEST_IA32_DEBUGCTL_HIGH = 0x00002803,
    PIN_BASED_VM_EXEC_CONTROL = 0x00004000,
    CPU_BASED_VM_EXEC_CONTROL = 0x00004002,
    EXCEPTION_BITMAP = 0x00004004,
    PAGE_FAULT_ERROR_CODE_MASK = 0x00004006,
    PAGE_FAULT_ERROR_CODE_MATCH = 0x00004008,
    CR3_TARGET_COUNT = 0x0000400a,
    VM_EXIT_CONTROLS = 0x0000400c,
    VM_EXIT_MSR_STORE_COUNT = 0x0000400e,
    VM_EXIT_MSR_LOAD_COUNT = 0x00004010,
    VM_ENTRY_CONTROLS = 0x00004012,
    VM_ENTRY_MSR_LOAD_COUNT = 0x00004014,
    VM_ENTRY_INTR_INFO_FIELD = 0x00004016,
    VM_ENTRY_EXCEPTION_ERROR_CODE = 0x00004018,
    VM_ENTRY_INSTRUCTION_LEN = 0x0000401a,
    TPR_THRESHOLD = 0x0000401c,
    SECONDARY_VM_EXEC_CONTROL = 0x0000401e,
    VM_INSTRUCTION_ERROR = 0x00004400,
    VM_EXIT_REASON = 0x00004402,
    VM_EXIT_INTR_INFO = 0x00004404,
    VM_EXIT_INTR_ERROR_CODE = 0x00004406,
    IDT_VECTORING_INFO_FIELD = 0x00004408,
    IDT_VECTORING_ERROR_CODE = 0x0000440a,
    VM_EXIT_INSTRUCTION_LEN = 0x0000440c,
    VMX_INSTRUCTION_INFO = 0x0000440e,
    GUEST_ES_LIMIT = 0x00004800,
    GUEST_CS_LIMIT = 0x00004802,
    GUEST_SS_LIMIT = 0x00004804,
    GUEST_DS_LIMIT = 0x00004806,
    GUEST_FS_LIMIT = 0x00004808,
    GUEST_GS_LIMIT = 0x0000480a,
    GUEST_LDTR_LIMIT = 0x0000480c,
    GUEST_TR_LIMIT = 0x0000480e,
    GUEST_GDTR_LIMIT = 0x00004810,
    GUEST_IDTR_LIMIT = 0x00004812,
    GUEST_ES_AR_BYTES = 0x00004814,
    GUEST_CS_AR_BYTES = 0x00004816,
    GUEST_SS_AR_BYTES = 0x00004818,
    GUEST_DS_AR_BYTES = 0x0000481a,
    GUEST_FS_AR_BYTES = 0x0000481c,
    GUEST_GS_AR_BYTES = 0x0000481e,
    GUEST_LDTR_AR_BYTES = 0x00004820,
    GUEST_TR_AR_BYTES = 0x00004822,
    GUEST_INTERRUPTIBILITY_INFO = 0x00004824,
    GUEST_ACTIVITY_STATE = 0x00004826,
    GUEST_SM_BASE = 0x00004828,
    GUEST_SYSENTER_CS = 0x0000482A,
    HOST_IA32_SYSENTER_CS = 0x00004c00,
    CR0_GUEST_HOST_MASK = 0x00006000,
    CR4_GUEST_HOST_MASK = 0x00006002,
    CR0_READ_SHADOW = 0x00006004,
    CR4_READ_SHADOW = 0x00006006,
    CR3_TARGET_VALUE0 = 0x00006008,
    CR3_TARGET_VALUE1 = 0x0000600a,
    CR3_TARGET_VALUE2 = 0x0000600c,
    CR3_TARGET_VALUE3 = 0x0000600e,
    EXIT_QUALIFICATION = 0x00006400,
    GUEST_LINEAR_ADDRESS = 0x0000640a,
    GUEST_CR0 = 0x00006800,
    GUEST_CR3 = 0x00006802,
    GUEST_CR4 = 0x00006804,
    GUEST_ES_BASE = 0x00006806,
    GUEST_CS_BASE = 0x00006808,
    GUEST_SS_BASE = 0x0000680a,
    GUEST_DS_BASE = 0x0000680c,
    GUEST_FS_BASE = 0x0000680e,
    GUEST_GS_BASE = 0x00006810,
    GUEST_LDTR_BASE = 0x00006812,
    GUEST_TR_BASE = 0x00006814,
    GUEST_GDTR_BASE = 0x00006816,
    GUEST_IDTR_BASE = 0x00006818,
    GUEST_DR7 = 0x0000681a,
    GUEST_RSP = 0x0000681c,
    GUEST_RIP = 0x0000681e,
    GUEST_RFLAGS = 0x00006820,
    GUEST_PENDING_DBG_EXCEPTIONS = 0x00006822,
    GUEST_SYSENTER_ESP = 0x00006824,
    GUEST_SYSENTER_EIP = 0x00006826,
    HOST_CR0 = 0x00006c00,
    HOST_CR3 = 0x00006c02,
    HOST_CR4 = 0x00006c04,
    HOST_FS_BASE = 0x00006c06,
    HOST_GS_BASE = 0x00006c08,
    HOST_TR_BASE = 0x00006c0a,
    HOST_GDTR_BASE = 0x00006c0c,
    HOST_IDTR_BASE = 0x00006c0e,
    HOST_IA32_SYSENTER_ESP = 0x00006c10,
    HOST_IA32_SYSENTER_EIP = 0x00006c12,
    HOST_RSP = 0x00006c14,
    HOST_RIP = 0x00006c16,
};

VOID StopVirtualization();

#endif

C:
#pragma once

NTSTATUS VTxEnableProcessors(LONG ProcessorCount);
NTSTATUS VTxHardwareStatus();
NTSTATUS VTxSoftwareStatus();

NASM:
.CODE

_Cs PROC
    mov        rax, cs
    ret
_Cs ENDP

_Ds PROC
    mov        rax, ds
    ret
_Ds ENDP

_Es PROC
    mov        rax, es
    ret
_Es ENDP

_Ss PROC
    mov        rax, ss
    ret
_Ss ENDP

_Fs PROC
    mov        rax, fs
    ret
_Fs ENDP

_Gs PROC
    mov        rax, gs
    ret
_Gs ENDP

_Rflags PROC
    pushfq
    pop        rax
    ret
_Rflags ENDP

_Rsp PROC
    mov        rax, rsp
    add        rax, 8
    ret
_Rsp ENDP

_IdtBase PROC
    LOCAL    idtr[10]:BYTE
  
    sidt    idtr
    mov        rax, QWORD PTR idtr[2]
    ret
_IdtBase ENDP

_IdtLimit PROC
    LOCAL    idtr[10]:BYTE
  
    sidt    idtr
    mov        ax, WORD PTR idtr[0]
    ret
_IdtLimit ENDP

_GdtBase PROC
    LOCAL    gdtr[10]:BYTE

    sgdt    gdtr
    mov        rax, QWORD PTR gdtr[2]
    ret
_GdtBase ENDP

_GdtLimit PROC
    LOCAL    gdtr[10]:BYTE

    sgdt    gdtr
    mov        ax, WORD PTR gdtr[0]
    ret
_GdtLimit ENDP

_Ldtr PROC
    sldt    rax
    ret
_Ldtr ENDP

_TrSelector PROC
    str    rax
    ret
_TrSelector ENDP

__writecr2 PROC
    mov cr2, rcx
    ret
__writecr2 ENDP

__invd PROC
    invd
    ret
__invd ENDP

END

NASM:
EXTERN StartVirtualization:PROC
EXTERN HandleVmExit:PROC

VMCALL_MAGIC_VALUE = 05644626748696465h

.CODE

_StartVirtualization PROC
    push    rax
    push    rcx
    push    rdx
    push    rbx
    push    rbp
    push    rsi
    push    rdi
    push    r8
    push    r9
    push    r10
    push    r11
    push    r12
    push    r13
    push    r14
    push    r15

    sub    rsp, 28h
    mov    rcx, rsp
    call StartVirtualization
_StartVirtualization ENDP

_StopVirtualization PROC
    mov rcx, VMCALL_MAGIC_VALUE
    mov eax, 0FFFFFFFFh
    vmcall
    int 3
_StopVirtualization ENDP 

_QueryVirtualization PROC
    mov rcx, VMCALL_MAGIC_VALUE
    mov eax, 0h
    vmcall
    ret
_QueryVirtualization ENDP

_GuestEntry PROC
    add    rsp, 28h

    pop    r15
    pop    r14
    pop    r13
    pop    r12
    pop    r11
    pop    r10
    pop    r9
    pop    r8
    pop    rdi
    pop    rsi
    pop    rbp
    pop    rbx
    pop    rdx
    pop    rcx
    pop    rax
    ret
_GuestEntry ENDP

_GuestExit PROC
    pop rbx
    pop rax
    ret
_GuestExit ENDP

_ExitHandler PROC
    sub rsp, 100h
    mov [rsp + 0h],  rax
    mov [rsp + 8h],  rcx
    mov [rsp + 10h], rdx
    mov [rsp + 18h], rbx
    mov [rsp + 20h], rbp ; RSP
    mov [rsp + 28h], rbp
    mov [rsp + 30h], rsi
    mov [rsp + 38h], rdi
    mov [rsp + 40h], r8
    mov [rsp + 48h], r9
    mov [rsp + 50h], r10
    mov [rsp + 58h], r11
    mov [rsp + 60h], r12
    mov [rsp + 68h], r13
    mov [rsp + 70h], r14
    mov [rsp + 78h], r15
    movups [rsp + 80h], xmm0
    movups [rsp + 90h], xmm1

    mov rcx, [rsp + 100h] ; PCPU
    mov rdx, rsp          ; GuestRegs

    sub    rsp, 28h
    call HandleVmExit
    add    rsp, 28h

    mov rax, [rsp + 0h]
    mov rcx, [rsp + 8h]
    mov rdx, [rsp + 10h]
    mov rbx, [rsp + 18h]
    mov rbp, [rsp + 20h] ; RSP
    mov rbp, [rsp + 28h]
    mov rsi, [rsp + 30h]
    mov rdi, [rsp + 38h]
    mov r8,  [rsp + 40h]
    mov r9,  [rsp + 48h]
    mov r10, [rsp + 50h]
    mov r11, [rsp + 58h]
    mov r12, [rsp + 60h]
    mov r13, [rsp + 68h]
    mov r14, [rsp + 70h]
    mov r15, [rsp + 78h]
    movups xmm0, [rsp + 80h]
    movups xmm1, [rsp + 90h]
    add rsp, 100h

    vmresume
    ret
_ExitHandler ENDP

END

Kod:
 = cpu;

    if (!NT_SUCCESS(AllocateVmxProcessorData(&cpu->VmxonVa, &cpu->VmxonPa, &cpu->VmxonSize)))
        return STATUS_NO_MEMORY;

    if (!NT_SUCCESS(AllocateVmxProcessorData(&cpu->VmcsVa, &cpu->VmcsPa, &cpu->VmcsSize)))
        return STATUS_NO_MEMORY;

    if (!NT_SUCCESS(AllocateVmxProcessorData(&cpu->MSRBitmapVa, &cpu->MSRBitmapPa, &cpu->MSRBitmapSize)))
        return STATUS_NO_MEMORY;

    RtlSecureZeroMemory(cpu->MSRBitmapVa, cpu->MSRBitmapSize);

    __try
    {
        if (__vmx_on(PA_PTR_INT64(cpu->VmxonPa)) > 0)
            return STATUS_UNSUCCESSFUL;

        if (__vmx_vmclear(PA_PTR_INT64(cpu->VmcsPa)) > 0)
            return STATUS_UNSUCCESSFUL;

        if (__vmx_vmptrld(PA_PTR_INT64(cpu->VmcsPa)) > 0)
            return STATUS_UNSUCCESSFUL;
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        return GetExceptionCode();
    }

    return STATUS_SUCCESS;
}

NTSTATUS AllocateVmxProcessorData(PVOID *VirtualAddress, PHYSICAL_ADDRESS *PhysicalAddress, SIZE_T *Size)
{
    if (!VirtualAddress || !PhysicalAddress || !Size)
        return STATUS_INVALID_PARAMETER;
  
    VMX_BASIC_MSR msr;
    TO_ULL(msr) = __readmsr(MSR_IA32_VMX_BASIC);

    if (*Size <= 0)
    {
        if (msr.szVmxOnRegion > 0)
            *Size = msr.szVmxOnRegion;
        else
            *Size = 0x1000;

        *Size = ROUND_TO_PAGES(*Size);
    }

    PHYSICAL_ADDRESS l1, l2, l3;

    l1.QuadPart = 0;
    l2.QuadPart = -1;
    l3.QuadPart = 0x200000;

    PVOID address = MmAllocateContiguousMemorySpecifyCache(*Size, l1, l2, l3, MmCached);

    if (!address)
        return STATUS_NO_MEMORY;

    RtlSecureZeroMemory(address, *Size);

    *(ULONG *)address = msr.RevId;
    *VirtualAddress     = address;
    *PhysicalAddress = MmGetPhysicalAddress(address);

    return STATUS_SUCCESS;
}

NTSTATUS FreeVmxProcessorData(PVOID VirtualAddress)
{
    if (!VirtualAddress)
        return STATUS_INVALID_PARAMETER;

    MmFreeContiguousMemory(VirtualAddress);
    return STATUS_SUCCESS;
}

Kod:
[CODE=c

NTSTATUS InitializeSegmentSelector(PSEGMENT_SELECTOR SegmentSelector, USHORT Selector, PUCHAR GdtBase)
{
    if (!SegmentSelector)
        return STATUS_INVALID_PARAMETER;

    if (Selector & 0x4)
    {
        return STATUS_INVALID_PARAMETER;
    }

    PSEGMENT_DESCRIPTOR SegDesc = (PSEGMENT_DESCRIPTOR)((PUCHAR)GdtBase + (Selector & ~0x7));
    SegmentSelector->sel = Selector;
    SegmentSelector->base = SegDesc->base0 | SegDesc->base1 << 16 | SegDesc->base2 << 24;
    SegmentSelector->limit = SegDesc->limit0 | (SegDesc->limit1attr1 & 0xf) << 16;
    SegmentSelector->attributes.UCHARs = SegDesc->attr0 | (SegDesc->limit1attr1 & 0xf0) << 4;

    if (!(SegDesc->attr0 & LA_STANDARD))
    {
        ULONG64 tmp = (*(PULONG64)((PUCHAR)SegDesc + 8));
        SegmentSelector->base = (SegmentSelector->base & 0xffffffff) | (tmp << 32);
    }

    if (SegmentSelector->attributes.fields.g)
    {
        SegmentSelector->limit = (SegmentSelector->limit << 12) + 0xfff;
    }

    return STATUS_SUCCESS;
}

ULONG AdjustControls(ULONG Ctl, ULONG Msr)
{
    LARGE_INTEGER msrValue;
    msrValue.QuadPart = __readmsr(Msr);

    Ctl &= msrValue.HighPart;
    Ctl |= msrValue.LowPart;
    return Ctl;
}

NTSTATUS FillGuestSelectorData(PVOID GdtBase, ULONG Segreg, USHORT Selector)
{
    SEGMENT_SELECTOR SegmentSelector = { 0 };
    ULONG uAccessRights;

    InitializeSegmentSelector(&SegmentSelector, Selector, GdtBase);
    uAccessRights = ((PUCHAR)& SegmentSelector.attributes)[0] + (((PUCHAR)&
        SegmentSelector.attributes)[1] << 12);

    if (!Selector)
        uAccessRights |= 0x10000;

    __vmx_vmwrite(GUEST_ES_SELECTOR + Segreg * 2, Selector);
    __vmx_vmwrite(GUEST_ES_LIMIT + Segreg * 2, SegmentSelector.limit);
    __vmx_vmwrite(GUEST_ES_AR_BYTES + Segreg * 2, uAccessRights);

    if ((Segreg == LDTR) || (Segreg == TR))
        __vmx_vmwrite(GUEST_ES_BASE + Segreg * 2, SegmentSelector.base);

    return STATUS_SUCCESS;
}

NASM:
EXTERN SyscallHookEnabled:DB
EXTERN SyscallParamTable:DB
EXTERN NtSyscallHandler:DQ
EXTERN NtKernelBase:DQ
EXTERN SyscallPointerTable:DQ

USERMD_STACK_GS = 10h
KERNEL_STACK_GS = 1A8h

MAX_SYSCALL_INDEX = 1000h

.CODE

SyscallEntryPoint PROC
    swapgs                               
    mov         gs:[USERMD_STACK_GS], rsp

    cmp         rax, MAX_SYSCALL_INDEX   
    jge         KiSystemCall64           

    lea         rsp, offset HookEnabled   
    cmp         byte ptr [rsp + rax], 0   
    jne         KiSystemCall64_Emulate   
SyscallEntryPoint ENDP

KiSystemCall64 PROC
    mov         rsp, gs:[USERMD_STACK_GS]   ; Usermode RSP
    swapgs                                  ; Switch usermode GS
    jmp         [KiSystemCall64Ptr]         ; jmp back to old syscall handler
KiSystemCall64 ENDP
KiSystemCall64_Emulate PROC

    mov         rsp, gs:[KERNEL_STACK_GS] 
    push        2Bh                       
    push        qword ptr gs:[10h]       
    push        r11                       
    push        33h                       
    push        rcx                     
    mov         rcx, r10                 

    sub         rsp, 8h                   
    push        rbp                       
    sub         rsp, 158h                 
    lea         rbp, [rsp+80h]           
    mov         [rbp+0C0h], rbx           
    mov         [rbp+0C8h], rdi           
    mov         [rbp+0D0h], rsi           
    mov         byte ptr [rbp-55h], 2h 
    mov         rbx, gs:[188h]           
    prefetchw   byte ptr [rbx+90h]       
    stmxcsr     dword ptr [rbp-54h]     
    ldmxcsr     dword ptr gs:[180h]       
    cmp         byte ptr [rbx+3], 0       
    mov         word ptr [rbp+80h], 0     
    jz          KiSS05                   
    mov         [rbp-50h], rax           
    mov         [rbp-48h], rcx           
    mov         [rbp-40h], rdx           
    mov         [rbp-38h], r8             
    mov         [rbp-30h], r9             

    int         3                         
    align       10h

    KiSS05:                           
    mov         [rbx+88h], rcx
    mov         [rbx+80h], eax

KiSystemCall64_Emulate ENDP

KiSystemServiceStart_Emulate PROC
    mov         [rbx+90h], rsp
    mov         edi, eax
    shr         edi, 7
    and         edi, 20h
    and         eax, 0FFFh
KiSystemServiceStart_Emulate ENDP

KiSystemServiceRepeat_Emulate PROC
    ; RAX = [IN ] syscall index
    ; R10 = [OUT] function address

    lea         r11, offset HookTable
    mov         r10, qword ptr [r11 + rax * 8h]

    lea         r11, offset ArgTble
    movzx       rax, byte ptr [r11 + rax]   ; RAX = parametre sayısı

    jmp         [KiServiceCopyEndPtr]
KiSystemServiceRepeat_Emulate ENDP

END

Kod:
;

    if (!NT_SUCCESS(status))
    {
        DbgPrint("Failed ControlAreaInitializeProcessor 0x%x\n", status);
        return status;
    }

    CpuSetupVMCS(cpu, GuestRsp);

    status = Virtualize(cpu);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("Failed Virtualize\n");
        return status;
    }

    return STATUS_SUCCESS;
}

Kod:
 =
{
    HandleException,            // 0  EXIT_REASON_EXCEPTION_NMI
    HandleUnimplemented,        // 1  EXIT_REASON_EXTERNAL_INTERRUPT
    HandleUnimplemented,        // 2  EXIT_REASON_TRIPLE_FAULT
    HandleUnimplemented,        // 3  EXIT_REASON_INIT
    HandleUnimplemented,        // 4  EXIT_REASON_SIPI
    HandleUnimplemented,        // 5  EXIT_REASON_IO_SMI
    HandleUnimplemented,        // 6  EXIT_REASON_OTHER_SMI
    HandleUnimplemented,        // 7  EXIT_REASON_PENDING_VIRT_INTR
    HandleUnimplemented,        // 8  EXIT_REASON_PENDING_VIRT_NMI
    HandleUnimplemented,        // 9  EXIT_REASON_TASK_SWITCH
    HandleCpuid,                // 10 EXIT_REASON_CPUID
    HandleUnimplemented,        // 11 EXIT_REASON_GETSEC
    HandleUnimplemented,        // 12 EXIT_REASON_HLT
    HandleInvd,                    // 13 EXIT_REASON_INVD
    HandleUnimplemented,        // 14 EXIT_REASON_INVLPG
    HandleRdpmc,                // 15 EXIT_REASON_RDPMC
    HandleRdtsc,                // 16 EXIT_REASON_RDTSC
    HandleUnimplemented,        // 17 EXIT_REASON_RSM
    HandleVmCall,                // 18 EXIT_REASON_VMCALL
    HandleVmInstruction,        // 19 EXIT_REASON_VMCLEAR
    HandleVmInstruction,        // 20 EXIT_REASON_VMLAUNCH
    HandleVmInstruction,        // 21 EXIT_REASON_VMPTRLD
    HandleVmInstruction,        // 22 EXIT_REASON_VMPTRST
    HandleVmInstruction,        // 23 EXIT_REASON_VMREAD
    HandleVmInstruction,        // 24 EXIT_REASON_VMRESUME
    HandleVmInstruction,        // 25 EXIT_REASON_VMWRITE
    HandleVmInstruction,        // 26 EXIT_REASON_VMXOFF
    HandleVmInstruction,        // 27 EXIT_REASON_VMXON
    HandleCrAccess,                // 28 EXIT_REASON_CR_ACCESS
    HandleDrAccess,                // 29 EXIT_REASON_DR_ACCESS
    HandleUnimplemented,        // 30 EXIT_REASON_IO_INSTRUCTION
    HandleMsrRead,                // 31 EXIT_REASON_MSR_READ
    HandleMsrWrite,                // 32 EXIT_REASON_MSR_WRITE
    HandleUnimplemented,        // 33 EXIT_REASON_INVALID_GUEST_STATE
    HandleUnimplemented,        // 34 EXIT_REASON_MSR_LOADING
    HandleUnimplemented,        // 35 ?
    HandleUnimplemented,        // 36 EXIT_REASON_MWAIT_INSTRUCTION
    HandleUnimplemented,        // 37 EXIT_REASON_MONITOR_TRAP_FLAG
    HandleUnimplemented,        // 38 ?
    HandleUnimplemented,        // 39 EXIT_REASON_MONITOR_INSTRUCTION
    HandleUnimplemented,        // 40 EXIT_REASON_PAUSE_INSTRUCTION
    HandleUnimplemented,        // 41 EXIT_REASON_MACHINE_CHECK
    HandleUnimplemented,        // 42 ?
    HandleUnimplemented,        // 43 EXIT_REASON_TPR_BELOW_THRESHOLD
    HandleUnimplemented,        // 44 EXIT_REASON_APIC_ACCESS
    HandleUnimplemented,        // 45 EXIT_REASON_EOI_INDUCED
    HandleUnimplemented,        // 46 EXIT_REASON_GIDTR_ACCESS
    HandleUnimplemented,        // 47 EXIT_REASON_LDTR_ACCESS
    HandleUnimplemented,        // 48 EXIT_REASON_EPT_VIOLATION
    HandleUnimplemented,        // 49 EXIT_REASON_EPT_MISCONFIG
    HandleUnimplemented,        // 50 EXIT_REASON_INVEPT
    HandleRdtscp,                // 51 EXIT_REASON_RDTSCP
    HandleUnimplemented,        // 52 EXIT_REASON_VMX_PREEMPTION_TIMER_EXPIRED
    HandleUnimplemented,        // 53 EXIT_REASON_INVVPID
    HandleUnimplemented,        // 54 EXIT_REASON_WBINVD
    HandleXsetbv,                // 55 EXIT_REASON_XSETBV
    HandleUnimplemented,        // 56 EXIT_REASON_APIC_WRITE
    HandleUnimplemented,        // 57 EXIT_REASON_RDRAND
    HandleUnimplemented,        // 58 EXIT_REASON_INVPCID
    HandleUnimplemented,        // 59 EXIT_REASON_VMFUNC
    HandleUnimplemented,        // 60 ?
    HandleUnimplemented,        // 61 EXIT_REASON_RDSEED
    HandleUnimplemented,        // 62 ?
    HandleUnimplemented,        // 63 EXIT_REASON_XSAVES
    HandleUnimplemented,        // 64 EXIT_REASON_XRSTORS
};

VOID HandleVmExit(PVIRT_CPU Cpu, PGUEST_REGS GuestRegs)
{
    CpuPrepareExit(Cpu);
    CpuUpdateState(Cpu, GuestRegs);
    __vmx_vmread(VM_EXIT_REASON, &Cpu->ExitReason);
    Cpu->ExitReason &= ~VMX_EXIT_REASONS_FAILED_VMENTRY;
    SIZE_T instructionLen = 0;
    __vmx_vmread(VM_EXIT_INSTRUCTION_LEN, &instructionLen);
    VmExitCallbacks[Cpu->ExitReason](Cpu, (ULONG)instructionLen);

    CpuSyncState(Cpu, GuestRegs);
    CpuPrepareEntry(Cpu);
}

Kod:
;
    __cpuidex(cpuInfo, (ULONG)Cpu->rax, (ULONG)Cpu->rcx);

    Cpu->rax = cpuInfo[0];
    Cpu->rbx = cpuInfo[1];
    Cpu->rcx = cpuInfo[2];
    Cpu->rdx = cpuInfo[3];
    Cpu->rip += InstructionLength;

    return STATUS_SUCCESS;
}

NTSTATUS NTAPI HandleException(PVIRT_CPU Cpu, ULONG InstructionLength)
{
    ULONG32 Event, InjectEvent;
    ULONG64 ErrorCode, ExitQualification;
    PINTERRUPT_INFO_FIELD pEvent;
    PINTERRUPT_INJECT_INFO_FIELD pInjectEvent;

    Event = (ULONG32)__readvmx(VM_EXIT_INTR_INFO);
    pEvent = (PINTERRUPT_INFO_FIELD)&Event;

    InjectEvent = 0;
    pInjectEvent = (PINTERRUPT_INJECT_INFO_FIELD)&InjectEvent;

    ErrorCode = __readvmx(VM_EXIT_INTR_ERROR_CODE);

    if (pEvent->ErrorCodeValid)
        __vmx_vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, ErrorCode);

    switch (pEvent->InterruptionType)
    {
    case INTERRUPT_NMI:
        DbgPrint("vmx: HandleNmi()\n");
        VmInjectInterrupt(INTERRUPT_NMI, VECTOR_NMI_INTERRUPT, 0);
        break;

    case INTERRUPT_EXTERNAL:
        DbgPrint("vmx: HandleExternalInterrupt()\n");
        break;

    case INTERRUPT_HARDWARE_EXCEPTION:
        switch (pEvent->Vector)
        {
        case VECTOR_DEBUG_EXCEPTION:
            DbgPrint("vmx: int1 rip = 0x%llx\n", Cpu->rip);
            VmInjectInterrupt(pEvent->InterruptionType, pEvent->Vector, InstructionLength);
            break;

        case VECTOR_INVALID_OPCODE_EXCEPTION:
            DbgPrint("vmx: Invalid opcode rip = 0x%llx\n", Cpu->rip);
          
            VmInjectInterrupt(pEvent->InterruptionType, pEvent->Vector, InstructionLength);
            break;

        case VECTOR_PAGE_FAULT_EXCEPTION:
            ExitQualification = __readvmx(EXIT_QUALIFICATION);
            __writecr2(ExitQualification);
            //__vmx_vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, ErrorCode);
            VmInjectInterrupt(pEvent->InterruptionType, pEvent->Vector, InstructionLength);
            break;

        default:
            DbgPrint("vmx: Hardware Exception (vector=0x%x)\n", pEvent->Vector);
            break;
        }

        break;

    case INTERRUPT_SOFTWARE_EXCEPTION:
        switch (pEvent->Vector)
        {
        case VECTOR_BREAKPOINT_EXCEPTION:
            DbgPrint("vmx: int3 rip = 0x%llx\n", Cpu->rip);

            VmInjectInterrupt(INTERRUPT_SOFTWARE_EXCEPTION, VECTOR_BREAKPOINT_EXCEPTION, InstructionLength);
            break;

        case VECTOR_OVERFLOW_EXCEPTION:
        default:
            DbgPrint("vmx: Software Exception (vector=0x%x)\n", pEvent->Vector);
            break;
        }
        break;

    default:
        DbgPrint("vmx: Unknown interruption type\n");
        break;
    }

    return STATUS_SUCCESS;
}

NTSTATUS NTAPI HandleInvd(PVIRT_CPU Cpu, ULONG InstructionLength)
{
    __invd();

    Cpu->rip += InstructionLength;

    return STATUS_SUCCESS;
}

NTSTATUS NTAPI HandleRdpmc(PVIRT_CPU Cpu, ULONG InstructionLength)
{
    LARGE_INTEGER pmc;
    pmc.QuadPart = __readpmc((ULONG)Cpu->rcx);

    Cpu->rax = pmc.LowPart;
    Cpu->rdx = pmc.HighPart;
    Cpu->rip += InstructionLength;

    return STATUS_SUCCESS;
}

NTSTATUS NTAPI HandleRdtsc(PVIRT_CPU Cpu, ULONG InstructionLength)
{
    // EDX:EAX <- TimeStampCounter
    LARGE_INTEGER tsc;
    tsc.QuadPart = __rdtsc();

    Cpu->rax = tsc.LowPart;
    Cpu->rdx = tsc.HighPart;
    Cpu->rip += InstructionLength;

    return STATUS_SUCCESS;
}

NTSTATUS NTAPI HandleVmCall(PVIRT_CPU Cpu, ULONG InstructionLength)
{
    DbgPrint("VMCALL: RIP = 0x%llx\n", Cpu->rip);

    if (Cpu->rcx != 0x5644626748696465)
    {
        VmInjectInterrupt(INTERRUPT_HARDWARE_EXCEPTION, VECTOR_INVALID_OPCODE_EXCEPTION, InstructionLength);
        return STATUS_SUCCESS;
    }
  
    switch ((ULONG)Cpu->rax)
    {
    case 0:
    {
        Cpu->rax = TRUE;
    }
    break;

    case 0xFFFFFFFF:
    {
        __debugbreak();
    }
    break;
    }

    Cpu->rip += InstructionLength;
    return STATUS_SUCCESS;
}

NTSTATUS NTAPI HandleVmInstruction(PVIRT_CPU Cpu, ULONG InstructionLength)
{
    DbgPrint("VmInstruction: rip = 0x%llx\n", Cpu->rip);

    Cpu->rflags |= 0x1;
    Cpu->rip += InstructionLength;

    return STATUS_SUCCESS;
}

NTSTATUS NTAPI HandleCrAccess(PVIRT_CPU Cpu, ULONG InstructionLength)
{
    size_t exitQualificationVal = __readvmx(EXIT_QUALIFICATION);
    PMOV_CR_QUALIFICATION exitQualification = (PMOV_CR_QUALIFICATION)&exitQualificationVal;

    if (exitQualification->AccessType == VMX_CONTROL_REG_ACCESS_TYPE_MOV_TO_CR)
    {
        ULONG64 reg = CpuGetRegister(Cpu, exitQualification->Register);

        switch (exitQualification->ControlRegister)
        {
        case CR0:    __vmx_vmwrite(GUEST_CR0, reg);    break;
        case CR3:    __vmx_vmwrite(GUEST_CR3, reg);    break;
        case CR4:    __vmx_vmwrite(GUEST_CR4, reg);    break;
        case CR8:    Cpu->ExitIRQL = (KIRQL)reg;        break;
        default:    __debugbreak();                    break;
        }
    }
    else if (exitQualification->AccessType == VMX_CONTROL_REG_ACCESS_TYPE_MOV_FROM_CR)
    {
        ULONG64 cr = 0;

        switch (exitQualification->ControlRegister)
        {
        case CR0:    __vmx_vmread(GUEST_CR0, &cr);    break;
        case CR3:    __vmx_vmread(GUEST_CR3, &cr);    break;
        case CR4:    __vmx_vmread(GUEST_CR4, &cr);    break;
        case CR8:    cr = Cpu->ExitIRQL;                break;
        default:    __debugbreak();                    break;
        }

        CpuSetRegister(Cpu, exitQualification->Register, cr);
    }
    else
    {
        __debugbreak();
    }

    Cpu->rip += InstructionLength;

    return STATUS_SUCCESS;
}

NTSTATUS NTAPI HandleDrAccess(PVIRT_CPU Cpu, ULONG InstructionLength)
{
    DbgPrint("DrAccess -- Src: 0x%llx\n", Cpu->rip);

    Cpu->rip += InstructionLength;

    return STATUS_SUCCESS;
}

NTSTATUS NTAPI HandleMsrRead(PVIRT_CPU Cpu, ULONG InstructionLength)
{
    LARGE_INTEGER msr;
    ULONG ecx = (ULONG)Cpu->rcx;

    switch (ecx)
    {
    case MSR_IA32_SYSENTER_CS:    msr.QuadPart = __readvmx(GUEST_SYSENTER_CS);    break;
    case MSR_IA32_SYSENTER_ESP:    msr.QuadPart = __readvmx(GUEST_SYSENTER_ESP);    break;
    case MSR_IA32_SYSENTER_EIP:    msr.QuadPart = __readvmx(GUEST_SYSENTER_EIP);    break;
    case MSR_GS_BASE:            msr.QuadPart = __readvmx(GUEST_GS_BASE);        break;
    case MSR_FS_BASE:            msr.QuadPart = __readvmx(GUEST_FS_BASE);        break;

    case MSR_LSTAR:             
            msr.QuadPart = NtSyscallHandler;
            DbgPrint("PG LSTAR - 0x%p\n", Cpu->rip);
            break;

    default:                 
            msr.QuadPart = __readmsr(ecx);                 
            break;
    }

    Cpu->rax = msr.LowPart;
    Cpu->rdx = msr.HighPart;
    Cpu->rip += InstructionLength;

    return STATUS_SUCCESS;
}

NTSTATUS NTAPI HandleMsrWrite(PVIRT_CPU Cpu, ULONG InstructionLength)
{
    LARGE_INTEGER msr;

    ULONG ecx        = (ULONG)Cpu->rcx;
    msr.LowPart        = (ULONG)Cpu->rax;
    msr.HighPart    = (ULONG)Cpu->rdx;

    switch (ecx)
    {
    case MSR_IA32_SYSENTER_CS:
        //__writemsr(MSR_IA32_SYSENTER_CS, Msr.QuadPart);
        __vmx_vmwrite(GUEST_SYSENTER_CS, msr.QuadPart);
        break;

    case MSR_IA32_SYSENTER_ESP:
        //__writemsr(MSR_IA32_SYSENTER_ESP, Msr.QuadPart);
        __vmx_vmwrite(GUEST_SYSENTER_ESP, msr.QuadPart);
        break;

    case MSR_IA32_SYSENTER_EIP:
        //__writemsr(MSR_IA32_SYSENTER_EIP, Msr.QuadPart);
        __vmx_vmwrite(GUEST_SYSENTER_EIP, msr.QuadPart);
        break;

    case MSR_GS_BASE:
        //__writemsr(MSR_GS_BASE, Msr.QuadPart);
        __vmx_vmwrite(GUEST_GS_BASE, msr.QuadPart);
        break;

    case MSR_FS_BASE:
        //__writemsr(MSR_FS_BASE, Msr.QuadPart);
        __vmx_vmwrite(GUEST_FS_BASE, msr.QuadPart);
        break;

    case MSR_LSTAR:
        // Ignore all writes
        break;

    default:
        __writemsr(ecx, msr.QuadPart);
        break;
    }

    Cpu->rip += InstructionLength;

    return STATUS_SUCCESS;
}

NTSTATUS NTAPI HandleRdtscp(PVIRT_CPU Cpu, ULONG InstructionLength)
{
    // ECX <- IA32_TSC_AUX[31:0]
    LARGE_INTEGER tsc;
    UINT32 procId;
    tsc.QuadPart = __rdtscp(&procId);

    Cpu->rax = tsc.LowPart;
    Cpu->rdx = tsc.HighPart;
    Cpu->rcx = procId;
    Cpu->rip += InstructionLength;

    return STATUS_SUCCESS;
}

NTSTATUS NTAPI HandleXsetbv(PVIRT_CPU Cpu, ULONG InstructionLength)
{
    // XCR[ECX] <- EDX:EAX
    LARGE_INTEGER controlValue;
    controlValue.LowPart    = (ULONG)Cpu->rax;
    controlValue.HighPart    = (ULONG)Cpu->rdx;

    _xsetbv((ULONG)Cpu->rcx, controlValue.QuadPart);

    Cpu->rip += InstructionLength;

    return STATUS_SUCCESS;
}

Kod:
[CODE=c]#include "stdafx.h"

NTSTATUS VTxEnableProcessors(LONG ProcessorCount)
{
    NTSTATUS status            = STATUS_SUCCESS;
    LONG processorIndex        = 0;

    for (; processorIndex < ProcessorCount; processorIndex++)
    {
        KAFFINITY oldAffinity    = KeSetSystemAffinityThreadEx((KAFFINITY)(1 << processorIndex));
        KIRQL oldIrql            = KeRaiseIrqlToDpcLevel();
        status = VTxSoftwareStatus();
        KeLowerIrql(oldIrql);
        KeRevertToUserAffinityThreadEx(oldAffinity);

        if (!NT_SUCCESS(status))
            break;
    }

    if (!NT_SUCCESS(status) || processorIndex != ProcessorCount)
    {
        return status;
    }

    return STATUS_SUCCESS;
}

NTSTATUS VTxHardwareStatus()
{
    int cpuInfo[4];
    __cpuid(cpuInfo, 0);

    if (cpuInfo[0] < 1)
    {
        return STATUS_NOT_SUPPORTED;
    }

    if (cpuInfo[1] != 'uneG' ||
        cpuInfo[2] != 'letn' ||
        cpuInfo[3] != 'Ieni')
    {
        int buffer[4];
        buffer[0] = cpuInfo[1];
        buffer[1] = cpuInfo[3];
        buffer[2] = cpuInfo[2];
        buffer[3] = 0;
        DbgPrint("%s\n", &buffer);

        return STATUS_NOT_SUPPORTED;
    }
  
    __cpuid(cpuInfo, 1);
  
    if ((cpuInfo[2] & (1 << 5)) == 0)
    {
        return STATUS_NOT_SUPPORTED;
    }

    return STATUS_SUCCESS;
}

NTSTATUS VTxSoftwareStatus()
{
    IA32_FEATURE_CONTROL_MSR msr;
    TO_ULL(msr) = __readmsr(MSR_IA32_FEATURE_CONTROL);

    if (msr.Lock == 1)
    {
        if (msr.EnableVmxon == 0)
        {
            return STATUS_NOT_SUPPORTED;
        }
    }
    else
    {
        msr.Lock        = 1;
        msr.VmxonInSmx    = 1;
        msr.EnableVmxon = 1;

        __writemsr(MSR_IA32_FEATURE_CONTROL, TO_ULL(msr));
    }

    CR0_REG cr0;
    TO_ULL(cr0) = __readcr0();

    if (cr0.PE == 0 || cr0.PG == 0)
    {
        return STATUS_NOT_SUPPORTED;
    }
    else
    {
        cr0.NE = 1;
    }

    __writecr0(TO_ULL(cr0));

    __try
    {
        __writecr4(__readcr4() | (1 << 13));
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        return GetExceptionCode();
    }

    return STATUS_SUCCESS;
}
 
Son düzenleme:
Üye
Katılım
5 Ocak 2021
Mesajlar
21
Tepki puanı
1
Yaş
24
1-#pragma once

2-ULONG_PTR GetNtoskrnlBase();
3-ULONG_PTR GetSSDTBase();
4-ULONG_PTR GetSSDTEntry(ULONG TableIndex);
5-NTSTATUS GetSSDTIndex(ULONG_PTR ImageBase, SIZE_T ImageSize, const char *FunctionName, 6-PUINT32 Index);

7-NTSTATUS RemoveProcessFromSysProcessInfo(PVOID SystemInformation, ULONG 8-SystemInformationLength);
9-NTSTATUS RemoveDriverFromSysModuleInfo(PVOID SystemInformation, ULONG 10-SystemInformationLength, PULONG OutLength);
11-NTSTATUS RemoveDebugObjectInfo(PVOID ObjectInformation, ULONG ObjectInformationLength);
12-NTSTATUS RemoveSingleDebugObjectInfo(OBJECT_TYPE_INFORMATION *Information);
13-NTSTATUS InitializeSegmentSelector(PSEGMENT_SELECTOR SegmentSelector, USHORT Selector, PUCHAR GdtBase);
14-ULONG AdjustControls(ULONG Ctl, ULONG Msr);
15- NTSTATUS FillGuestSelectorData(PVOID GdtBase, ULONG Segreg, USHORT Selector);
 
Onaylı Üye
Katılım
2 Ocak 2021
Mesajlar
50
Çözümler
1
Tepki puanı
2
Ödüller
1
Yaş
32
whats all this?
 
Durum
Üzgünüz bu konu cevaplar için kapatılmıştır...
Üst
  AdBlock Detected
Elbette, reklam engelleme yazılımı, reklamları engelleme konusunda harika bir iş çıkarır, ancak aynı zamanda web sitemizin bazı yararlı ve önemli özelliklerini de engeller. Mümkün olan en iyi site deneyimi için lütfen bir dakikanızı ayırarak AdBlocker'ınızı devre dışı bırakın.