Ü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: