HyperDbg/hyperdbg/libhyperdbg/code/app/libhyperdbg.cpp

888 lines
24 KiB
C++
Raw Normal View History

2020-04-11 08:27:51 -07:00
/**
2024-06-24 17:26:03 +09:00
* @file libhyperdbg.cpp
2022-01-18 22:38:56 +03:30
* @author Sina Karvandi (sina@hyperdbg.org)
2020-04-11 10:28:37 -07:00
* @brief Main interface to connect applications to driver
2020-04-11 08:27:51 -07:00
* @details
* @version 0.1
* @date 2020-04-11
*
2020-04-11 08:27:51 -07:00
* @copyright This project is released under the GNU Public License v3.
*
2020-04-11 08:27:51 -07:00
*/
#include "pch.h"
2020-07-13 14:27:04 -07:00
2020-05-27 12:09:57 -07:00
using namespace std;
2020-03-26 11:02:50 -07:00
2020-04-27 10:44:15 -07:00
//
// Global Variables
//
2023-03-22 17:45:52 +09:00
extern HANDLE g_DeviceHandle;
extern HANDLE g_IsDriverLoadedSuccessfully;
extern BOOLEAN g_IsVmxOffProcessStart;
extern PVOID g_MessageHandler;
extern PVOID g_MessageHandlerSharedBuffer;
2023-03-22 17:45:52 +09:00
extern TCHAR g_DriverLocation[MAX_PATH];
extern TCHAR g_DriverName[MAX_PATH];
2024-06-28 20:56:17 +09:00
extern BOOLEAN g_UseCustomDriverLocation;
2020-05-27 12:09:57 -07:00
extern LIST_ENTRY g_EventTrace;
2023-03-22 17:45:52 +09:00
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 LIST_ENTRY g_OutputSources;
2020-04-20 12:03:21 -07:00
2020-04-11 08:27:51 -07:00
/**
* @brief Set the function callback that will be called if any message
* needs to be shown
*
* @param Handler Function that handles the messages
2024-07-06 22:46:57 +09:00
* @return VOID
2020-04-11 08:27:51 -07:00
*/
2023-03-22 17:45:52 +09:00
VOID
SetTextMessageCallback(PVOID Handler)
2021-03-22 18:19:39 +04:30
{
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;
2020-03-26 11:02:50 -07:00
}
2024-07-18 12:51:53 +09:00
/**
* @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;
2024-07-18 12:51:53 +09:00
}
2020-04-11 20:43:08 -07:00
/**
* @brief Show messages
2020-04-11 20:43:08 -07:00
*
2020-08-28 04:03:12 -07:00
* @param Fmt format string message
2024-07-06 22:46:57 +09:00
* @param ... arguments
* @return VOID
2020-04-11 20:43:08 -07:00
*/
2023-03-22 17:45:52 +09:00
VOID
ShowMessages(const char * Fmt, ...)
2021-03-22 18:19:39 +04:30
{
va_list ArgList;
va_list Args;
2023-03-22 17:45:52 +09:00
char TempMessage[COMMUNICATION_BUFFER_SIZE + TCP_END_OF_BUFFER_CHARS_COUNT] = {0};
2021-03-22 18:19:39 +04:30
2023-03-22 17:45:52 +09:00
if (g_MessageHandler == NULL && !g_IsConnectedToRemoteDebugger && !g_IsSerialConnectedToRemoteDebugger)
{
2021-03-22 18:19:39 +04:30
va_start(Args, Fmt);
2021-03-22 18:19:39 +04:30
vprintf(Fmt, Args);
2021-03-22 18:19:39 +04:30
va_end(Args);
2023-03-22 17:45:52 +09:00
if (!g_LogOpened)
{
return;
2021-03-22 18:19:39 +04:30
}
2020-08-28 04:03:12 -07:00
}
2021-03-22 18:19:39 +04:30
va_start(ArgList, Fmt);
int SprintfResult = vsprintf_s(TempMessage, Fmt, ArgList);
2021-03-22 18:19:39 +04:30
va_end(ArgList);
2020-08-28 04:03:12 -07:00
if (SprintfResult != -1)
2023-03-22 17:45:52 +09:00
{
if (g_IsConnectedToRemoteDebugger)
{
2021-03-22 18:19:39 +04:30
//
// 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);
2023-03-22 17:45:52 +09:00
}
else if (g_IsSerialConnectedToRemoteDebugger)
{
KdSendUsermodePrints(TempMessage, SprintfResult);
2021-03-22 18:19:39 +04:30
}
2023-03-22 17:45:52 +09:00
if (g_LogOpened)
{
2021-03-22 18:19:39 +04:30
//
// .logopen command executed
//
LogopenSaveToFile(TempMessage);
}
if (g_MessageHandler != NULL)
2023-03-22 17:45:52 +09:00
{
2021-03-22 18:19:39 +04:30
//
// There is another handler
//
if (g_MessageHandlerSharedBuffer == NULL)
{
((SendMessageWithParamCallback)g_MessageHandler)(TempMessage);
}
else
{
memcpy(g_MessageHandlerSharedBuffer, TempMessage, strlen(TempMessage) + 1);
((SendMessageWWithSharedBufferCallback)g_MessageHandler)();
}
}
2020-04-27 10:44:15 -07:00
}
2020-03-26 11:02:50 -07:00
}
2020-04-11 08:27:51 -07:00
/**
2020-04-11 10:28:37 -07:00
* @brief Read kernel buffers using IRP Pending
*
2020-04-11 10:28:37 -07:00
* @param Device Driver handle
2024-07-06 22:46:57 +09:00
* @return VOID
2020-04-11 08:27:51 -07:00
*/
2024-07-06 22:46:57 +09:00
VOID
2023-03-22 17:45:52 +09:00
ReadIrpBasedBuffer()
2021-03-22 18:19:39 +04:30
{
2023-03-22 17:45:52 +09:00
BOOL Status;
ULONG ReturnedLength;
2021-03-22 18:19:39 +04:30
REGISTER_NOTIFY_BUFFER RegisterEvent;
2023-03-22 17:45:52 +09:00
UINT32 OperationCode;
DWORD ErrorNum;
HANDLE Handle;
2021-03-22 18:19:39 +04:30
RegisterEvent.hEvent = NULL;
2023-03-22 17:45:52 +09:00
RegisterEvent.Type = IRP_BASED;
2020-04-27 10:44:15 -07:00
2021-03-22 18:19:39 +04:30
//
// 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(
2023-01-29 22:51:20 +09:00
"\\\\.\\HyperDbgDebuggerDevice",
2021-03-22 18:19:39 +04:30
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, /// lpSecurityAttirbutes
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL); /// lpTemplateFile
2023-03-22 17:45:52 +09:00
if (Handle == INVALID_HANDLE_VALUE)
{
2021-03-22 18:19:39 +04:30
ErrorNum = GetLastError();
2023-02-02 19:41:32 +09:00
2023-03-22 17:45:52 +09:00
if (ErrorNum == ERROR_ACCESS_DENIED)
{
2021-10-16 20:33:13 +03:30
ShowMessages("err, access denied\nare you sure you have administrator "
2021-03-22 18:19:39 +04:30
"rights?\n");
2023-03-22 17:45:52 +09:00
}
else if (ErrorNum == ERROR_GEN_FAILURE)
{
2021-10-16 20:33:13 +03:30
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");
2023-03-22 17:45:52 +09:00
}
else
{
ShowMessages("err, CreateFile failed with (%x)\n", ErrorNum);
2020-07-25 03:32:04 -07:00
}
g_DeviceHandle = NULL;
2023-03-22 17:45:52 +09:00
Handle = NULL;
2021-03-22 18:19:39 +04:30
return;
}
2020-07-25 03:32:04 -07:00
2021-03-22 18:19:39 +04:30
//
2024-03-17 01:01:22 +09:00
// allocate buffer for transferring messages
2021-03-22 18:19:39 +04:30
//
2023-03-22 17:45:52 +09:00
char * OutputBuffer = (char *)malloc(UsermodeBufferSize);
2021-03-22 18:19:39 +04:30
2023-03-22 17:45:52 +09:00
try
{
while (TRUE)
{
if (!g_IsVmxOffProcessStart)
{
2021-03-22 18:19:39 +04:30
//
// Clear the buffer
//
ZeroMemory(OutputBuffer, UsermodeBufferSize);
2021-04-05 02:33:27 +04:30
Sleep(DefaultSpeedOfReadingKernelMessages); // we're not trying to eat all of the CPU ;)
2021-03-22 18:19:39 +04:30
Status = DeviceIoControl(
2023-03-22 17:45:52 +09:00
Handle, // Handle to device
IOCTL_REGISTER_EVENT, // IO Control Code (IOCTL)
2023-03-22 17:45:52 +09:00
&RegisterEvent, // Input Buffer to driver.
2023-02-01 22:01:46 +09:00
SIZEOF_REGISTER_EVENT * 2, // Length of input buffer in bytes. (x 2 is bcuz as the
// driver is x64 and has 64 bit values)
2023-03-22 17:45:52 +09:00
OutputBuffer, // Output Buffer from driver.
UsermodeBufferSize, // Length of output buffer in bytes.
&ReturnedLength, // Bytes placed in buffer.
NULL // synchronous call
2021-03-22 18:19:39 +04:30
);
2023-03-22 17:45:52 +09:00
if (!Status)
{
2021-03-22 18:19:39 +04:30
//
2024-03-17 01:01:22 +09:00
// Error occurred for second time, and we show the error message
2021-03-22 18:19:39 +04:30
//
2022-07-14 04:37:31 -07:00
// ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
2021-03-22 18:19:39 +04:30
//
2021-04-24 16:50:12 +04:30
// if we reach here, the packet is probably failed, it might
// be because of using flush command
//
2021-04-24 16:50:12 +04:30
continue;
}
2020-04-27 10:44:15 -07:00
//
// Compute the received buffer's operation code
//
2021-03-22 18:19:39 +04:30
OperationCode = 0;
memcpy(&OperationCode, OutputBuffer, sizeof(UINT32));
2020-04-27 10:44:15 -07:00
2021-03-22 18:19:39 +04:30
/*
ShowMessages("Returned Length : 0x%x \n", ReturnedLength);
ShowMessages("Operation Code : 0x%x \n", OperationCode);
*/
2020-04-27 10:44:15 -07:00
2023-03-22 17:45:52 +09:00
switch (OperationCode)
{
2021-03-22 18:19:39 +04:30
case OPERATION_LOG_NON_IMMEDIATE_MESSAGE:
2020-05-14 08:28:28 -07:00
2023-03-22 17:45:52 +09:00
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;
}
2021-03-22 18:19:39 +04:30
ShowMessages("%s", OutputBuffer + sizeof(UINT32));
2021-03-22 18:19:39 +04:30
break;
case OPERATION_LOG_INFO_MESSAGE:
2023-03-22 17:45:52 +09:00
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;
}
2021-03-22 18:19:39 +04:30
ShowMessages("%s", OutputBuffer + sizeof(UINT32));
2021-03-22 18:19:39 +04:30
break;
case OPERATION_LOG_ERROR_MESSAGE:
2023-03-22 17:45:52 +09:00
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;
}
2021-03-22 18:19:39 +04:30
ShowMessages("%s", OutputBuffer + sizeof(UINT32));
2021-03-22 18:19:39 +04:30
break;
case OPERATION_LOG_WARNING_MESSAGE:
2023-03-22 17:45:52 +09:00
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;
}
2021-03-22 18:19:39 +04:30
ShowMessages("%s", OutputBuffer + sizeof(UINT32));
2021-03-22 18:19:39 +04:30
break;
2020-04-27 10:44:15 -07:00
2021-03-22 18:19:39 +04:30
case OPERATION_COMMAND_FROM_DEBUGGER_CLOSE_AND_UNLOAD_VMM:
2021-03-22 18:19:39 +04:30
KdCloseConnection();
2021-03-22 18:19:39 +04:30
break;
2021-03-22 18:19:39 +04:30
case OPERATION_DEBUGGEE_USER_INPUT:
2023-03-22 17:45:52 +09:00
KdHandleUserInputInDebuggee((DEBUGGEE_USER_INPUT_PACKET *)(OutputBuffer + sizeof(UINT32)));
2021-03-22 18:19:39 +04:30
break;
2021-03-22 18:19:39 +04:30
case OPERATION_DEBUGGEE_REGISTER_EVENT:
2021-03-22 18:19:39 +04:30
KdRegisterEventInDebuggee(
(PDEBUGGER_GENERAL_EVENT_DETAIL)(OutputBuffer + sizeof(UINT32)),
ReturnedLength);
2021-03-22 18:19:39 +04:30
break;
2021-03-22 18:19:39 +04:30
case OPERATION_DEBUGGEE_ADD_ACTION_TO_EVENT:
2021-03-22 18:19:39 +04:30
KdAddActionToEventInDebuggee(
(PDEBUGGER_GENERAL_ACTION)(OutputBuffer + sizeof(UINT32)),
ReturnedLength);
2021-03-22 18:19:39 +04:30
break;
2021-03-22 18:19:39 +04:30
case OPERATION_DEBUGGEE_CLEAR_EVENTS:
2021-03-22 18:19:39 +04:30
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);
2021-03-22 18:19:39 +04:30
break;
2021-03-27 02:18:09 +04:30
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:
2021-09-27 01:01:25 +03:30
//
// Pause debugger after getting the results
//
KdReloadSymbolsInDebuggee(TRUE,
2023-03-22 17:45:52 +09:00
((PDEBUGGEE_SYMBOL_REQUEST_PACKET)(OutputBuffer + sizeof(UINT32)))->ProcessId);
break;
2022-01-12 18:52:34 +03:30
case OPERATION_NOTIFICATION_FROM_USER_DEBUGGER_PAUSE:
//
// handle pausing packet from user debugger
//
UdHandleUserDebuggerPausing(
(PDEBUGGEE_UD_PAUSED_PACKET)(OutputBuffer + sizeof(UINT32)));
break;
2021-03-22 18:19:39 +04:30
default:
2021-03-22 18:19:39 +04:30
//
// Check if there are available output sources
//
if (!g_OutputSourcesInitialized || !ForwardingCheckAndPerformEventForwarding(OperationCode,
OutputBuffer + sizeof(UINT32),
ReturnedLength - sizeof(UINT32) - 1))
2023-03-22 17:45:52 +09:00
{
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;
}
2021-03-22 18:19:39 +04:30
ShowMessages("%s", OutputBuffer + sizeof(UINT32));
}
break;
}
2023-03-22 17:45:52 +09:00
}
else
{
//
2021-03-22 18:19:39 +04:30
// the thread should not work anymore
//
2021-03-22 18:19:39 +04:30
free(OutputBuffer);
2021-08-06 18:31:14 +08:00
//
// closeHandle
//
2023-03-22 17:45:52 +09:00
if (!CloseHandle(Handle))
{
2021-08-06 18:31:14 +08:00
ShowMessages("err, closing handle 0x%x\n", GetLastError());
2023-02-02 19:41:32 +09:00
}
2021-08-06 18:31:14 +08:00
2021-03-22 18:19:39 +04:30
return;
}
2020-04-27 10:44:15 -07:00
}
2023-03-22 17:45:52 +09:00
}
catch (const std::exception &)
{
2024-03-17 01:01:22 +09:00
ShowMessages("err, exception occurred in creating handle or parsing buffer\n");
2021-03-22 18:19:39 +04:30
}
2023-02-02 19:41:32 +09:00
2021-03-22 18:19:39 +04:30
free(OutputBuffer);
2021-08-06 18:31:14 +08:00
//
// closeHandle
//
2023-03-22 17:45:52 +09:00
if (!CloseHandle(Handle))
{
2021-08-06 18:31:14 +08:00
ShowMessages("err, closing handle 0x%x\n", GetLastError());
};
2020-03-26 11:02:50 -07:00
}
2020-04-11 08:27:51 -07:00
/**
2020-04-11 10:28:37 -07:00
* @brief Create a thread for pending buffers
*
* @param Data
* @return DWORD Device Handle
2020-04-11 08:27:51 -07:00
*/
2021-03-22 18:19:39 +04:30
DWORD WINAPI
2023-03-22 17:45:52 +09:00
IrpBasedBufferThread(void * data)
2021-03-22 18:19:39 +04:30
{
//
// 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();
2020-04-27 10:44:15 -07:00
2021-03-22 18:19:39 +04:30
return 0;
2020-03-26 11:02:50 -07:00
}
2020-04-11 08:27:51 -07:00
/**
2022-07-15 14:52:07 -07:00
* @brief Install VMM driver
*
2024-06-24 19:07:06 +09:00
* @return INT return zero if it was successful or non-zero if there
* was error
2020-04-11 08:27:51 -07:00
*/
2024-06-24 19:07:06 +09:00
INT
2022-07-15 14:52:07 -07:00
HyperDbgInstallVmmDriver()
2021-03-22 18:19:39 +04:30
{
//
// The driver is not started yet so let us the install driver
// First setup full path to driver name
2021-03-22 18:19:39 +04:30
//
2020-04-27 10:44:15 -07:00
2024-06-28 20:56:17 +09:00
//
// 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)
2023-03-22 17:45:52 +09:00
{
2024-06-28 20:56:17 +09:00
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);
2021-03-22 18:19:39 +04:30
}
2020-04-27 10:44:15 -07:00
if (!ManageDriver(g_DriverName, g_DriverLocation, DRIVER_FUNC_INSTALL))
2023-03-22 17:45:52 +09:00
{
2023-02-02 12:48:15 +09:00
ShowMessages("unable to install VMM driver\n");
2020-04-27 10:44:15 -07:00
2021-03-22 18:19:39 +04:30
//
// Error - remove driver
2021-03-22 18:19:39 +04:30
//
ManageDriver(g_DriverName, g_DriverLocation, DRIVER_FUNC_REMOVE);
2020-04-27 10:44:15 -07:00
2021-03-22 18:19:39 +04:30
return 1;
}
2021-03-22 18:19:39 +04:30
return 0;
2020-04-02 09:18:10 -07:00
}
2020-04-11 08:27:51 -07:00
/**
* @brief Stop the driver
*
* @return int return zero if it was successful or non-zero if there
* was error
*/
2023-03-22 17:45:52 +09:00
int
HyperDbgStopDriver(LPCTSTR DriverName)
{
//
// Unload the driver if loaded
//
2023-03-22 17:45:52 +09:00
if (g_DriverLocation[0] != (TCHAR)0 && ManageDriver(DriverName, g_DriverLocation, DRIVER_FUNC_STOP))
{
return 0;
2023-03-22 17:45:52 +09:00
}
else
{
return 1;
}
}
/**
2022-07-14 04:37:31 -07:00
* @brief Stop VMM driver
*
2024-06-24 19:07:06 +09:00
* @return INT return zero if it was successful or non-zero if there
* was error
2020-04-11 08:27:51 -07:00
*/
2024-06-24 19:07:06 +09:00
INT
2022-07-15 14:52:07 -07:00
HyperDbgStopVmmDriver()
2022-07-14 04:37:31 -07:00
{
return HyperDbgStopDriver(g_DriverName);
2022-07-14 04:37:31 -07:00
}
/**
* @brief Remove the driver
*
* @return int return zero if it was successful or non-zero if there
* was error
*/
2023-03-22 17:45:52 +09:00
int
HyperDbgUninstallDriver(LPCTSTR DriverName)
2021-03-22 18:19:39 +04:30
{
//
// Unload the driver if loaded. Ignore any errors
2021-03-22 18:19:39 +04:30
//
2023-03-22 17:45:52 +09:00
if (g_DriverLocation[0] != (TCHAR)0 && ManageDriver(DriverName, g_DriverLocation, DRIVER_FUNC_REMOVE))
{
return 0;
2023-03-22 17:45:52 +09:00
}
else
{
return 1;
2021-03-22 18:19:39 +04:30
}
2020-04-02 09:18:10 -07:00
}
2020-03-28 02:34:59 -07:00
2022-07-14 04:37:31 -07:00
/**
* @brief Remove the VMM driver
*
2024-06-24 19:07:06 +09:00
* @return INT return zero if it was successful or non-zero if there
2022-07-14 04:37:31 -07:00
* was error
*/
2024-06-24 19:07:06 +09:00
INT
2022-07-15 14:52:07 -07:00
HyperDbgUninstallVmmDriver()
2022-07-14 04:37:31 -07:00
{
return HyperDbgUninstallDriver(g_DriverName);
2022-07-14 04:37:31 -07:00
}
2020-04-11 10:28:37 -07:00
/**
2024-07-03 19:16:14 +09:00
* @brief Create handle from VMM module
*
2024-06-24 19:07:06 +09:00
* @return INT return zero if it was successful or non-zero if there
* was error
2020-04-11 10:28:37 -07:00
*/
2024-06-24 19:07:06 +09:00
INT
2024-07-03 19:16:14 +09:00
HyperDbgCreateHandleFromVmmModule()
2021-03-22 18:19:39 +04:30
{
2023-09-12 11:45:50 +09:00
DWORD ErrorNum;
DWORD ThreadId;
2021-03-22 18:19:39 +04:30
2023-03-22 17:45:52 +09:00
if (g_DeviceHandle)
{
2021-04-19 02:54:38 +04:30
ShowMessages("handle of the driver found, if you use 'load' before, please "
"unload it using 'unload'\n");
2021-03-22 18:19:39 +04:30
return 1;
2020-04-27 10:44:15 -07:00
}
//
// 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
//
2021-03-22 18:19:39 +04:30
g_DeviceHandle = CreateFileA(
2023-01-29 22:51:20 +09:00
"\\\\.\\HyperDbgDebuggerDevice",
2021-03-22 18:19:39 +04:30
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, /// lpSecurityAttirbutes
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL); /// lpTemplateFile
2023-03-22 17:45:52 +09:00
if (g_DeviceHandle == INVALID_HANDLE_VALUE)
{
2021-03-22 18:19:39 +04:30
ErrorNum = GetLastError();
2023-03-22 17:45:52 +09:00
if (ErrorNum == ERROR_ACCESS_DENIED)
{
2021-10-16 20:33:13 +03:30
ShowMessages("err, access denied\nare you sure you have administrator "
2021-03-22 18:19:39 +04:30
"rights?\n");
2023-03-22 17:45:52 +09:00
}
else if (ErrorNum == ERROR_GEN_FAILURE)
{
2021-10-16 20:33:13 +03:30
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");
2023-03-22 17:45:52 +09:00
}
else
{
ShowMessages("err, CreateFile failed (%x)\n", ErrorNum);
2021-03-22 18:19:39 +04:30
}
g_DeviceHandle = NULL;
2021-03-22 18:19:39 +04:30
return 1;
}
//
// Initialize the list of events
//
InitializeListHead(&g_EventTrace);
2020-04-27 10:44:15 -07:00
#if !UseDbgPrintInsteadOfUsermodeMessageTracking
2023-02-02 12:48:15 +09:00
HANDLE Thread = CreateThread(NULL, 0, IrpBasedBufferThread, NULL, 0, &ThreadId);
2021-03-28 21:17:55 +04:30
// if (Thread)
// {
// ShowMessages("thread Created successfully\n");
// }
2021-03-28 21:17:55 +04:30
2020-03-26 11:02:50 -07:00
#endif
2021-03-22 18:19:39 +04:30
return 0;
2020-03-29 04:14:18 -07:00
}
2020-03-28 02:34:59 -07:00
2020-04-11 08:27:51 -07:00
/**
2022-07-14 04:37:31 -07:00
* @brief Unload VMM driver
*
2024-06-24 19:07:06 +09:00
* @return INT return zero if it was successful or non-zero if there
* was error
2020-04-11 08:27:51 -07:00
*/
2024-06-24 19:07:06 +09:00
INT
2022-07-15 14:52:07 -07:00
HyperDbgUnloadVmm()
2021-03-22 18:19:39 +04:30
{
BOOL Status;
AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnOne);
2021-03-22 18:19:39 +04:30
ShowMessages("start terminating...\n");
//
// Uninitialize the user debugger if it's initialized
//
UdUninitializeUserDebugger();
2021-03-22 18:19:39 +04:30
//
// Send IOCTL to mark complete all IRP Pending
//
2023-03-22 17:45:52 +09:00
Status = DeviceIoControl(g_DeviceHandle, // Handle to device
IOCTL_TERMINATE_VMX, // IO Control Code (IOCTL)
2023-03-22 17:45:52 +09:00
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
2021-03-22 18:19:39 +04:30
);
//
// wait to make sure we don't use an invalid handle in another Ioctl
//
2023-03-22 17:45:52 +09:00
if (!Status)
{
2021-03-22 18:19:39 +04:30
ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
return 1;
2021-03-22 18:19:39 +04:30
}
//
// Send IOCTL to mark complete all IRP Pending
//
Status = DeviceIoControl(
2023-03-22 17:45:52 +09:00
g_DeviceHandle, // Handle to device
2021-03-22 18:19:39 +04:30
IOCTL_RETURN_IRP_PENDING_PACKETS_AND_DISALLOW_IOCTL, // IO
// Control
// code
2023-03-22 17:45:52 +09:00
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
2021-03-22 18:19:39 +04:30
);
//
// wait to make sure we don't use an invalid handle in another Ioctl
//
2023-03-22 17:45:52 +09:00
if (!Status)
{
2021-03-22 18:19:39 +04:30
ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
return 1;
2021-03-22 18:19:39 +04:30
}
//
// 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
//
2023-03-22 17:45:52 +09:00
if (!CloseHandle(g_DeviceHandle))
{
2021-04-05 19:35:58 +04:30
ShowMessages("err, closing handle 0x%x\n", GetLastError());
return 1;
2021-03-22 18:19:39 +04:30
};
//
// 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;
2022-05-29 03:32:04 +04:30
//
// Check if we found an already built symbol table
//
SymbolDeleteSymTable();
2021-04-19 02:54:38 +04:30
ShowMessages("you're not on HyperDbg's hypervisor anymore!\n");
return 0;
}
2024-07-03 19:16:14 +09:00
/**
* @brief load vmm module
*
* @return int return zero if it was successful or non-zero if there
*/
INT
HyperDbgLoadVmmModule()
{
BOOL Status;
HANDLE hToken;
char CpuId[13] = {0};
//
// Enable Debug privilege
//
Status = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
if (!Status)
{
ShowMessages("err, OpenProcessToken failed (%x)\n", GetLastError());
return 1;
}
Status = SetPrivilege(hToken, SE_DEBUG_NAME, TRUE);
if (!Status)
{
CloseHandle(hToken);
return 1;
}
//
// Read the vendor string
//
CpuReadVendorString(CpuId);
ShowMessages("current processor vendor is : %s\n", CpuId);
if (strcmp(CpuId, "GenuineIntel") == 0)
{
ShowMessages("virtualization technology is vt-x\n");
}
else
{
ShowMessages("this program is not designed to run in a non-VT-x "
"environment !\n");
return 1;
}
if (VmxSupportDetection())
{
ShowMessages("vmx operation is supported by your processor\n");
}
else
{
ShowMessages("vmx operation is not supported by your processor\n");
return 1;
}
//
// Create event to show if the hypervisor is loaded or not
//
g_IsDriverLoadedSuccessfully = CreateEvent(NULL, FALSE, FALSE, NULL);
if (HyperDbgCreateHandleFromVmmModule() == 1)
{
//
// No need to handle anymore
//
CloseHandle(g_IsDriverLoadedSuccessfully);
return 1;
}
//
// Vmm module (Hypervisor) is loaded
//
//
// We wait for the first message from the kernel debugger to continue
//
WaitForSingleObject(
g_IsDriverLoadedSuccessfully,
INFINITE);
//
// No need to handle anymore
//
CloseHandle(g_IsDriverLoadedSuccessfully);
//
// If we reach here so the module are loaded
//
g_IsDebuggerModulesLoaded = TRUE;
ShowMessages("vmm module is running...\n");
return 0;
}