/** * @file libhyperdbg.cpp * @author Sina Karvandi (sina@hyperdbg.org) * @brief Main interface to connect applications to driver * @details * @version 0.1 * @date 2020-04-11 * * @copyright This project is released under the GNU Public License v3. * */ #include "pch.h" using namespace std; // // Global Variables // extern HANDLE g_DeviceHandle; extern HANDLE g_IsDriverLoadedSuccessfully; extern BOOLEAN g_IsVmxOffProcessStart; extern PVOID g_MessageHandler; extern PVOID g_MessageHandlerSharedBuffer; extern TCHAR g_DriverLocation[MAX_PATH]; extern TCHAR g_DriverName[MAX_PATH]; extern BOOLEAN g_UseCustomDriverLocation; extern LIST_ENTRY g_EventTrace; extern BOOLEAN g_LogOpened; extern BOOLEAN g_BreakPrintingOutput; extern BOOLEAN g_IsConnectedToRemoteDebugger; extern BOOLEAN g_OutputSourcesInitialized; extern BOOLEAN g_IsSerialConnectedToRemoteDebugger; extern BOOLEAN g_IsDebuggerModulesLoaded; extern BOOLEAN g_IsReversingMachineModulesLoaded; extern BOOLEAN g_PrivilegesAlreadyAdjusted; extern LIST_ENTRY g_OutputSources; extern DEBUGGER_SYNCRONIZATION_EVENTS_STATE g_UserSyncronizationObjectsHandleTable[DEBUGGER_MAXIMUM_SYNCRONIZATION_USER_DEBUGGER_OBJECTS]; /** * @brief Set the function callback that will be called if any message * needs to be shown * * @param Handler Function that handles the messages * @return VOID */ VOID SetTextMessageCallback(PVOID Handler) { g_MessageHandler = Handler; } /** * @brief Set the function callback that will be called if any message * needs to be shown * * @param Handler Function that handles the messages * @return PVOID */ PVOID SetTextMessageCallbackUsingSharedBuffer(PVOID Handler) { g_MessageHandler = Handler; g_MessageHandlerSharedBuffer = malloc(COMMUNICATION_BUFFER_SIZE + TCP_END_OF_BUFFER_CHARS_COUNT); if (!g_MessageHandlerSharedBuffer) { g_MessageHandler = NULL; return NULL; } RtlZeroMemory(g_MessageHandlerSharedBuffer, COMMUNICATION_BUFFER_SIZE + TCP_END_OF_BUFFER_CHARS_COUNT); return g_MessageHandlerSharedBuffer; } /** * @brief Unset the function callback that will be called if any message * needs to be shown * * @return VOID */ VOID UnsetTextMessageCallback() { g_MessageHandler = NULL; free(g_MessageHandlerSharedBuffer); g_MessageHandlerSharedBuffer = NULL; } /** * @brief Show messages * * @param Fmt format string message * @param ... arguments * @return VOID */ VOID ShowMessages(const char * Fmt, ...) { va_list ArgList; va_list Args; char TempMessage[COMMUNICATION_BUFFER_SIZE + TCP_END_OF_BUFFER_CHARS_COUNT] = {0}; if (g_MessageHandler == NULL && !g_IsConnectedToRemoteDebugger && !g_IsSerialConnectedToRemoteDebugger) { va_start(Args, Fmt); vprintf(Fmt, Args); va_end(Args); if (!g_LogOpened) { return; } } va_start(ArgList, Fmt); int SprintfResult = vsprintf_s(TempMessage, Fmt, ArgList); va_end(ArgList); if (SprintfResult != -1) { if (g_IsConnectedToRemoteDebugger) { // // vsprintf_s and vswprintf_s return the number of characters written, // not including the terminating null character, or a negative value // if an output error occurs. // RemoteConnectionSendResultsToHost(TempMessage, SprintfResult); } else if (g_IsSerialConnectedToRemoteDebugger) { KdSendUsermodePrints(TempMessage, SprintfResult); } if (g_LogOpened) { // // .logopen command executed // LogopenSaveToFile(TempMessage); } if (g_MessageHandler != NULL) { // // There is another handler // if (g_MessageHandlerSharedBuffer == NULL) { ((SendMessageWithParamCallback)g_MessageHandler)(TempMessage); } else { memcpy(g_MessageHandlerSharedBuffer, TempMessage, strlen(TempMessage) + 1); ((SendMessageWithSharedBufferCallback)g_MessageHandler)(); } } } } /** * @brief Read kernel buffers using IRP Pending * * @param Device Driver handle * @return VOID */ VOID ReadIrpBasedBuffer() { BOOL Status; ULONG ReturnedLength; REGISTER_NOTIFY_BUFFER RegisterEvent; DWORD ErrorNum; HANDLE Handle; UINT32 OperationCode; RegisterEvent.hEvent = NULL; RegisterEvent.Type = IRP_BASED; // // Create another handle to be used in for reading kernel messages, // it is because I noticed that if I use a same handle for IRP Pending // and other IOCTLs then if I complete that IOCTL then both of the current // IOCTL and the Pending IRP are completed and return to user mode, // even if it's odd but that what happens, so this way we can solve it // if you know why this problem happens, then contact me ! // Handle = CreateFileA( "\\\\.\\HyperDbgDebuggerDevice", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, /// lpSecurityAttirbutes OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); /// lpTemplateFile if (Handle == INVALID_HANDLE_VALUE) { ErrorNum = GetLastError(); if (ErrorNum == ERROR_ACCESS_DENIED) { ShowMessages("err, access denied\nare you sure you have administrator " "rights?\n"); } else if (ErrorNum == ERROR_GEN_FAILURE) { ShowMessages("err, a device attached to the system is not functioning\n" "vmx feature might be disabled from BIOS or VBS/HVCI is active\n"); } else { ShowMessages("err, CreateFile failed with (%x)\n", ErrorNum); } g_DeviceHandle = NULL; Handle = NULL; return; } // // allocate buffer for transferring messages // char * OutputBuffer = (char *)malloc(UsermodeBufferSize); try { while (TRUE) { if (!g_IsVmxOffProcessStart) { // // Clear the buffer // ZeroMemory(OutputBuffer, UsermodeBufferSize); Status = DeviceIoControl( Handle, // Handle to device IOCTL_REGISTER_EVENT, // IO Control Code (IOCTL) &RegisterEvent, // Input Buffer to driver. SIZEOF_REGISTER_EVENT * 2, // Length of input buffer in bytes. (x 2 is bcuz as the // driver is x64 and has 64 bit values) OutputBuffer, // Output Buffer from driver. UsermodeBufferSize, // Length of output buffer in bytes. &ReturnedLength, // Bytes placed in buffer. NULL // synchronous call ); if (!Status) { // // Error occurred for second time, and we show the error message // // ShowMessages("ioctl failed with code 0x%x\n", GetLastError()); // // if we reach here, the packet is probably failed, it might // be because of using flush command // continue; } // // Compute the received buffer's operation code // memcpy(&OperationCode, OutputBuffer, sizeof(UINT32)); // ShowMessages("Returned Length : 0x%x \n", ReturnedLength); // ShowMessages("Operation Code : 0x%x \n", OperationCode); // // Check if the operation code contains mandatory debuggee bit // If that's the case, we shouldn't wait (sleep) for new messages // if ((OperationCode & OPERATION_MANDATORY_DEBUGGEE_BIT) == 0) { Sleep(DefaultSpeedOfReadingKernelMessages); // we're not trying to eat all of the CPU ;) } switch (OperationCode) { case OPERATION_LOG_NON_IMMEDIATE_MESSAGE: if (g_BreakPrintingOutput) { // // means that the user asserts a CTRL+C or CTRL+BREAK Signal // we shouldn't show or save anything in this case // continue; } ShowMessages("%s", OutputBuffer + sizeof(UINT32)); break; case OPERATION_LOG_MESSAGE_MANDATORY: ShowMessages("%s", OutputBuffer + sizeof(UINT32)); break; case OPERATION_LOG_INFO_MESSAGE: if (g_BreakPrintingOutput) { // // means that the user asserts a CTRL+C or CTRL+BREAK Signal // we shouldn't show or save anything in this case // continue; } ShowMessages("%s", OutputBuffer + sizeof(UINT32)); break; case OPERATION_LOG_ERROR_MESSAGE: if (g_BreakPrintingOutput) { // // means that the user asserts a CTRL+C or CTRL+BREAK Signal // we shouldn't show or save anything in this case // continue; } ShowMessages("%s", OutputBuffer + sizeof(UINT32)); break; case OPERATION_LOG_WARNING_MESSAGE: if (g_BreakPrintingOutput) { // // means that the user asserts a CTRL+C or CTRL+BREAK Signal // we shouldn't show or save anything in this case // continue; } ShowMessages("%s", OutputBuffer + sizeof(UINT32)); break; case OPERATION_COMMAND_FROM_DEBUGGER_CLOSE_AND_UNLOAD_VMM: KdCloseConnection(); break; case OPERATION_DEBUGGEE_USER_INPUT: KdHandleUserInputInDebuggee((DEBUGGEE_USER_INPUT_PACKET *)(OutputBuffer + sizeof(UINT32))); break; case OPERATION_DEBUGGEE_REGISTER_EVENT: KdRegisterEventInDebuggee( (PDEBUGGER_GENERAL_EVENT_DETAIL)(OutputBuffer + sizeof(UINT32)), ReturnedLength); break; case OPERATION_DEBUGGEE_ADD_ACTION_TO_EVENT: KdAddActionToEventInDebuggee( (PDEBUGGER_GENERAL_ACTION)(OutputBuffer + sizeof(UINT32)), ReturnedLength); break; case OPERATION_DEBUGGEE_CLEAR_EVENTS: KdSendModifyEventInDebuggee( (PDEBUGGER_MODIFY_EVENTS)(OutputBuffer + sizeof(UINT32)), TRUE); break; case OPERATION_DEBUGGEE_CLEAR_EVENTS_WITHOUT_NOTIFYING_DEBUGGER: KdSendModifyEventInDebuggee( (PDEBUGGER_MODIFY_EVENTS)(OutputBuffer + sizeof(UINT32)), FALSE); break; case OPERATION_HYPERVISOR_DRIVER_IS_SUCCESSFULLY_LOADED: // // Indicate that driver (Hypervisor) is loaded successfully // SetEvent(g_IsDriverLoadedSuccessfully); break; case OPERATION_HYPERVISOR_DRIVER_END_OF_IRPS: // // End of receiving messages (IRPs), nothing to do // break; case OPERATION_COMMAND_FROM_DEBUGGER_RELOAD_SYMBOL: // // Pause debugger after getting the results // KdReloadSymbolsInDebuggee(TRUE, ((PDEBUGGEE_SYMBOL_REQUEST_PACKET)(OutputBuffer + sizeof(UINT32)))->ProcessId); break; case OPERATION_NOTIFICATION_FROM_USER_DEBUGGER_PAUSE: // // handle pausing packet from user debugger // UdHandleUserDebuggerPausing( (PDEBUGGEE_UD_PAUSED_PACKET)(OutputBuffer + sizeof(UINT32))); break; default: // // Check if there are available output sources // if (!g_OutputSourcesInitialized || !ForwardingCheckAndPerformEventForwarding(OperationCode, OutputBuffer + sizeof(UINT32), ReturnedLength - sizeof(UINT32) - 1)) { if (g_BreakPrintingOutput) { // // means that the user asserts a CTRL+C or CTRL+BREAK Signal // we shouldn't show or save anything in this case // continue; } ShowMessages("%s", OutputBuffer + sizeof(UINT32)); } break; } } else { // // the thread should not work anymore // free(OutputBuffer); // // closeHandle // if (!CloseHandle(Handle)) { ShowMessages("err, closing handle 0x%x\n", GetLastError()); } return; } } } catch (const std::exception &) { ShowMessages("err, exception occurred in creating handle or parsing buffer\n"); } free(OutputBuffer); // // closeHandle // if (!CloseHandle(Handle)) { ShowMessages("err, closing handle 0x%x\n", GetLastError()); }; } /** * @brief Create a thread for pending buffers * * @param Data * @return DWORD Device Handle */ DWORD WINAPI IrpBasedBufferThread(void * data) { // // Do stuff. This will be the first function called on the new // thread. When this function returns, the thread goes away. See // MSDN for more details. Test Irp Based Notifications // ReadIrpBasedBuffer(); return 0; } /** * @brief Adjust kernel debug privilege * * @return BOOLEAN return TRUE if it was successful or FALSE if there */ BOOLEAN SetDebugPrivilege() { BOOL Status; HANDLE Token; // // Check if we already adjusted the privilege // if (g_PrivilegesAlreadyAdjusted) { return TRUE; } // // Enable Debug privilege // Status = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &Token); if (!Status) { ShowMessages("err, OpenProcessToken failed (%x)\n", GetLastError()); return FALSE; } Status = SetPrivilege(Token, SE_DEBUG_NAME, TRUE); if (!Status) { CloseHandle(Token); return FALSE; } // // Indicate that the privilege is already adjusted // g_PrivilegesAlreadyAdjusted = TRUE; CloseHandle(Token); return TRUE; } /** * @brief Install KD (Kernel Debugger) driver * * @return INT return zero if it was successful or non-zero if there * was error */ INT HyperDbgInstallKdDriver() { // // The driver is not started yet so let us the install driver // First setup full path to driver name // // // If the user has not specified a custom driver location, then we // need to find the driver in the same directory as the executable // if (!g_UseCustomDriverLocation) { if (!SetupPathForFileName(KERNEL_DEBUGGER_DRIVER_NAME_AND_EXTENSION, g_DriverLocation, sizeof(g_DriverLocation), TRUE)) { return 1; } // // Use default driver name // strcpy_s(g_DriverName, KERNEL_DEBUGGER_DRIVER_NAME); } if (!ManageDriver(g_DriverName, g_DriverLocation, DRIVER_FUNC_INSTALL)) { ShowMessages("unable to install VMM driver\n"); // // Error - remove driver // ManageDriver(g_DriverName, g_DriverLocation, DRIVER_FUNC_REMOVE); return 1; } return 0; } /** * @brief Stop the driver * * @return int return zero if it was successful or non-zero if there * was error */ int HyperDbgStopDriver(LPCTSTR DriverName) { // // Unload the driver if loaded // if (g_DriverLocation[0] != (TCHAR)0 && ManageDriver(DriverName, g_DriverLocation, DRIVER_FUNC_STOP)) { return 0; } else { return 1; } } /** * @brief Stop VMM driver * * @return INT return zero if it was successful or non-zero if there * was error */ INT HyperDbgStopVmmDriver() { return HyperDbgStopDriver(g_DriverName); } /** * @brief Remove the driver * * @return int return zero if it was successful or non-zero if there * was error */ int HyperDbgUninstallDriver(LPCTSTR DriverName) { // // Unload the driver if loaded. Ignore any errors // if (g_DriverLocation[0] != (TCHAR)0 && ManageDriver(DriverName, g_DriverLocation, DRIVER_FUNC_REMOVE)) { return 0; } else { return 1; } } /** * @brief Remove the KD (Kernel Debugger) driver * * @return INT return zero if it was successful or non-zero if there * was error */ INT HyperDbgUninstallKdDriver() { return HyperDbgUninstallDriver(g_DriverName); } /** * @brief Initialize VMM module * * @return INT return zero if it was successful or non-zero if there * was error */ INT HyperDbgInitHyperTraceModule() { BOOL Status; DEBUGGER_INIT_HYPERTRACE_PACKET InitHyperTracePacket = {0}; AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnOne); // // Send IOCTL to initialize HyperTrace module // Status = DeviceIoControl(g_DeviceHandle, // Handle to device IOCTL_INIT_HYPERTRACE, // IO Control Code (IOCTL) &InitHyperTracePacket, // Input Buffer to driver. SIZEOF_DEBUGGER_INIT_HYPERTRACE_PACKET, // Length of input buffer in bytes. &InitHyperTracePacket, // Output Buffer from driver. SIZEOF_DEBUGGER_INIT_HYPERTRACE_PACKET, // Length of output buffer in bytes. NULL, // Bytes placed in buffer. NULL // synchronous call ); // // Check if the IOCTL was successful, if not show the error message and return // if (!Status) { ShowMessages("ioctl failed with code 0x%x\n", GetLastError()); return 1; } // // Check the kernel status // if (InitHyperTracePacket.KernelStatus != DEBUGGER_OPERATION_WAS_SUCCESSFUL) { ShowErrorMessage(InitHyperTracePacket.KernelStatus); return 1; } return 0; } /** * @brief Initialize VMM module * * @return INT return zero if it was successful or non-zero if there * was error */ INT HyperDbgInitVmmModule() { BOOL Status; DEBUGGER_INIT_VMM_PACKET InitVmmPacket = {0}; AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnOne); // // Create event to show if the kd module is loaded or not // g_IsDriverLoadedSuccessfully = CreateEvent(NULL, FALSE, FALSE, NULL); // // Send IOCTL to initialize VMM module // Status = DeviceIoControl(g_DeviceHandle, // Handle to device IOCTL_INIT_VMM, // IO Control Code (IOCTL) &InitVmmPacket, // Input Buffer to driver. SIZEOF_DEBUGGER_INIT_VMM_PACKET, // Length of input buffer in bytes. &InitVmmPacket, // Output Buffer from driver. SIZEOF_DEBUGGER_INIT_VMM_PACKET, // Length of output buffer in bytes. NULL, // Bytes placed in buffer. NULL // synchronous call ); // // check if the IOCTL was successful, if not show the error message and return // if (!Status) { ShowMessages("ioctl failed with code 0x%x\n", GetLastError()); CloseHandle(g_IsDriverLoadedSuccessfully); return 1; } // // Check the kernel status for early errors (e.g., HyperTrace already loaded) // if (InitVmmPacket.KernelStatus != DEBUGGER_OPERATION_WAS_SUCCESSFUL && InitVmmPacket.KernelStatus != 0) { ShowErrorMessage(InitVmmPacket.KernelStatus); CloseHandle(g_IsDriverLoadedSuccessfully); return 1; } // // We wait for the first message from the kernel debugger to continue // WaitForSingleObject( g_IsDriverLoadedSuccessfully, INFINITE); // // No need to handle anymore // CloseHandle(g_IsDriverLoadedSuccessfully); // // VMM module is initialized at this point // return 0; } /** * @brief Create handle from KD (HyperKD) module * * @return INT return zero if it was successful or non-zero if there * was error */ INT HyperDbgCreateHandleFromKdModule() { DWORD ErrorNum; DWORD ThreadId; if (g_DeviceHandle) { ShowMessages("handle of the driver found, if you use the 'load' command before, please " "unload it using the 'unload' command\n"); return 1; } // // Make sure that this variable is false, because it might be set to // true as the result of a previous load // g_IsVmxOffProcessStart = FALSE; // // Init entering vmx // g_DeviceHandle = CreateFileA( "\\\\.\\HyperDbgDebuggerDevice", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, /// lpSecurityAttirbutes OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); /// lpTemplateFile if (g_DeviceHandle == INVALID_HANDLE_VALUE) { ErrorNum = GetLastError(); if (ErrorNum == ERROR_ACCESS_DENIED) { ShowMessages("err, access denied\nare you sure you have administrator " "rights?\n"); } else if (ErrorNum == ERROR_GEN_FAILURE) { ShowMessages("err, a device attached to the system is not functioning\n" "vmx feature might be disabled from BIOS or VBS/HVCI is active\n"); } else { ShowMessages("err, CreateFile failed (%x)\n", ErrorNum); } g_DeviceHandle = NULL; return 1; } // // Initialize the list of events // InitializeListHead(&g_EventTrace); #if !UseDbgPrintInsteadOfUsermodeMessageTracking HANDLE Thread = CreateThread(NULL, 0, IrpBasedBufferThread, NULL, 0, &ThreadId); // if (Thread) // { // ShowMessages("thread Created successfully\n"); // } #endif return 0; } /** * @brief Unload VMM driver * * @return INT return zero if it was successful or non-zero if there * was error */ INT HyperDbgUnloadVmm() { BOOL Status; AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnOne); ShowMessages("start terminating...\n"); // // Uninitialize the user debugger if it's initialized // UdUninitializeUserDebugger(); // // Send IOCTL to mark complete all IRP Pending // Status = DeviceIoControl(g_DeviceHandle, // Handle to device IOCTL_TERMINATE_VMX, // IO Control Code (IOCTL) NULL, // Input Buffer to driver. 0, // Length of input buffer in bytes. (x 2 is bcuz // as the driver is x64 and has 64 bit values) NULL, // Output Buffer from driver. 0, // Length of output buffer in bytes. NULL, // Bytes placed in buffer. NULL // synchronous call ); // // wait to make sure we don't use an invalid handle in another Ioctl // if (!Status) { ShowMessages("ioctl failed with code 0x%x\n", GetLastError()); return 1; } // // Send IOCTL to mark complete all IRP Pending // Status = DeviceIoControl( g_DeviceHandle, // Handle to device IOCTL_RETURN_IRP_PENDING_PACKETS_AND_DISALLOW_IOCTL, // IO // Control // code NULL, // Input Buffer to driver. 0, // Length of input buffer in bytes. (x 2 is bcuz as the // driver is x64 and has 64 bit values) NULL, // Output Buffer from driver. 0, // Length of output buffer in bytes. NULL, // Bytes placed in buffer. NULL // synchronous call ); // // wait to make sure we don't use an invalid handle in another Ioctl // if (!Status) { ShowMessages("ioctl failed with code 0x%x\n", GetLastError()); return 1; } // // Indicate that the finish process start or not // g_IsVmxOffProcessStart = TRUE; Sleep(1000); // Wait so next thread can return from IRP Pending // // Send IRP_MJ_CLOSE to driver to terminate Vmxs // if (!CloseHandle(g_DeviceHandle)) { ShowMessages("err, closing handle 0x%x\n", GetLastError()); return 1; }; // // Null the handle to indicate that the driver's device is not ready // to use // g_DeviceHandle = NULL; // // Debugger module is not loaded anymore // g_IsDebuggerModulesLoaded = FALSE; // // Check if we found an already built symbol table // SymbolDeleteSymTable(); ShowMessages("you're not on HyperDbg's hypervisor anymore!\n"); return 0; } /** * @brief load kd module * * @return int return zero if it was successful or non-zero if there */ INT HyperDbgLoadKdModule() { // // Check if the module is already loaded, if that's the case, we don't // need to handle anymore // if (g_IsDebuggerModulesLoaded) { // // Return zero to indicate that the module is loaded successfully, // and we no need to re-load it anymore // return 0; } if (HyperDbgCreateHandleFromKdModule() == 1) { // // No need to handle anymore // return 1; } // // KD module is loaded at this point // // // If we reach here so the module are loaded // g_IsDebuggerModulesLoaded = TRUE; return 0; } /** * @brief Get the vendor of the current processor * * @return GENERIC_PROCESSOR_VENDOR the vendor of the processor */ GENERIC_PROCESSOR_VENDOR HyperDbgGetProcessorVendor() { char CpuId[13] = {0}; // // Read the vendor string // CpuReadVendorString(CpuId); ShowMessages("current processor vendor is : %s\n", CpuId); if (strcmp(CpuId, "GenuineIntel") == 0) { return GENERIC_PROCESSOR_VENDOR_INTEL; } else if (strcmp(CpuId, "AuthenticAMD") == 0) { return GENERIC_PROCESSOR_VENDOR_AMD; } else { return GENERIC_PROCESSOR_VENDOR_OTHERS; } } /** * @brief load vmm module * * @return int return zero if it was successful or non-zero if there */ INT HyperDbgLoadVmmModule() { // // Enable Debug privilege to the current token // if (!SetDebugPrivilege()) { ShowMessages("err, couldn't set debug privilege\n"); return 1; } // // Check if the processor is a genuine Intel processor (required for VT-x) // if (HyperDbgGetProcessorVendor() != GENERIC_PROCESSOR_VENDOR_INTEL) { ShowMessages("err, this program is not designed to run in a non-VT-x " "environment. It needs an Intel processor.\n"); return 1; } ShowMessages("virtualization technology is vt-x\n"); if (VmxSupportDetection()) { ShowMessages("vmx operation is supported by your processor\n"); } else { #ifdef HYPERDBG_ENV_WINDOWS ShowMessages("vmx operation is not supported by your processor " "(if you are using an Intel processor, it might be because VBS is not disabled!)\n"); #endif return 1; } // // Load the KD module and create handle to it // if (HyperDbgLoadKdModule() == 1) { return 1; } // // Initialize VMM module // if (HyperDbgInitVmmModule() == 1) { ShowMessages("err, initializing VMM module\n"); return 1; } ShowMessages("vmm module is running...\n"); return 0; } /** * @brief load hypertrace module * * @return int return zero if it was successful or non-zero if there * was error */ INT HyperDbgLoadHyperTraceModule() { // // Enable Debug privilege to the current token // if (!SetDebugPrivilege()) { ShowMessages("err, couldn't set debug privilege\n"); return 1; } // // Check if the processor is a genuine Intel processor (required for HyperTrace) // if (HyperDbgGetProcessorVendor() != GENERIC_PROCESSOR_VENDOR_INTEL) { ShowMessages("err, this program is not designed to run in a non-Intel " "environment as it needs Intel PT (Processor Trace) and Intel LBR " "(Last Branch Record). It needs an Intel processor.\n"); return 1; } // // Load the KD module and create handle to it // if (HyperDbgLoadKdModule() == 1) { return 1; } // // Initialize HyperTrace module // if (HyperDbgInitHyperTraceModule() == 1) { ShowMessages("err, initializing HyperTrace module\n"); return 1; } ShowMessages("hypertrace module is running...\n"); return 0; }