diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f9ac26a..8a0909b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,8 +25,10 @@ New release of the HyperDbg Debugger. - Exported SDK API for detecting CPU vendors - Initial codes for the HyperTrace project by using Intel Processor Trace (PT), thanks to [@masoudrahimi01](https://github.com/masoudrahimi01) ([link](https://github.com/HyperDbg/HyperDbg/pull/589)) - Exported SDK APIs for loading the 'kd' and the 'trace' modules +- Exported SDK APIs for starting (installing) the 'kd' driver - Added tests for checking PE parser in 'hyperdbg-test' project - Added example for loading HyperDbg in VMI mode directly from libhyperdbg +- Fix action cleanup list removal in debugger events ([link](https://github.com/HyperDbg/HyperDbg/pull/601)) ### Changed - Fix the problem of not applying the EAX index in the CPUID event extension command ([link](https://docs.hyperdbg.org/commands/extension-commands/cpuid#parameters)) @@ -42,6 +44,7 @@ New release of the HyperDbg Debugger. - Fix synchronous debugger device IOCTL handles thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/595)) - PE parser ('.pe' command) now supports richer DOS/NT/COFF/optional-header output, section bounds checking, data directory reporting, import/export parsing, TLS/debug/PDB/load-config metadata, overlay reporting, and malformed metadata warnings thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/598))([link](https://docs.hyperdbg.org/commands/meta-commands/.pe)) - Building the script engine module on Linux (GCC) thanks to [@maxraulea](https://github.com/maxraulea) ([link](https://github.com/HyperDbg/HyperDbg/pull/596)) +- Pool manager moved from 'hyperhv' to 'hyperkd' ## [0.18.1.0] - 2026-04-09 New release of the HyperDbg Debugger. diff --git a/examples/kernel/hyperdbg_driver/code/driver/Driver.c b/examples/kernel/hyperdbg_driver/code/driver/Driver.c index 9a44e862..b4092073 100644 --- a/examples/kernel/hyperdbg_driver/code/driver/Driver.c +++ b/examples/kernel/hyperdbg_driver/code/driver/Driver.c @@ -106,7 +106,7 @@ DrvUnload(PDRIVER_OBJECT DriverObject) // // Unloading VMM and Debugger // - LoaderUninitializeLogTracer(); + LoaderUninitLogTracer(); } /** diff --git a/examples/kernel/hyperdbg_driver/code/driver/Ioctl.c b/examples/kernel/hyperdbg_driver/code/driver/Ioctl.c index ceb117c0..679a8aef 100644 --- a/examples/kernel/hyperdbg_driver/code/driver/Ioctl.c +++ b/examples/kernel/hyperdbg_driver/code/driver/Ioctl.c @@ -36,7 +36,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // PoolManagerCheckAndPerformAllocationAndDeallocation(); - if (g_AllowIoctlFromUsermode) + if (g_VmmInitialized) { IrpStack = IoGetCurrentIrpStackLocation(Irp); diff --git a/examples/kernel/hyperdbg_driver/code/driver/Loader.c b/examples/kernel/hyperdbg_driver/code/driver/Loader.c index 4eaae9f8..7a2ed944 100644 --- a/examples/kernel/hyperdbg_driver/code/driver/Loader.c +++ b/examples/kernel/hyperdbg_driver/code/driver/Loader.c @@ -24,7 +24,7 @@ LoaderInitVmmAndReversingMachine() // // Allow to server IOCTL // - g_AllowIoctlFromUsermode = TRUE; + g_VmmInitialized = TRUE; // // Fill the callbacks for the message tracer @@ -90,7 +90,7 @@ LoaderInitVmmAndReversingMachine() // // Not loaded // - g_AllowIoctlFromUsermode = FALSE; + g_VmmInitialized = FALSE; return FALSE; } @@ -101,7 +101,7 @@ LoaderInitVmmAndReversingMachine() * @return VOID */ VOID -LoaderUninitializeLogTracer() +LoaderUninitLogTracer() { LogDebugInfo("Unloading HyperDbg's debugger...\n"); diff --git a/examples/kernel/hyperdbg_driver/header/driver/Loader.h b/examples/kernel/hyperdbg_driver/header/driver/Loader.h index c12b0d12..7ead903c 100644 --- a/examples/kernel/hyperdbg_driver/header/driver/Loader.h +++ b/examples/kernel/hyperdbg_driver/header/driver/Loader.h @@ -17,7 +17,7 @@ ////////////////////////////////////////////////// VOID -LoaderUninitializeLogTracer(); +LoaderUninitLogTracer(); BOOLEAN LoaderInitVmmAndReversingMachine(); diff --git a/examples/kernel/hyperdbg_driver/header/misc/Global.h b/examples/kernel/hyperdbg_driver/header/misc/Global.h index 7113ff2f..db81c9d8 100644 --- a/examples/kernel/hyperdbg_driver/header/misc/Global.h +++ b/examples/kernel/hyperdbg_driver/header/misc/Global.h @@ -18,7 +18,7 @@ BOOLEAN g_HandleInUse; /** - * @brief Determines whether the clients are allowed to send IOCTL to the drive or not + * @brief Shows whether the VMM is initialized or not * */ -BOOLEAN g_AllowIoctlFromUsermode; +BOOLEAN g_VmmInitialized; \ No newline at end of file diff --git a/hyperdbg/hyperhv/code/hooks/ept-hook/EptHook.c b/hyperdbg/hyperhv/code/hooks/ept-hook/EptHook.c index 561212b7..dc2b4fd8 100644 --- a/hyperdbg/hyperhv/code/hooks/ept-hook/EptHook.c +++ b/hyperdbg/hyperhv/code/hooks/ept-hook/EptHook.c @@ -80,22 +80,22 @@ EptHookReservePreallocatedPoolsForEptHooks(UINT32 Count) // Request pages to be allocated for converting 2MB to 4KB pages // Each core needs its own splitting page-tables // - PoolManagerRequestAllocation(sizeof(VMM_EPT_DYNAMIC_SPLIT), Count * ProcessorsCount, SPLIT_2MB_PAGING_TO_4KB_PAGE); + PoolManagerCallbackRequestAllocation(sizeof(VMM_EPT_DYNAMIC_SPLIT), Count * ProcessorsCount, SPLIT_2MB_PAGING_TO_4KB_PAGE); // // Request pages to be allocated for paged hook details // - PoolManagerRequestAllocation(sizeof(EPT_HOOKED_PAGE_DETAIL), Count, TRACKING_HOOKED_PAGES); + PoolManagerCallbackRequestAllocation(sizeof(EPT_HOOKED_PAGE_DETAIL), Count, TRACKING_HOOKED_PAGES); // // Request pages to be allocated for Trampoline of Executable hooked pages // - PoolManagerRequestAllocation(MAX_EXEC_TRAMPOLINE_SIZE, Count, EXEC_TRAMPOLINE); + PoolManagerCallbackRequestAllocation(MAX_EXEC_TRAMPOLINE_SIZE, Count, EXEC_TRAMPOLINE); // // Request pages to be allocated for detour hooked pages details // - PoolManagerRequestAllocation(sizeof(HIDDEN_HOOKS_DETOUR_DETAILS), Count, DETOUR_HOOK_DETAILS); + PoolManagerCallbackRequestAllocation(sizeof(HIDDEN_HOOKS_DETOUR_DETAILS), Count, DETOUR_HOOK_DETAILS); } /** @@ -120,16 +120,16 @@ EptHookAllocateExtraHookingPagesForMemoryMonitorsAndExecEptHooks(UINT32 Count) // Request pages to be allocated for converting 2MB to 4KB pages // Each core needs its own splitting page-tables // - PoolManagerRequestAllocation(sizeof(VMM_EPT_DYNAMIC_SPLIT), - Count * ProcessorsCount, - SPLIT_2MB_PAGING_TO_4KB_PAGE); + PoolManagerCallbackRequestAllocation(sizeof(VMM_EPT_DYNAMIC_SPLIT), + Count * ProcessorsCount, + SPLIT_2MB_PAGING_TO_4KB_PAGE); // // Request pages to be allocated for paged hook details // - PoolManagerRequestAllocation(sizeof(EPT_HOOKED_PAGE_DETAIL), - Count, - TRACKING_HOOKED_PAGES); + PoolManagerCallbackRequestAllocation(sizeof(EPT_HOOKED_PAGE_DETAIL), + Count, + TRACKING_HOOKED_PAGES); } /** @@ -199,7 +199,7 @@ EptHookCreateHookPage(_Inout_ VIRTUAL_MACHINE_STATE * VCpu, // // Save the detail of hooked page to keep track of it // - HookedPage = (EPT_HOOKED_PAGE_DETAIL *)PoolManagerRequestPool(TRACKING_HOOKED_PAGES, TRUE, sizeof(EPT_HOOKED_PAGE_DETAIL)); + HookedPage = (EPT_HOOKED_PAGE_DETAIL *)PoolManagerCallbackRequestPool(TRACKING_HOOKED_PAGES, TRUE, sizeof(EPT_HOOKED_PAGE_DETAIL)); if (!HookedPage) { @@ -281,7 +281,7 @@ EptHookCreateHookPage(_Inout_ VIRTUAL_MACHINE_STATE * VCpu, // if (!EptSplitLargePage(g_GuestState[i].EptPageTable, TRUE, PhysicalBaseAddress)) { - PoolManagerFreePool((UINT64)HookedPage); + PoolManagerCallbackFreePool((UINT64)HookedPage); // // Here also other previous pools should be specified, but we forget it for now @@ -302,7 +302,7 @@ EptHookCreateHookPage(_Inout_ VIRTUAL_MACHINE_STATE * VCpu, // if (!TargetPage) { - PoolManagerFreePool((UINT64)HookedPage); + PoolManagerCallbackFreePool((UINT64)HookedPage); // // Here also other previous pools should be specified, but we forget it for now @@ -907,7 +907,7 @@ EptHookInstructionMemory(PEPT_HOOKED_PAGE_DETAIL Hook, // // Allocate some executable memory for the trampoline // - Hook->Trampoline = (CHAR *)PoolManagerRequestPool(EXEC_TRAMPOLINE, TRUE, MAX_EXEC_TRAMPOLINE_SIZE); + Hook->Trampoline = (CHAR *)PoolManagerCallbackRequestPool(EXEC_TRAMPOLINE, TRUE, MAX_EXEC_TRAMPOLINE_SIZE); if (!Hook->Trampoline) { @@ -956,7 +956,7 @@ EptHookInstructionMemory(PEPT_HOOKED_PAGE_DETAIL Hook, // function that changes the original function and if our structure is no ready after this // function then we probably see BSOD on other cores // - DetourHookDetails = (HIDDEN_HOOKS_DETOUR_DETAILS *)PoolManagerRequestPool(DETOUR_HOOK_DETAILS, TRUE, sizeof(HIDDEN_HOOKS_DETOUR_DETAILS)); + DetourHookDetails = (HIDDEN_HOOKS_DETOUR_DETAILS *)PoolManagerCallbackRequestPool(DETOUR_HOOK_DETAILS, TRUE, sizeof(HIDDEN_HOOKS_DETOUR_DETAILS)); DetourHookDetails->HookedFunctionAddress = TargetFunction; DetourHookDetails->ReturnAddress = Hook->Trampoline; @@ -1104,7 +1104,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu, // // Save the detail of hooked page to keep track of it // - HookedPage = (EPT_HOOKED_PAGE_DETAIL *)PoolManagerRequestPool(TRACKING_HOOKED_PAGES, TRUE, sizeof(EPT_HOOKED_PAGE_DETAIL)); + HookedPage = (EPT_HOOKED_PAGE_DETAIL *)PoolManagerCallbackRequestPool(TRACKING_HOOKED_PAGES, TRUE, sizeof(EPT_HOOKED_PAGE_DETAIL)); if (!HookedPage) { @@ -1155,7 +1155,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu, if (!HookedPage->StartOfTargetPhysicalAddress) { - PoolManagerFreePool((UINT64)HookedPage); + PoolManagerCallbackFreePool((UINT64)HookedPage); VmmCallbackSetLastError(DEBUGGER_ERROR_INVALID_ADDRESS); return FALSE; @@ -1183,7 +1183,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu, if (!HookedPage->EndOfTargetPhysicalAddress) { - PoolManagerFreePool((UINT64)HookedPage); + PoolManagerCallbackFreePool((UINT64)HookedPage); VmmCallbackSetLastError(DEBUGGER_ERROR_INVALID_ADDRESS); return FALSE; @@ -1244,7 +1244,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu, // if (!EptHookInstructionMemory(HookedPage, ProcessCr3, TargetAddress, (PVOID)TargetAddressInSafeMemory, HookFunction)) { - PoolManagerFreePool((UINT64)HookedPage); + PoolManagerCallbackFreePool((UINT64)HookedPage); VmmCallbackSetLastError(DEBUGGER_ERROR_COULD_NOT_BUILD_THE_EPT_HOOK); return FALSE; @@ -1258,7 +1258,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu, // if (!EptSplitLargePage(g_GuestState[i].EptPageTable, TRUE, PhysicalBaseAddress)) { - PoolManagerFreePool((UINT64)HookedPage); + PoolManagerCallbackFreePool((UINT64)HookedPage); // // Here also other previous pools should be specified, but we forget it for now @@ -1278,7 +1278,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu, // if (!TargetPage) { - PoolManagerFreePool((UINT64)HookedPage); + PoolManagerCallbackFreePool((UINT64)HookedPage); // // Here also other previous pools should be specified, but we forget it for now @@ -1862,7 +1862,7 @@ EptHookRemoveEntryAndFreePoolFromEptHook2sDetourList(UINT64 Address) // // Free the pool in next ioctl // - if (!PoolManagerFreePool((UINT64)CurrentHookedDetails)) + if (!PoolManagerCallbackFreePool((UINT64)CurrentHookedDetails)) { LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager"); } @@ -1964,7 +1964,7 @@ EptHookUnHookSingleAddressDetoursAndMonitor(PEPT_HOOKED_PAGE_DETAIL // we add the hooked entry to the list // of pools that will be deallocated on next IOCTL // - if (!PoolManagerFreePool((UINT64)HookedEntry)) + if (!PoolManagerCallbackFreePool((UINT64)HookedEntry)) { LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager"); return FALSE; @@ -2113,7 +2113,7 @@ EptHookUnHookSingleAddressHiddenBreakpoint(PEPT_HOOKED_PAGE_DETAIL H // we add the hooked entry to the list // of pools that will be deallocated on next IOCTL // - if (!PoolManagerFreePool((UINT64)HookedEntry)) + if (!PoolManagerCallbackFreePool((UINT64)HookedEntry)) { LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager"); } @@ -2485,7 +2485,7 @@ EptHookUnHookAll() // As we are in vmx-root here, we add the hooked entry to the list // of pools that will be deallocated on next IOCTL // - if (!PoolManagerFreePool((UINT64)CurrEntity)) + if (!PoolManagerCallbackFreePool((UINT64)CurrEntity)) { LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager"); } diff --git a/hyperdbg/hyperhv/code/interface/Callback.c b/hyperdbg/hyperhv/code/interface/Callback.c index cd924a0a..9e9a7492 100644 --- a/hyperdbg/hyperhv/code/interface/Callback.c +++ b/hyperdbg/hyperhv/code/interface/Callback.c @@ -284,6 +284,71 @@ DebuggingCallbackCheckThreadInterception(UINT32 CoreId) return g_Callbacks.DebuggingCallbackCheckThreadInterception(CoreId); } +/** + * @brief routine callback to request pool allocation + * + * @param Size + * @param Count + * @param Intention The intention of the buffer (buffer tag) + * + * @return BOOLEAN + */ +BOOLEAN +PoolManagerCallbackRequestAllocation(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention) +{ + if (g_Callbacks.PoolManagerRequestAllocation == NULL) + { + // + // ignore it as it's not handled + // + return FALSE; + } + return g_Callbacks.PoolManagerRequestAllocation(Size, Count, Intention); +} + +/** + * @brief routine callback to request pool + * + * @param Intention The intention why we need this pool for (buffer tag) + * @param RequestNewPool Create a request to allocate a new pool with the same size, next time + * that it's safe to allocate (this way we never ran out of pools for this "Intention") + * @param Size If the RequestNewPool is true the we should specify a size for the new pool + * + * @return UINT64 Returns a pool address or returns null if there was an error + */ +UINT64 +PoolManagerCallbackRequestPool(POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPool, UINT32 Size) +{ + if (g_Callbacks.PoolManagerRequestPool == NULL) + { + // + // ignore it as it's not handled + // + return 0; + } + return g_Callbacks.PoolManagerRequestPool(Intention, RequestNewPool, Size); +} + +/** + * @brief routine callback to free pool + * + * @param AddressToFree + * + * @return BOOLEAN + */ +BOOLEAN +PoolManagerCallbackFreePool(UINT64 AddressToFree) +{ + if (g_Callbacks.PoolManagerFreePool == NULL) + { + // + // ignore it as it's not handled + // + return FALSE; + } + return g_Callbacks.PoolManagerFreePool(AddressToFree); +} + /** * @brief routine callback to handle cr3 process change * diff --git a/hyperdbg/hyperhv/code/vmm/ept/Ept.c b/hyperdbg/hyperhv/code/vmm/ept/Ept.c index c07ff4f8..f237b710 100644 --- a/hyperdbg/hyperhv/code/vmm/ept/Ept.c +++ b/hyperdbg/hyperhv/code/vmm/ept/Ept.c @@ -502,7 +502,7 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable, // if (UsePreAllocatedBuffer) { - NewSplit = (PVMM_EPT_DYNAMIC_SPLIT)PoolManagerRequestPool(SPLIT_2MB_PAGING_TO_4KB_PAGE, TRUE, sizeof(VMM_EPT_DYNAMIC_SPLIT)); + NewSplit = (PVMM_EPT_DYNAMIC_SPLIT)PoolManagerCallbackRequestPool(SPLIT_2MB_PAGING_TO_4KB_PAGE, TRUE, sizeof(VMM_EPT_DYNAMIC_SPLIT)); } else { diff --git a/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c b/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c index ef43a11e..ab4eab29 100644 --- a/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c +++ b/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c @@ -317,15 +317,6 @@ VmxPerformVirtualizationOnAllCores() LogDebugInfo("MTRR memory map built successfully"); } - // - // Initialize Pool Manager - // - if (!PoolManagerInitialize()) - { - LogError("Err, could not initialize pool manager"); - return FALSE; - } - if (!EptLogicalProcessorInitialize()) { // @@ -1158,11 +1149,6 @@ VmxPerformTermination() PlatformMemFreePool(g_EptState); g_EptState = NULL; - // - // Free the Pool manager - // - PoolManagerUninitialize(); - // // Uninitialize memory mapper // diff --git a/hyperdbg/hyperhv/header/interface/Callback.h b/hyperdbg/hyperhv/header/interface/Callback.h index 4673930f..ce02087f 100644 --- a/hyperdbg/hyperhv/header/interface/Callback.h +++ b/hyperdbg/hyperhv/header/interface/Callback.h @@ -72,6 +72,19 @@ DebuggingCallbackHandleDebugBreakpointException(UINT32 CoreId); BOOLEAN DebuggingCallbackCheckThreadInterception(UINT32 CoreId); +// +// Pool Manager Callbacks +// + +BOOLEAN +PoolManagerCallbackRequestAllocation(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention); + +UINT64 +PoolManagerCallbackRequestPool(POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPool, UINT32 Size); + +BOOLEAN +PoolManagerCallbackFreePool(UINT64 AddressToFree); + // // Interception Callbacks // diff --git a/hyperdbg/hyperhv/hyperhv.vcxproj b/hyperdbg/hyperhv/hyperhv.vcxproj index b007446c..f2dc2413 100644 --- a/hyperdbg/hyperhv/hyperhv.vcxproj +++ b/hyperdbg/hyperhv/hyperhv.vcxproj @@ -165,7 +165,6 @@ - @@ -272,7 +271,6 @@ - diff --git a/hyperdbg/hyperhv/hyperhv.vcxproj.filters b/hyperdbg/hyperhv/hyperhv.vcxproj.filters index 2ef34332..f8fcb900 100644 --- a/hyperdbg/hyperhv/hyperhv.vcxproj.filters +++ b/hyperdbg/hyperhv/hyperhv.vcxproj.filters @@ -203,9 +203,6 @@ code\memory - - code\memory - code\components\registers @@ -394,9 +391,6 @@ header\memory - - header\memory - header\vmm\vmx diff --git a/hyperdbg/hyperhv/pch.h b/hyperdbg/hyperhv/pch.h index c988ebad..43398529 100644 --- a/hyperdbg/hyperhv/pch.h +++ b/hyperdbg/hyperhv/pch.h @@ -95,7 +95,6 @@ #include "memory/MemoryMapper.h" #include "interface/Dispatch.h" #include "common/Msr.h" -#include "memory/PoolManager.h" #include "common/Trace.h" #include "assembly/InlineAsm.h" #include "vmm/ept/Vpid.h" diff --git a/hyperdbg/hyperkd/code/debugger/core/Debugger.c b/hyperdbg/hyperkd/code/debugger/core/Debugger.c index 740fec48..99cd8c4d 100644 --- a/hyperdbg/hyperkd/code/debugger/core/Debugger.c +++ b/hyperdbg/hyperkd/code/debugger/core/Debugger.c @@ -47,41 +47,106 @@ DebuggerSetLastError(UINT32 LastError) } /** - * @brief Initialize Debugger Structures and Routines + * @brief Initialize script engine global variables and per-core stack buffers * * @return BOOLEAN Shows whether the initialization process was successful * or not */ BOOLEAN -DebuggerInitialize() +DebuggerInitializeScriptEngine() { ULONG ProcessorsCount = KeQueryActiveProcessorCount(0); PROCESSOR_DEBUGGING_STATE * CurrentDebuggerState = NULL; // - // Also allocate the debugging state + // Initialize script engines global variables holder // - if (!GlobalDebuggingStateAllocateZeroedMemory()) + if (!g_ScriptGlobalVariables) { + g_ScriptGlobalVariables = PlatformMemAllocateNonPagedPool(MAX_VAR_COUNT * sizeof(UINT64)); + } + + if (!g_ScriptGlobalVariables) + { + // + // Out of resource, initialization of script engine's global variable holders failed + // return FALSE; } // - // Allocate buffer for saving events + // Zero the global variables memory // - if (GlobalEventsAllocateZeroedMemory() == FALSE) - { - return FALSE; - } + RtlZeroMemory(g_ScriptGlobalVariables, MAX_VAR_COUNT * sizeof(UINT64)); // - // Set the core's IDs + // Initialize the local and temp variables // - for (UINT32 i = 0; i < ProcessorsCount; i++) + for (SIZE_T i = 0; i < ProcessorsCount; i++) { - g_DbgState[i].CoreId = i; + CurrentDebuggerState = &g_DbgState[i]; + + if (!CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer) + { + CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer = PlatformMemAllocateNonPagedPool(MAX_STACK_BUFFER_COUNT * sizeof(UINT64)); + } + + if (!CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer) + { + // + // Out of resource, initialization of script engine's stack buffer holders failed + // + return FALSE; + } + + // + // Zero stack buffer memory + // + RtlZeroMemory(CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer, MAX_STACK_BUFFER_COUNT * sizeof(UINT64)); } + return TRUE; +} + +/** + * @brief Initialize trap flag state and breakpoint related structures + * + * @return BOOLEAN Shows whether the initialization process was successful + * or not + */ +BOOLEAN +DebuggerInitializeTrapsAndBreakpoints() +{ + // + // Zero the TRAP FLAG state memory + // + RtlZeroMemory(&g_TrapFlagState, sizeof(DEBUGGER_TRAP_FLAG_STATE)); + + // + // Request pages for breakpoint detail + // + PoolManagerRequestAllocation(sizeof(DEBUGGEE_BP_DESCRIPTOR), + MAXIMUM_BREAKPOINTS_WITHOUT_CONTINUE, + BREAKPOINT_DEFINITION_STRUCTURE); + + // + // Initialize list of breakpoints and breakpoint id + // + g_MaximumBreakpointId = 0; + InitializeListHead(&g_BreakpointsListHead); + + return TRUE; +} + +/** + * @brief Initialize VMM operations (events and related operations) + * + * @return BOOLEAN Shows whether the initialization process was successful + * or not + */ +BOOLEAN +DebuggerInitializeVmmOperations() +{ // // Initialize lists relating to the debugger events store // @@ -113,101 +178,6 @@ DebuggerInitialize() InitializeListHead(&g_Events->ControlRegisterModifiedEventsHead); InitializeListHead(&g_Events->XsetbvInstructionExecutionEventsHead); - // - // Enabled Debugger Events - // - g_EnableDebuggerEvents = TRUE; - - // - // Set initial state of triggering events for VMCALLs - // - VmFuncSetTriggerEventForVmcalls(FALSE); - - // - // Set initial state of triggering events for VMCALLs - // - VmFuncSetTriggerEventForCpuids(FALSE); - - // - // Initialize script engines global variables holder - // - if (!g_ScriptGlobalVariables) - { - g_ScriptGlobalVariables = PlatformMemAllocateNonPagedPool(MAX_VAR_COUNT * sizeof(UINT64)); - } - - if (!g_ScriptGlobalVariables) - { - // - // Out of resource, initialization of script engine's global variable holders failed - // - return FALSE; - } - - // - // Zero the global variables memory - // - RtlZeroMemory(g_ScriptGlobalVariables, MAX_VAR_COUNT * sizeof(UINT64)); - - // - // Zero the TRAP FLAG state memory - // - RtlZeroMemory(&g_TrapFlagState, sizeof(DEBUGGER_TRAP_FLAG_STATE)); - - // - // Initialize the local and temp variables - // - for (SIZE_T i = 0; i < ProcessorsCount; i++) - { - CurrentDebuggerState = &g_DbgState[i]; - - if (!CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer) - { - CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer = PlatformMemAllocateNonPagedPool(MAX_STACK_BUFFER_COUNT * sizeof(UINT64)); - } - - if (!CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer) - { - // - // Out of resource, initialization of script engine's stack buffer holders failed - // - return FALSE; - } - - // - // Zero stack buffer memory - // - RtlZeroMemory(CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer, MAX_STACK_BUFFER_COUNT * sizeof(UINT64)); - } - - // - // Request pages for breakpoint detail - // - PoolManagerRequestAllocation(sizeof(DEBUGGEE_BP_DESCRIPTOR), - MAXIMUM_BREAKPOINTS_WITHOUT_CONTINUE, - BREAKPOINT_DEFINITION_STRUCTURE); - - // - // Initialize list of breakpoints and breakpoint id - // - g_MaximumBreakpointId = 0; - InitializeListHead(&g_BreakpointsListHead); - - // - // Initialize NMI broadcasting mechanism - // - VmFuncVmxBroadcastInitialize(); - - // - // Initialize attaching mechanism, - // we'll use the functionalities of the attaching in reading modules - // of user mode applications (other than attaching mechanism itself) - // - if (!AttachingInitialize()) - { - return FALSE; - } - // // Pre-allocate pools for possible EPT hooks // @@ -222,21 +192,110 @@ DebuggerInitialize() // } + // + // Initialize NMI broadcasting mechanism + // + VmFuncVmxBroadcastInitialize(); + + // + // Set initial state of triggering events for VMCALLs + // + VmFuncSetTriggerEventForVmcalls(FALSE); + + // + // Set initial state of triggering events for CPUIDs + // + VmFuncSetTriggerEventForCpuids(FALSE); + + // + // Enabled Debugger VMX Events + // + g_EnableDebuggerVmxEvents = TRUE; + return TRUE; } /** - * @brief Uninitialize Debugger Structures and Routines + * @brief Initialize Debugger Structures and Routines * + * @return BOOLEAN Shows whether the initialization process was successful + * or not + */ +BOOLEAN +DebuggerInitialize() +{ + ULONG ProcessorsCount = KeQueryActiveProcessorCount(0); + + // + // Also allocate the debugging state + // + if (!GlobalDebuggingStateAllocateZeroedMemory()) + { + return FALSE; + } + + // + // Allocate buffer for saving events + // + if (GlobalEventsAllocateZeroedMemory() == FALSE) + { + return FALSE; + } + + // + // Set the core's IDs + // + for (UINT32 i = 0; i < ProcessorsCount; i++) + { + g_DbgState[i].CoreId = i; + } + + // + // Initialize Pool Manager + // + if (!PoolManagerInitialize()) + { + LogError("Err, could not initialize pool manager"); + return FALSE; + } + + // + // Initialize script engine global variables and per-core stack buffers + // + if (!DebuggerInitializeScriptEngine()) + { + return FALSE; + } + + // + // Initialize trap flag state and breakpoint related structures + // + if (!DebuggerInitializeTrapsAndBreakpoints()) + { + return FALSE; + } + + // + // Initialize attaching mechanism, + // we'll use the functionalities of the attaching in reading modules + // of user mode applications (other than attaching mechanism itself) + // + if (!AttachingInitialize()) + { + return FALSE; + } + + return TRUE; +} + +/** + * @brief Uninitialize Debugger VMM Operations (Events and other related operations) + * + * @return VOID */ VOID -DebuggerUninitialize() +DebuggerUninitializeVmmOperations() { - ULONG ProcessorsCount; - PROCESSOR_DEBUGGING_STATE * CurrentDebuggerState = NULL; - - ProcessorsCount = KeQueryActiveProcessorCount(0); - // // *** Disable, terminate and clear all the events *** // @@ -253,7 +312,7 @@ DebuggerUninitialize() // // Disable triggering events // - g_EnableDebuggerEvents = FALSE; + g_EnableDebuggerVmxEvents = FALSE; // // Clear all events (Check if the kernel debugger is enable @@ -268,11 +327,6 @@ DebuggerUninitialize() DebuggerClearAllEvents(FALSE, FALSE); } - // - // Uninitialize the HyperTrace (if it was initialized) - // - HyperTraceUnInit(); - // // Uninitialize kernel debugger // @@ -287,6 +341,30 @@ DebuggerUninitialize() // Uninitialize NMI broadcasting mechanism // VmFuncVmxBroadcastUninitialize(); +} + +/** + * @brief Uninitialize Debugger Structures and Routines + * + * @return VOID + */ +VOID +DebuggerUninitialize() +{ + ULONG ProcessorsCount; + PROCESSOR_DEBUGGING_STATE * CurrentDebuggerState = NULL; + + ProcessorsCount = KeQueryActiveProcessorCount(0); + + // + // Uninitialize the HyperTrace (if it was initialized) + // + HyperTraceUnInit(); + + // + // Free the Pool manager + // + PoolManagerUninitialize(); // // Free g_Events @@ -1087,7 +1165,7 @@ DebuggerTriggerEvents(VMM_EVENT_TYPE_ENUM EventType, // // Check if triggering debugging actions are allowed or not // - if (!g_EnableDebuggerEvents || g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer) + if (!g_EnableDebuggerVmxEvents || g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer) { // // Debugger is not enabled diff --git a/hyperdbg/hyperhv/code/memory/PoolManager.c b/hyperdbg/hyperkd/code/debugger/memory/PoolManager.c similarity index 94% rename from hyperdbg/hyperhv/code/memory/PoolManager.c rename to hyperdbg/hyperkd/code/debugger/memory/PoolManager.c index 1a101067..7965aefb 100644 --- a/hyperdbg/hyperhv/code/memory/PoolManager.c +++ b/hyperdbg/hyperkd/code/debugger/memory/PoolManager.c @@ -68,9 +68,15 @@ PoolManagerInitialize() InitializeListHead(&g_ListOfAllocatedPoolsHead); // - // Nothing to deallocate + // Nothing to deallocate or allocate at the beginning // - g_IsNewRequestForDeAllocation = FALSE; + g_IsNewRequestForDeAllocation = FALSE; + g_IsNewRequestForAllocationReceived = FALSE; + + // + // Memory allocator is initialized + // + g_PoolManagerInitialized = TRUE; // // Initialized successfully @@ -86,8 +92,12 @@ PoolManagerInitialize() VOID PoolManagerUninitialize() { - PLIST_ENTRY ListTemp = 0; - ListTemp = &g_ListOfAllocatedPoolsHead; + PLIST_ENTRY ListTemp = &g_ListOfAllocatedPoolsHead; + + // + // Pool manager is not initialized anymore + // + g_PoolManagerInitialized = FALSE; SpinlockLock(&LockForReadingPool); @@ -305,12 +315,14 @@ PoolManagerCheckAndPerformAllocationAndDeallocation() PLIST_ENTRY ListTemp = 0; // - // let's make sure we're on vmx non-root and also we have new allocation + // Make sure we're on vmx non-root and also we have new allocation + // and also pool manager is initialized, otherwise we shouldn't allocate or deallocate // - if (VmxGetCurrentExecutionMode() == TRUE) + if (!g_PoolManagerInitialized || VmFuncVmxGetCurrentExecutionMode() == TRUE) { // // allocation's can't be done from vmx root + // or pool manager is not initialized yet // return FALSE; } diff --git a/hyperdbg/hyperkd/code/driver/Driver.c b/hyperdbg/hyperkd/code/driver/Driver.c index 48059898..053eb828 100644 --- a/hyperdbg/hyperkd/code/driver/Driver.c +++ b/hyperdbg/hyperkd/code/driver/Driver.c @@ -103,7 +103,7 @@ DrvUnload(PDRIVER_OBJECT DriverObject) // // Unloading Log Tracer // - LoaderUninitializeLogTracer(); + LoaderUninitLogTracer(); } /** diff --git a/hyperdbg/hyperkd/code/driver/Ioctl.c b/hyperdbg/hyperkd/code/driver/Ioctl.c index 94b0d9d0..b14572f7 100644 --- a/hyperdbg/hyperkd/code/driver/Ioctl.c +++ b/hyperdbg/hyperkd/code/driver/Ioctl.c @@ -95,106 +95,63 @@ IoctlCheckIoctlAllowed(ULONG Ioctl) ULONG IoctlFunction = CTL_CODE_FUNCTION(Ioctl); // - // First 10 IOCTLs are about loading and initializing modules + // First 100 IOCTLs are about loading and initializing modules // - if (IoctlFunction > IOCTL_START_CODE && IoctlFunction <= IOCTL_START_CODE + 0x10) + if (IoctlFunction > IOCTL_BASIC_IOCTL && IoctlFunction <= IOCTL_BASIC_IOCTL + 0x100) { // - // Allow these IOCTLs even if we don't allow IOCTL from user-mode, because they are used for loading and initializing the driver and its components + // Always allow these IOCTLs even if we don't allow IOCTL from user-mode, because they are used for loading and initializing the driver and its components // return TRUE; } - - return g_AllowIoctlFromUsermode; + else if (IoctlFunction > IOCTL_KD_IOCTL && IoctlFunction <= IOCTL_KD_IOCTL + 0x100) + { + // + // Allow if the KD module is initialized + // + return g_KdInitialized; + } + else if (IoctlFunction > IOCTL_VMM_IOCTL && IoctlFunction <= IOCTL_VMM_IOCTL + 0x100) + { + // + // Allow if the VMM module is initialized + // + return g_VmmInitialized; + } + else if (IoctlFunction > IOCTL_HYPERTRACE_IOCTL && IoctlFunction <= IOCTL_HYPERTRACE_IOCTL + 0x100) + { + // + // Allow if the HyperTrace module is initialized + // + return g_HyperTraceInitialized; + } + else + { + // + // For other (unknown) IOCTLs, we don't allow them + // + return FALSE; + } } /** - * @brief Driver IOCTL Dispatcher + * @brief IOCTL Dispatcher for Basic IOCTLs (initialization and event registration) * - * @param DeviceObject * @param Irp + * @param IrpStack + * @param DoNotChangeInformation * @return NTSTATUS */ NTSTATUS -DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) +DrvDispatchBasicIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation) { - UNREFERENCED_PARAMETER(DeviceObject); - - PIO_STACK_LOCATION IrpStack; - PREGISTER_NOTIFY_BUFFER RegisterEventRequest; - PDEBUGGER_READ_MEMORY DebuggerReadMemRequest; - PDEBUGGER_READ_AND_WRITE_ON_MSR DebuggerReadOrWriteMsrRequest; - PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE DebuggerHideAndUnhideRequest; - PDEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS DebuggerPteRequest; - PDEBUGGER_PAGE_IN_REQUEST DebuggerPageinRequest; - PDEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET PcitreeRequest; - PDEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET PcidevinfoRequest; - PDEBUGGER_VA2PA_AND_PA2VA_COMMANDS DebuggerVa2paAndPa2vaRequest; - PDEBUGGER_EDIT_MEMORY DebuggerEditMemoryRequest; - PDEBUGGER_SEARCH_MEMORY DebuggerSearchMemoryRequest; - PDEBUGGER_GENERAL_EVENT_DETAIL DebuggerNewEventRequest; - PDEBUGGER_MODIFY_EVENTS DebuggerModifyEventRequest; - PDEBUGGER_FLUSH_LOGGING_BUFFERS DebuggerFlushBuffersRequest; - PDEBUGGER_INIT_VMM_PACKET InitVmmRequest; - PDEBUGGER_INIT_HYPERTRACE_PACKET InitHyperTraceRequest; - PDEBUGGER_PREALLOC_COMMAND DebuggerReservePreallocPoolRequest; - PDEBUGGER_PREACTIVATE_COMMAND DebuggerPreactivationRequest; - PDEBUGGER_APIC_REQUEST DebuggerApicRequest; - PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS DebuggerQueryIdtRequest; - PDEBUGGEE_BP_PACKET DebuggerBreakpointRequest; - PDEBUGGER_UD_COMMAND_PACKET DebuggerUdCommandRequest; - PUSERMODE_LOADED_MODULE_DETAILS DebuggerUsermodeModulesRequest; - PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS DebuggerUsermodeProcessOrThreadQueryRequest; - PDEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET GetInformationProcessRequest; - PREVERSING_MACHINE_RECONSTRUCT_MEMORY_REQUEST RevServiceRequest; - PDEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET GetInformationThreadRequest; - PDEBUGGER_PERFORM_KERNEL_TESTS DebuggerKernelTestRequest; - PDEBUGGER_SEND_COMMAND_EXECUTION_FINISHED_SIGNAL DebuggerCommandExecutionFinishedRequest; - PDEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER DebuggerSendUsermodeMessageRequest; - PDEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER DebuggerSendBufferFromDebuggeeToDebuggerRequest; - PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS DebuggerAttachOrDetachToThreadRequest; - PDEBUGGER_PREPARE_DEBUGGEE DebuggeeRequest; - PDEBUGGER_PAUSE_PACKET_RECEIVED DebuggerPauseKernelRequest; - PDEBUGGER_GENERAL_ACTION DebuggerNewActionRequest; - PSMI_OPERATION_PACKETS SmiOperationRequest; - PHYPERTRACE_LBR_OPERATION_PACKETS HyperTraceLbrOperationRequest; - PHYPERTRACE_LBR_DUMP_PACKETS HyperTraceLbrdumpRequest; - PHYPERTRACE_PT_OPERATION_PACKETS HyperTracePtOperationRequest; - PVOID BufferToStoreThreadsAndProcessesDetails; - ULONG InBuffLength; // Input buffer length - ULONG OutBuffLength; // Output buffer length - SIZE_T ReturnSize; - NTSTATUS Status = STATUS_SUCCESS; - BOOLEAN DoNotChangeInformation = FALSE; - UINT32 Ioctl = 0; - - // - // Here's the best place to see if there is any allocation pending - // to be allcated as we're in PASSIVE_LEVEL - // - PoolManagerCheckAndPerformAllocationAndDeallocation(); - - // - // Get the current stack location of the IRP to access the parameters of the IOCTL request - // - IrpStack = IoGetCurrentIrpStackLocation(Irp); - - // - // Get the IOCTL code from the parameters - // - Ioctl = IrpStack->Parameters.DeviceIoControl.IoControlCode; - - // - // If we don't allow IOCTL from user-mode, we just complete the request with success, and return - // - if (!IoctlCheckIoctlAllowed(Ioctl)) - { - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_SUCCESS; - } + PREGISTER_NOTIFY_BUFFER RegisterEventRequest; + PDEBUGGER_INIT_VMM_PACKET InitVmmRequest; + PDEBUGGER_INIT_HYPERTRACE_PACKET InitHyperTraceRequest; + ULONG InBuffLength; + ULONG OutBuffLength; + NTSTATUS Status = STATUS_SUCCESS; + UINT32 Ioctl = IrpStack->Parameters.DeviceIoControl.IoControlCode; switch (Ioctl) { @@ -215,9 +172,9 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) } // - // Initialize the vmm and the debugger + // Initialize the debugger and the vmm // - if (LoaderInitVmmAndDebugger(InitVmmRequest)) + if (LoaderInitDebuggerAndVmm(InitVmmRequest)) { Status = STATUS_SUCCESS; } @@ -232,7 +189,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_INIT_VMM_PACKET, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_INIT_VMM_PACKET, DoNotChangeInformation, Irp, &Status); break; @@ -260,7 +217,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_INIT_HYPERTRACE_PACKET, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_INIT_HYPERTRACE_PACKET, DoNotChangeInformation, Irp, &Status); break; @@ -312,11 +269,6 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) case IOCTL_RETURN_IRP_PENDING_PACKETS_AND_DISALLOW_IOCTL: - // - // Disallow new IOCTL - // - g_AllowIoctlFromUsermode = FALSE; - // // Send an immediate message, and we're no longer get new IRP // @@ -329,17 +281,102 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) break; + default: + LogError("Err, unknown IOCTL"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + + return Status; +} + +/** + * @brief IOCTL Dispatcher for KD (Kernel Debugger) IOCTLs + * + * @param Irp + * @param IrpStack + * @param DoNotChangeInformation + * @return NTSTATUS + */ +NTSTATUS +DrvDispatchKdIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation) +{ + NTSTATUS Status = STATUS_SUCCESS; + UINT32 Ioctl = IrpStack->Parameters.DeviceIoControl.IoControlCode; + + UNREFERENCED_PARAMETER(Irp); + UNREFERENCED_PARAMETER(DoNotChangeInformation); + + switch (Ioctl) + { + default: + LogError("Err, unknown IOCTL"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + + return Status; +} + +/** + * @brief IOCTL Dispatcher for VMM IOCTLs + * + * @param Irp + * @param IrpStack + * @param DoNotChangeInformation + * @return NTSTATUS + */ +NTSTATUS +DrvDispatchVmmIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation) +{ + PDEBUGGER_READ_MEMORY DebuggerReadMemRequest; + PDEBUGGER_READ_AND_WRITE_ON_MSR DebuggerReadOrWriteMsrRequest; + PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE DebuggerHideAndUnhideRequest; + PDEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS DebuggerPteRequest; + PDEBUGGER_PAGE_IN_REQUEST DebuggerPageinRequest; + PDEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET PcitreeRequest; + PDEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET PcidevinfoRequest; + PDEBUGGER_VA2PA_AND_PA2VA_COMMANDS DebuggerVa2paAndPa2vaRequest; + PDEBUGGER_EDIT_MEMORY DebuggerEditMemoryRequest; + PDEBUGGER_SEARCH_MEMORY DebuggerSearchMemoryRequest; + PDEBUGGER_GENERAL_EVENT_DETAIL DebuggerNewEventRequest; + PDEBUGGER_MODIFY_EVENTS DebuggerModifyEventRequest; + PDEBUGGER_FLUSH_LOGGING_BUFFERS DebuggerFlushBuffersRequest; + PDEBUGGER_PREALLOC_COMMAND DebuggerReservePreallocPoolRequest; + PDEBUGGER_PREACTIVATE_COMMAND DebuggerPreactivationRequest; + PDEBUGGER_APIC_REQUEST DebuggerApicRequest; + PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS DebuggerQueryIdtRequest; + PDEBUGGEE_BP_PACKET DebuggerBreakpointRequest; + PDEBUGGER_UD_COMMAND_PACKET DebuggerUdCommandRequest; + PUSERMODE_LOADED_MODULE_DETAILS DebuggerUsermodeModulesRequest; + PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS DebuggerUsermodeProcessOrThreadQueryRequest; + PDEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET GetInformationProcessRequest; + PREVERSING_MACHINE_RECONSTRUCT_MEMORY_REQUEST RevServiceRequest; + PDEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET GetInformationThreadRequest; + PDEBUGGER_PERFORM_KERNEL_TESTS DebuggerKernelTestRequest; + PDEBUGGER_SEND_COMMAND_EXECUTION_FINISHED_SIGNAL DebuggerCommandExecutionFinishedRequest; + PDEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER DebuggerSendUsermodeMessageRequest; + PDEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER DebuggerSendBufferFromDebuggeeToDebuggerRequest; + PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS DebuggerAttachOrDetachToThreadRequest; + PDEBUGGER_PREPARE_DEBUGGEE DebuggeeRequest; + PDEBUGGER_PAUSE_PACKET_RECEIVED DebuggerPauseKernelRequest; + PDEBUGGER_GENERAL_ACTION DebuggerNewActionRequest; + PSMI_OPERATION_PACKETS SmiOperationRequest; + PVOID BufferToStoreThreadsAndProcessesDetails; + ULONG InBuffLength; // Input buffer length + ULONG OutBuffLength; // Output buffer length + SIZE_T ReturnSize; + NTSTATUS Status = STATUS_SUCCESS; + UINT32 Ioctl = IrpStack->Parameters.DeviceIoControl.IoControlCode; + + switch (Ioctl) + { case IOCTL_TERMINATE_VMX: // - // Uninitialize the debugger and its sub-mechanisms + // Uninitialize the VMM and the debugger // - DebuggerUninitialize(); - - // - // Terminate VMX - // - VmFuncUninitVmm(); + LoaderUninitVmmAndDebugger(); Status = STATUS_SUCCESS; @@ -368,14 +405,14 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Return the header a read bytes // - DrvAdjustStatusAndSetOutputSize((UINT32)(ReturnSize + SIZEOF_DEBUGGER_READ_MEMORY), &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize((UINT32)(ReturnSize + SIZEOF_DEBUGGER_READ_MEMORY), DoNotChangeInformation, Irp, &Status); } else { // // Just return the header to the user-mode // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_READ_MEMORY, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_READ_MEMORY, DoNotChangeInformation, Irp, &Status); } break; @@ -410,7 +447,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize((UINT32)ReturnSize, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize((UINT32)ReturnSize, DoNotChangeInformation, Irp, &Status); } break; @@ -440,7 +477,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS, DoNotChangeInformation, Irp, &Status); break; @@ -471,7 +508,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(sizeof(DEBUGGER_EVENT_AND_ACTION_RESULT), &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(sizeof(DEBUGGER_EVENT_AND_ACTION_RESULT), DoNotChangeInformation, Irp, &Status); break; @@ -502,7 +539,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(sizeof(DEBUGGER_EVENT_AND_ACTION_RESULT), &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(sizeof(DEBUGGER_EVENT_AND_ACTION_RESULT), DoNotChangeInformation, Irp, &Status); break; @@ -543,7 +580,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE, DoNotChangeInformation, Irp, &Status); break; @@ -572,7 +609,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_VA2PA_AND_PA2VA_COMMANDS, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_VA2PA_AND_PA2VA_COMMANDS, DoNotChangeInformation, Irp, &Status); break; @@ -611,7 +648,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_EDIT_MEMORY, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_EDIT_MEMORY, DoNotChangeInformation, Irp, &Status); break; @@ -669,7 +706,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // Configure IRP status, and also we send the results // buffer, with it's null values (if any) // - DrvAdjustStatusAndSetOutputSize(MaximumSearchResults * sizeof(UINT64), &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(MaximumSearchResults * sizeof(UINT64), DoNotChangeInformation, Irp, &Status); break; @@ -698,7 +735,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_MODIFY_EVENTS, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_MODIFY_EVENTS, DoNotChangeInformation, Irp, &Status); break; @@ -726,7 +763,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_FLUSH_LOGGING_BUFFERS, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_FLUSH_LOGGING_BUFFERS, DoNotChangeInformation, Irp, &Status); break; @@ -754,7 +791,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS, DoNotChangeInformation, Irp, &Status); break; @@ -782,7 +819,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PREPARE_DEBUGGEE, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PREPARE_DEBUGGEE, DoNotChangeInformation, Irp, &Status); break; @@ -810,7 +847,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PAUSE_PACKET_RECEIVED, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PAUSE_PACKET_RECEIVED, DoNotChangeInformation, Irp, &Status); break; @@ -838,7 +875,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_SEND_COMMAND_EXECUTION_FINISHED_SIGNAL, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_SEND_COMMAND_EXECUTION_FINISHED_SIGNAL, DoNotChangeInformation, Irp, &Status); break; @@ -876,7 +913,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER, DoNotChangeInformation, Irp, &Status); break; @@ -914,7 +951,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER, DoNotChangeInformation, Irp, &Status); break; @@ -942,7 +979,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PERFORM_KERNEL_TESTS, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PERFORM_KERNEL_TESTS, DoNotChangeInformation, Irp, &Status); break; @@ -970,7 +1007,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PREALLOC_COMMAND, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PREALLOC_COMMAND, DoNotChangeInformation, Irp, &Status); break; @@ -998,7 +1035,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PREACTIVATE_COMMAND, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PREACTIVATE_COMMAND, DoNotChangeInformation, Irp, &Status); break; @@ -1021,7 +1058,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(ExtensionCommandPerformActionsForApicRequests(DebuggerApicRequest), &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(ExtensionCommandPerformActionsForApicRequests(DebuggerApicRequest), DoNotChangeInformation, Irp, &Status); break; @@ -1049,7 +1086,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS, DoNotChangeInformation, Irp, &Status); break; @@ -1080,7 +1117,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_BP_PACKET, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_BP_PACKET, DoNotChangeInformation, Irp, &Status); break; @@ -1108,91 +1145,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_SMI_OPERATION_PACKETS, &DoNotChangeInformation, Irp, &Status); - - break; - - case IOCTL_PERFORM_HYPERTRACE_LBR_OPERATION: - - // - // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP - // - if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_HYPERTRACE_LBR_OPERATION_PACKETS, - (PVOID *)&HyperTraceLbrOperationRequest, - Irp, - IrpStack, - &InBuffLength, - &OutBuffLength)) - { - Status = STATUS_INVALID_PARAMETER; - break; - } - - // - // Perform the HyperTrace LBR operation - // - HyperTraceLbrPerformOperation(HyperTraceLbrOperationRequest); - - // - // Adjust the status and output size - // - DrvAdjustStatusAndSetOutputSize(SIZEOF_HYPERTRACE_LBR_OPERATION_PACKETS, &DoNotChangeInformation, Irp, &Status); - - break; - - case IOCTL_PERFORM_HYPERTRACE_LBR_DUMP: - - // - // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP - // - if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_HYPERTRACE_LBR_DUMP_PACKETS, - (PVOID *)&HyperTraceLbrdumpRequest, - Irp, - IrpStack, - &InBuffLength, - &OutBuffLength)) - { - Status = STATUS_INVALID_PARAMETER; - break; - } - - // - // Perform the HyperTrace LBR dump operation - // - HyperTraceLbrPerformDump(HyperTraceLbrdumpRequest); - - // - // Adjust the status and output size - // - DrvAdjustStatusAndSetOutputSize(SIZEOF_HYPERTRACE_LBR_DUMP_PACKETS, &DoNotChangeInformation, Irp, &Status); - - break; - - case IOCTL_PERFORM_HYPERTRACE_PT_OPERATION: - - // - // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP - // - if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_HYPERTRACE_PT_OPERATION_PACKETS, - (PVOID *)&HyperTracePtOperationRequest, - Irp, - IrpStack, - &InBuffLength, - &OutBuffLength)) - { - Status = STATUS_INVALID_PARAMETER; - break; - } - - // - // Perform the HyperTrace PT operation - // - HyperTracePtPerformOperation(HyperTracePtOperationRequest); - - // - // Adjust the status and output size - // - DrvAdjustStatusAndSetOutputSize(SIZEOF_HYPERTRACE_PT_OPERATION_PACKETS, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_SMI_OPERATION_PACKETS, DoNotChangeInformation, Irp, &Status); break; @@ -1220,7 +1173,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(OutBuffLength, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(OutBuffLength, DoNotChangeInformation, Irp, &Status); break; @@ -1247,7 +1200,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(OutBuffLength, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(OutBuffLength, DoNotChangeInformation, Irp, &Status); break; @@ -1275,7 +1228,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(OutBuffLength, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(OutBuffLength, DoNotChangeInformation, Irp, &Status); break; @@ -1310,7 +1263,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS, DoNotChangeInformation, Irp, &Status); break; @@ -1349,7 +1302,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(OutBuffLength, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(OutBuffLength, DoNotChangeInformation, Irp, &Status); break; @@ -1377,7 +1330,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET, DoNotChangeInformation, Irp, &Status); break; @@ -1405,7 +1358,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET, DoNotChangeInformation, Irp, &Status); break; @@ -1433,7 +1386,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_REVERSING_MACHINE_RECONSTRUCT_MEMORY_REQUEST, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_REVERSING_MACHINE_RECONSTRUCT_MEMORY_REQUEST, DoNotChangeInformation, Irp, &Status); break; @@ -1462,7 +1415,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PAGE_IN_REQUEST, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PAGE_IN_REQUEST, DoNotChangeInformation, Irp, &Status); break; @@ -1491,7 +1444,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET, DoNotChangeInformation, Irp, &Status); break; @@ -1520,7 +1473,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) // // Adjust the status and output size // - DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET, &DoNotChangeInformation, Irp, &Status); + DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET, DoNotChangeInformation, Irp, &Status); break; @@ -1530,6 +1483,195 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) break; } + return Status; +} + +/** + * @brief IOCTL Dispatcher for HyperTrace IOCTLs + * + * @param Irp + * @param IrpStack + * @param DoNotChangeInformation + * @return NTSTATUS + */ +NTSTATUS +DrvDispatchHyperTraceIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation) +{ + PHYPERTRACE_LBR_OPERATION_PACKETS HyperTraceLbrOperationRequest; + PHYPERTRACE_LBR_DUMP_PACKETS HyperTraceLbrdumpRequest; + PHYPERTRACE_PT_OPERATION_PACKETS HyperTracePtOperationRequest; + ULONG InBuffLength; + ULONG OutBuffLength; + NTSTATUS Status = STATUS_SUCCESS; + UINT32 Ioctl = IrpStack->Parameters.DeviceIoControl.IoControlCode; + + switch (Ioctl) + { + case IOCTL_PERFORM_HYPERTRACE_LBR_OPERATION: + + // + // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP + // + if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_HYPERTRACE_LBR_OPERATION_PACKETS, + (PVOID *)&HyperTraceLbrOperationRequest, + Irp, + IrpStack, + &InBuffLength, + &OutBuffLength)) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + + // + // Perform the HyperTrace LBR operation + // + HyperTraceLbrPerformOperation(HyperTraceLbrOperationRequest); + + // + // Adjust the status and output size + // + DrvAdjustStatusAndSetOutputSize(SIZEOF_HYPERTRACE_LBR_OPERATION_PACKETS, DoNotChangeInformation, Irp, &Status); + + break; + + case IOCTL_PERFORM_HYPERTRACE_LBR_DUMP: + + // + // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP + // + if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_HYPERTRACE_LBR_DUMP_PACKETS, + (PVOID *)&HyperTraceLbrdumpRequest, + Irp, + IrpStack, + &InBuffLength, + &OutBuffLength)) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + + // + // Perform the HyperTrace LBR dump operation + // + HyperTraceLbrPerformDump(HyperTraceLbrdumpRequest); + + // + // Adjust the status and output size + // + DrvAdjustStatusAndSetOutputSize(SIZEOF_HYPERTRACE_LBR_DUMP_PACKETS, DoNotChangeInformation, Irp, &Status); + + break; + + case IOCTL_PERFORM_HYPERTRACE_PT_OPERATION: + + // + // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP + // + if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_HYPERTRACE_PT_OPERATION_PACKETS, + (PVOID *)&HyperTracePtOperationRequest, + Irp, + IrpStack, + &InBuffLength, + &OutBuffLength)) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + + // + // Perform the HyperTrace PT operation + // + HyperTracePtPerformOperation(HyperTracePtOperationRequest); + + // + // Adjust the status and output size + // + DrvAdjustStatusAndSetOutputSize(SIZEOF_HYPERTRACE_PT_OPERATION_PACKETS, DoNotChangeInformation, Irp, &Status); + + break; + + default: + LogError("Err, unknown IOCTL"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + + return Status; +} + +/** + * @brief Driver IOCTL Dispatcher + * + * @param DeviceObject + * @param Irp + * @return NTSTATUS + */ +NTSTATUS +DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + UNREFERENCED_PARAMETER(DeviceObject); + + PIO_STACK_LOCATION IrpStack; + NTSTATUS Status = STATUS_SUCCESS; + BOOLEAN DoNotChangeInformation = FALSE; + UINT32 Ioctl = 0; + ULONG IoctlFunction = 0; + + // + // Here's the best place to see if there is any allocation pending + // to be allocated as we're in PASSIVE_LEVEL + // + PoolManagerCheckAndPerformAllocationAndDeallocation(); + + // + // Get the current stack location of the IRP to access the parameters of the IOCTL request + // + IrpStack = IoGetCurrentIrpStackLocation(Irp); + + // + // Get the IOCTL code from the parameters + // + Ioctl = IrpStack->Parameters.DeviceIoControl.IoControlCode; + + // + // If we don't allow IOCTL from user-mode, we just complete the request with success, and return + // + if (!IoctlCheckIoctlAllowed(Ioctl)) + { + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; + } + + // + // Dispatch to the appropriate handler based on the IOCTL range + // + IoctlFunction = CTL_CODE_FUNCTION(Ioctl); + + if (IoctlFunction > IOCTL_BASIC_IOCTL && IoctlFunction <= IOCTL_BASIC_IOCTL + 0x100) + { + Status = DrvDispatchBasicIoControl(Irp, IrpStack, &DoNotChangeInformation); + } + else if (IoctlFunction > IOCTL_KD_IOCTL && IoctlFunction <= IOCTL_KD_IOCTL + 0x100) + { + Status = DrvDispatchKdIoControl(Irp, IrpStack, &DoNotChangeInformation); + } + else if (IoctlFunction > IOCTL_VMM_IOCTL && IoctlFunction <= IOCTL_VMM_IOCTL + 0x100) + { + Status = DrvDispatchVmmIoControl(Irp, IrpStack, &DoNotChangeInformation); + } + else if (IoctlFunction > IOCTL_HYPERTRACE_IOCTL && IoctlFunction <= IOCTL_HYPERTRACE_IOCTL + 0x100) + { + Status = DrvDispatchHyperTraceIoControl(Irp, IrpStack, &DoNotChangeInformation); + } + else + { + Status = STATUS_NOT_IMPLEMENTED; + } + if (Status != STATUS_PENDING) { Irp->IoStatus.Status = Status; diff --git a/hyperdbg/hyperkd/code/driver/Loader.c b/hyperdbg/hyperkd/code/driver/Loader.c index 5adf9f5c..ac431eb8 100644 --- a/hyperdbg/hyperkd/code/driver/Loader.c +++ b/hyperdbg/hyperkd/code/driver/Loader.c @@ -150,17 +150,26 @@ LoaderInitHyperLog() } /** - * @brief Initialize the VMM and Debugger + * @brief Initialize the VMM * * @param InitVmmPacket The packet to fill the result of the initialization * * @return BOOLEAN */ BOOLEAN -LoaderInitVmmAndDebugger(PDEBUGGER_INIT_VMM_PACKET InitVmmPacket) +LoaderInitVmm(PDEBUGGER_INIT_VMM_PACKET InitVmmPacket) { VMM_CALLBACKS VmmCallbacks = {0}; + // + // Check if KD is not already initialized, if so we cannot initialize VMM + // + if (!g_KdInitialized) + { + InitVmmPacket->KernelStatus = DEBUGGER_ERROR_VMM_CANNOT_BE_INITIALIZED_IF_DEBUGGER_IS_NOT_LOADED; + return FALSE; + } + // // Check if HyperTrace is already initialized, if so we cannot initialize VMM // @@ -170,11 +179,6 @@ LoaderInitVmmAndDebugger(PDEBUGGER_INIT_VMM_PACKET InitVmmPacket) return FALSE; } - // - // Allow to serve IOCTL - // - g_AllowIoctlFromUsermode = TRUE; - // // *** Fill the callbacks for using hyperlog in VMM *** // @@ -211,6 +215,13 @@ LoaderInitVmmAndDebugger(PDEBUGGER_INIT_VMM_PACKET InitVmmPacket) VmmCallbacks.KdCheckAndHandleNmiCallback = KdCheckAndHandleNmiCallback; VmmCallbacks.KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId = KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId; + // + // Fill the pool manager callbacks + // + VmmCallbacks.PoolManagerRequestAllocation = PoolManagerRequestAllocation; + VmmCallbacks.PoolManagerRequestPool = PoolManagerRequestPool; + VmmCallbacks.PoolManagerFreePool = PoolManagerFreePool; + // // Fill the interception callbacks // @@ -224,44 +235,174 @@ LoaderInitVmmAndDebugger(PDEBUGGER_INIT_VMM_PACKET InitVmmPacket) LogDebugInfo("HyperDbg's hypervisor loaded successfully"); // - // Initialize the debugger + // Initialize VMM opeartions (event related state from the debugger) // - if (DebuggerInitialize()) + if (!DebuggerInitializeVmmOperations()) { - LogDebugInfo("HyperDbg's debugger loaded successfully"); - - // - // Set the kernel status to success - // - InitVmmPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL; - - return TRUE; - } - else - { - LogError("Err, HyperDbg's debugger was not loaded"); + return FALSE; } + + // + // VMM module initialized + // + g_VmmInitialized = TRUE; + + return TRUE; } else { LogError("Err, HyperDbg's hypervisor was not loaded"); } - // - // Not loaded - // - g_AllowIoctlFromUsermode = FALSE; - return FALSE; } +/** + * @brief Initialize the debugger + * + * @return BOOLEAN + */ +BOOLEAN +LoaderInitKd() +{ + // + // If the debugger is already initialized, we don't need to initialize it again + // and simply return true + // + if (g_KdInitialized) + { + return TRUE; + } + + // + // The debugger is not initialized, so we try to initialize it + // + if (DebuggerInitialize()) + { + LogDebugInfo("HyperDbg's debugger loaded successfully"); + + // + // KD module initialized + // + g_KdInitialized = TRUE; + + return TRUE; + } + + LogError("Err, HyperDbg's debugger was not loaded"); + return FALSE; +} + +/** + * @brief Initialize the debugger and the vmm + * + * @param InitVmmPacket The packet to fill the result of the initialization + * + * @return BOOLEAN + */ +BOOLEAN +LoaderInitDebuggerAndVmm(PDEBUGGER_INIT_VMM_PACKET InitVmmPacket) +{ + // + // First we need to initialize the debugger + // because the VMM relies on the debugger for some of its functionalities, + // so if we cannot initialize the debugger we cannot initialize the VMM + // + if (!LoaderInitKd()) + { + // + // Unable to initialize the debugger, so we cannot initialize the VMM, and we return false + // + InitVmmPacket->KernelStatus = DEBUGGER_ERROR_CANNOT_INITIALIZE_DEBUGGER; + + return FALSE; + } + + // + // Now we can initialize the VMM + // + if (!LoaderInitVmm(InitVmmPacket)) + { + return FALSE; + } + + // + // Set the kernel status to success + // + InitVmmPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL; + + return TRUE; +} + +/** + * @brief Uninitialize the VMM + * + * @return VOID + */ +VOID +LoaderUninitVmm() +{ + // + // Mark VMM as uninitialized before uninitializing it to avoid any potential reentrancy issues during the uninitialization process + // + g_VmmInitialized = FALSE; + + // + // First remove all VMM related state from the debugger + // + DebuggerUninitializeVmmOperations(); + + // + // Terminate VMM and its sub-mechanisms + // + VmFuncUninitVmm(); +} + +/** + * @brief Uninitialize the debugger + * + * @return VOID + */ +VOID +LoaderUninitKd() +{ + // + // Mark KD as uninitialized before uninitializing it to avoid any potential reentrancy issues during the uninitialization process + // + g_KdInitialized = FALSE; + + // + // Uninitialize the debugger and its sub-mechanisms + // + DebuggerUninitialize(); +} + +/** + * @brief Uninitialize the VMM and the debugger + * + * @return VOID + */ +VOID +LoaderUninitVmmAndDebugger() +{ + // + // Uninitialize the VMM first because it relies on the debugger for some + // + LoaderUninitVmm(); + + // + // Uninitialize the debugger + // + LoaderUninitKd(); +} + /** * @brief Uninitialize the log tracer * * @return VOID */ VOID -LoaderUninitializeLogTracer() +LoaderUninitLogTracer() { #if !UseDbgPrintInsteadOfUsermodeMessageTracking diff --git a/hyperdbg/hyperkd/header/debugger/core/Debugger.h b/hyperdbg/hyperkd/header/debugger/core/Debugger.h index c6013525..3553e20a 100644 --- a/hyperdbg/hyperkd/header/debugger/core/Debugger.h +++ b/hyperdbg/hyperkd/header/debugger/core/Debugger.h @@ -188,9 +188,21 @@ DebuggerGetLastError(); VOID DebuggerSetLastError(UINT32 LastError); +BOOLEAN +DebuggerInitializeScriptEngine(); + +BOOLEAN +DebuggerInitializeTrapsAndBreakpoints(); + +BOOLEAN +DebuggerInitializeVmmOperations(); + BOOLEAN DebuggerInitialize(); +VOID +DebuggerUninitializeVmmOperations(); + VOID DebuggerUninitialize(); diff --git a/hyperdbg/hyperhv/header/memory/PoolManager.h b/hyperdbg/hyperkd/header/debugger/memory/PoolManager.h similarity index 86% rename from hyperdbg/hyperhv/header/memory/PoolManager.h rename to hyperdbg/hyperkd/header/debugger/memory/PoolManager.h index 5c5dbc7b..ef4af344 100644 --- a/hyperdbg/hyperhv/header/memory/PoolManager.h +++ b/hyperdbg/hyperkd/header/debugger/memory/PoolManager.h @@ -76,6 +76,12 @@ volatile LONG LockForRequestAllocation; */ volatile LONG LockForReadingPool; +/** + * @brief Pool manager memory allocator initialized + * + */ +BOOLEAN g_PoolManagerInitialized; + /** * @brief We set it when there is a new allocation * @@ -114,18 +120,23 @@ static VOID PlmgrFreeRequestNewAllocation(VOID); // Public Interfaces // -/** - * @brief Initializes the Pool Manager and pre-allocate some pools - * - * @return BOOLEAN - */ BOOLEAN PoolManagerInitialize(); -/** - * @brief De-allocate all the allocated pools - * - * @return VOID - */ VOID PoolManagerUninitialize(); + +VOID +PoolManagerShowPreAllocatedPools(); + +BOOLEAN +PoolManagerCheckAndPerformAllocationAndDeallocation(); + +BOOLEAN +PoolManagerRequestAllocation(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention); + +UINT64 +PoolManagerRequestPool(POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPool, UINT32 Size); + +BOOLEAN +PoolManagerFreePool(UINT64 AddressToFree); diff --git a/hyperdbg/hyperkd/header/driver/Driver.h b/hyperdbg/hyperkd/header/driver/Driver.h index b5739220..e3233b0b 100644 --- a/hyperdbg/hyperkd/header/driver/Driver.h +++ b/hyperdbg/hyperkd/header/driver/Driver.h @@ -45,3 +45,15 @@ DrvUnsupported(PDEVICE_OBJECT DeviceObject, PIRP Irp); NTSTATUS DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp); + +NTSTATUS +DrvDispatchBasicIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation); + +NTSTATUS +DrvDispatchKdIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation); + +NTSTATUS +DrvDispatchVmmIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation); + +NTSTATUS +DrvDispatchHyperTraceIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation); diff --git a/hyperdbg/hyperkd/header/driver/Loader.h b/hyperdbg/hyperkd/header/driver/Loader.h index ff112c85..9a5dc75a 100644 --- a/hyperdbg/hyperkd/header/driver/Loader.h +++ b/hyperdbg/hyperkd/header/driver/Loader.h @@ -19,11 +19,14 @@ BOOLEAN LoaderInitHyperLog(); -BOOLEAN -LoaderInitVmmAndDebugger(PDEBUGGER_INIT_VMM_PACKET InitVmmPacket); - BOOLEAN LoaderInitHyperTrace(PDEBUGGER_INIT_HYPERTRACE_PACKET InitHyperTracePacket, BOOLEAN RunningOnHypervisorEnvironment); +BOOLEAN +LoaderInitDebuggerAndVmm(PDEBUGGER_INIT_VMM_PACKET InitVmmPacket); + VOID -LoaderUninitializeLogTracer(); +LoaderUninitVmmAndDebugger(); + +VOID +LoaderUninitLogTracer(); diff --git a/hyperdbg/hyperkd/header/globals/Global.h b/hyperdbg/hyperkd/header/globals/Global.h index 8d98a8ae..02195709 100644 --- a/hyperdbg/hyperkd/header/globals/Global.h +++ b/hyperdbg/hyperkd/header/globals/Global.h @@ -22,6 +22,18 @@ PROCESSOR_DEBUGGING_STATE * g_DbgState; */ BOOLEAN g_HyperLogInitialized; +/** + * @brief Shows whether the KD module is initialized or not + * + */ +BOOLEAN g_KdInitialized; + +/** + * @brief Shows whether the VMM is initialized or not + * + */ +BOOLEAN g_VmmInitialized; + /** * @brief Shows whether the hypertrace module is initialized or not * @@ -71,12 +83,6 @@ DEBUGGER_TRAP_FLAG_STATE g_TrapFlagState; */ BOOLEAN g_HandleInUse; -/** - * @brief Determines whether the clients are allowed to send IOCTL to the drive or not - * - */ -BOOLEAN g_AllowIoctlFromUsermode; - /** * @brief events list (for debugger) * @@ -124,7 +130,7 @@ UINT32 g_LastError; * @brief Determines whether the debugger events should be active or not * */ -BOOLEAN g_EnableDebuggerEvents; +BOOLEAN g_EnableDebuggerVmxEvents; /** * @brief List header of breakpoints for debugger-mode diff --git a/hyperdbg/hyperkd/header/pch.h b/hyperdbg/hyperkd/header/pch.h index 8da24baa..630ee6b9 100644 --- a/hyperdbg/hyperkd/header/pch.h +++ b/hyperdbg/hyperkd/header/pch.h @@ -115,6 +115,7 @@ #include "header/debugger/memory/Memory.h" #include "header/common/Common.h" #include "header/common/Synchronization.h" +#include "header/debugger/memory/PoolManager.h" #include "header/debugger/memory/Allocations.h" #include "header/debugger/kernel-level/Kd.h" #include "header/debugger/user-level/Ud.h" diff --git a/hyperdbg/hyperkd/hyperkd.vcxproj b/hyperdbg/hyperkd/hyperkd.vcxproj index 2438e56a..c7a6d222 100644 --- a/hyperdbg/hyperkd/hyperkd.vcxproj +++ b/hyperdbg/hyperkd/hyperkd.vcxproj @@ -137,6 +137,7 @@ + @@ -185,6 +186,7 @@ + diff --git a/hyperdbg/hyperkd/hyperkd.vcxproj.filters b/hyperdbg/hyperkd/hyperkd.vcxproj.filters index 375ef4fa..55eeeb30 100644 --- a/hyperdbg/hyperkd/hyperkd.vcxproj.filters +++ b/hyperdbg/hyperkd/hyperkd.vcxproj.filters @@ -279,6 +279,9 @@ code\platform + + code\debugger\memory + @@ -422,6 +425,9 @@ header\platform + + header\debugger\memory + diff --git a/hyperdbg/include/SDK/headers/ErrorCodes.h b/hyperdbg/include/SDK/headers/ErrorCodes.h index b205383f..bf31a55c 100644 --- a/hyperdbg/include/SDK/headers/ErrorCodes.h +++ b/hyperdbg/include/SDK/headers/ErrorCodes.h @@ -641,6 +641,18 @@ */ #define DEBUGGER_ERROR_VMM_CANNOT_BE_INITIALIZED_IF_HYPERTRACE_IS_LOADED 0xc0000063 +/** + * @brief error, VMM cannot be initialized if the debugger is not loaded + * + */ +#define DEBUGGER_ERROR_VMM_CANNOT_BE_INITIALIZED_IF_DEBUGGER_IS_NOT_LOADED 0xc0000064 + +/** + * @brief error, cannot initialize the debugger + * + */ +#define DEBUGGER_ERROR_CANNOT_INITIALIZE_DEBUGGER 0xc0000065 + // // WHEN YOU ADD ANYTHING TO THIS LIST OF ERRORS, THEN // MAKE SURE TO ADD AN ERROR MESSAGE TO ShowErrorMessage(UINT32 Error) diff --git a/hyperdbg/include/SDK/headers/Ioctls.h b/hyperdbg/include/SDK/headers/Ioctls.h index 26d8df3b..3d63c8cc 100644 --- a/hyperdbg/include/SDK/headers/Ioctls.h +++ b/hyperdbg/include/SDK/headers/Ioctls.h @@ -60,13 +60,37 @@ #define CTL_CODE_FUNCTION(Code) (((Code) >> 2) & 0xFFF) /** - * @brief Base code for IOCTLs, to avoid conflicts with other drivers + * @brief Base code for IOCTLs * */ #define IOCTL_START_CODE 0x800 +/** + * @brief ioctl, for basic communication between user-mode and kernel-mode, and for loading and initializing the driver and its components + * + */ +#define IOCTL_BASIC_IOCTL IOCTL_START_CODE + 0x00 + +/** + * @brief ioctl, for KD (Kernel Debugger) related functionalities + * + */ +#define IOCTL_KD_IOCTL IOCTL_START_CODE + 0x100 + +/** + * @brief ioctl, for VMM and debugger related functionalities + * + */ +#define IOCTL_VMM_IOCTL IOCTL_START_CODE + 0x200 + +/** + * @brief ioctl, for HyperTrace related functionalities + * + */ +#define IOCTL_HYPERTRACE_IOCTL IOCTL_START_CODE + 0x300 + ////////////////////////////////////////////////// -// IOCTLs // +// Basic IOCTLs // ////////////////////////////////////////////////// /** @@ -74,119 +98,127 @@ * */ #define IOCTL_INIT_VMM \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASIC_IOCTL + 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, initialize the HyperTrace module * */ #define IOCTL_INIT_HYPERTRACE \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASIC_IOCTL + 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, register a new event * */ #define IOCTL_REGISTER_EVENT \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASIC_IOCTL + 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, irp pending mechanism for reading from message tracing buffers * */ #define IOCTL_RETURN_IRP_PENDING_PACKETS_AND_DISALLOW_IOCTL \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x10, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASIC_IOCTL + 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS) + +////////////////////////////////////////////////// +// KD IOCTLs // +////////////////////////////////////////////////// + +////////////////////////////////////////////////// +// VMM IOCTLs // +////////////////////////////////////////////////// /** * @brief ioctl, to terminate vmx and exit form debugger * */ #define IOCTL_TERMINATE_VMX \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x12, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, request to read memory * */ #define IOCTL_DEBUGGER_READ_MEMORY \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x13, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, request to read or write on a special MSR * */ #define IOCTL_DEBUGGER_READ_OR_WRITE_MSR \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x14, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, request to read page table entries * */ #define IOCTL_DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x15, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x05, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, register an event * */ #define IOCTL_DEBUGGER_REGISTER_EVENT \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x16, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x06, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, add action to event * */ #define IOCTL_DEBUGGER_ADD_ACTION_TO_EVENT \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x17, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x07, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, request to enable or disable transparent-mode * */ #define IOCTL_DEBUGGER_HIDE_AND_UNHIDE_TO_TRANSPARENT_THE_DEBUGGER \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x18, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x08, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, for !va2pa and !pa2va commands * */ #define IOCTL_DEBUGGER_VA2PA_AND_PA2VA_COMMANDS \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x19, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x09, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, request to edit virtual and physical memory * */ #define IOCTL_DEBUGGER_EDIT_MEMORY \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x1a, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x0a, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, request to search virtual and physical memory * */ #define IOCTL_DEBUGGER_SEARCH_MEMORY \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x1b, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x0b, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, request to modify an event (enable/disable/clear) * */ #define IOCTL_DEBUGGER_MODIFY_EVENTS \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x1c, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x0c, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, flush the kernel buffers * */ #define IOCTL_DEBUGGER_FLUSH_LOGGING_BUFFERS \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x1d, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x0d, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, attach or detach user-mode processes * */ #define IOCTL_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x1e, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x0e, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, print states (Deprecated) @@ -194,186 +226,190 @@ * */ #define IOCTL_DEBUGGER_PRINT \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x1f, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x0f, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, prepare debuggee * */ #define IOCTL_PREPARE_DEBUGGEE \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x20, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x10, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, pause and halt the system * */ #define IOCTL_PAUSE_PACKET_RECEIVED \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x21, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x11, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, send a signal that execution of command finished * */ #define IOCTL_SEND_SIGNAL_EXECUTION_IN_DEBUGGEE_FINISHED \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x22, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x12, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, send user-mode messages to the debugger * */ #define IOCTL_SEND_USERMODE_MESSAGES_TO_DEBUGGER \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x23, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x13, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, send general buffer from debuggee to debugger * */ #define IOCTL_SEND_GENERAL_BUFFER_FROM_DEBUGGEE_TO_DEBUGGER \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x24, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x14, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, to perform kernel-side tests * */ #define IOCTL_PERFORM_KERNEL_SIDE_TESTS \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x25, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x15, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, to reserve pre-allocated pools * */ #define IOCTL_RESERVE_PRE_ALLOCATED_POOLS \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x26, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x16, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, to send user debugger commands * */ #define IOCTL_SEND_USER_DEBUGGER_COMMANDS \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x27, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x17, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, to get active threads/processes that are debugging * */ #define IOCTL_GET_DETAIL_OF_ACTIVE_THREADS_AND_PROCESSES \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x28, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x18, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, to get user mode modules details * */ #define IOCTL_GET_USER_MODE_MODULE_DETAILS \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x29, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x19, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, query count of active threads or processes * */ #define IOCTL_QUERY_COUNT_OF_ACTIVE_PROCESSES_OR_THREADS \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x2a, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x1a, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, to get list threads/processes * */ #define IOCTL_GET_LIST_OF_THREADS_AND_PROCESSES \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x2b, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x1b, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, query the current process details * */ #define IOCTL_QUERY_CURRENT_PROCESS \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x2c, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x1c, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, query the current thread details * */ #define IOCTL_QUERY_CURRENT_THREAD \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x2d, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x1d, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, request service from the reversing machine * */ #define IOCTL_REQUEST_REV_MACHINE_SERVICE \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x2e, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x1e, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, request to bring pages in * */ #define IOCTL_DEBUGGER_BRING_PAGES_IN \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x2f, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x1f, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, to preactivate a functionality * */ #define IOCTL_PREACTIVATE_FUNCTIONALITY \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x30, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x20, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, to enumerate PCIe endpoints * */ #define IOCTL_PCIE_ENDPOINT_ENUM \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x31, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x21, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, to perform actions related to APIC * */ #define IOCTL_PERFORM_ACTIONS_ON_APIC \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x32, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x22, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, to query for PCI endpoint info * */ #define IOCTL_PCIDEVINFO_ENUM \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x33, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x23, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, to query the IDT entries * */ #define IOCTL_QUERY_IDT_ENTRY \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x34, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x24, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, to set breakpoint for the user debugger * */ #define IOCTL_SET_BREAKPOINT_USER_DEBUGGER \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x35, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x26, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, to perform SMI operations * */ #define IOCTL_PERFORM_SMI_OPERATION \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x36, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x27, METHOD_BUFFERED, FILE_ANY_ACCESS) + +////////////////////////////////////////////////// +// HyperTrace IOCTLs // +////////////////////////////////////////////////// /** * @brief ioctl, to perform HyperTrace LBR operations * */ #define IOCTL_PERFORM_HYPERTRACE_LBR_OPERATION \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x37, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_HYPERTRACE_IOCTL + 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, to perform HyperTrace LBR dump * */ #define IOCTL_PERFORM_HYPERTRACE_LBR_DUMP \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x38, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_HYPERTRACE_IOCTL + 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS) /** * @brief ioctl, to perform HyperTrace PT operations * */ #define IOCTL_PERFORM_HYPERTRACE_PT_OPERATION \ - CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_START_CODE + 0x39, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_HYPERTRACE_IOCTL + 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS) diff --git a/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h b/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h index b24083d5..a82400cc 100644 --- a/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h +++ b/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h @@ -756,25 +756,6 @@ ReadPhysicalMemoryUsingMapIoSpace(PVOID PhysicalAddress, PVOID Buffer, SIZE_T Bu IMPORT_EXPORT_VMM BOOLEAN WritePhysicalMemoryUsingMapIoSpace(PVOID PhysicalAddress, PVOID Buffer, SIZE_T BufferSize); -////////////////////////////////////////////////// -// Pool Manager // -////////////////////////////////////////////////// - -IMPORT_EXPORT_VMM BOOLEAN -PoolManagerCheckAndPerformAllocationAndDeallocation(); - -IMPORT_EXPORT_VMM BOOLEAN -PoolManagerRequestAllocation(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention); - -IMPORT_EXPORT_VMM UINT64 -PoolManagerRequestPool(POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPool, UINT32 Size); - -IMPORT_EXPORT_VMM BOOLEAN -PoolManagerFreePool(UINT64 AddressToFree); - -IMPORT_EXPORT_VMM VOID -PoolManagerShowPreAllocatedPools(); - ////////////////////////////////////////////////// // VMX Registers Modification // ////////////////////////////////////////////////// diff --git a/hyperdbg/include/SDK/imports/user/HyperDbgLibImports.h b/hyperdbg/include/SDK/imports/user/HyperDbgLibImports.h index 0a3dea02..68a529d1 100644 --- a/hyperdbg/include/SDK/imports/user/HyperDbgLibImports.h +++ b/hyperdbg/include/SDK/imports/user/HyperDbgLibImports.h @@ -11,19 +11,19 @@ #pragma once #ifdef _WIN32 - // MSVC (Windows) -# ifdef HYPERDBG_LIBHYPERDBG -# define IMPORT_EXPORT_LIBHYPERDBG __declspec(dllexport) -# else -# define IMPORT_EXPORT_LIBHYPERDBG __declspec(dllimport) -# endif +// MSVC (Windows) +# ifdef HYPERDBG_LIBHYPERDBG +# define IMPORT_EXPORT_LIBHYPERDBG __declspec(dllexport) +# else +# define IMPORT_EXPORT_LIBHYPERDBG __declspec(dllimport) +# endif #else - // GCC/Clang (Linux) -# ifdef HYPERDBG_LIBHYPERDBG -# define IMPORT_EXPORT_LIBHYPERDBG __attribute__((visibility("default"))) -# else -# define IMPORT_EXPORT_LIBHYPERDBG -# endif +// GCC/Clang (Linux) +# ifdef HYPERDBG_LIBHYPERDBG +# define IMPORT_EXPORT_LIBHYPERDBG __attribute__((visibility("default"))) +# else +# define IMPORT_EXPORT_LIBHYPERDBG +# endif #endif // // Header file of libhyperdbg @@ -60,6 +60,9 @@ hyperdbg_u_install_kd_driver(); IMPORT_EXPORT_LIBHYPERDBG INT hyperdbg_u_uninstall_kd_driver(); +IMPORT_EXPORT_LIBHYPERDBG INT +hyperdbg_u_start_kd_driver(); + IMPORT_EXPORT_LIBHYPERDBG INT hyperdbg_u_stop_kd_driver(); diff --git a/hyperdbg/include/SDK/modules/VMM.h b/hyperdbg/include/SDK/modules/VMM.h index ed20c43c..0b818ab3 100644 --- a/hyperdbg/include/SDK/modules/VMM.h +++ b/hyperdbg/include/SDK/modules/VMM.h @@ -82,6 +82,24 @@ typedef BOOLEAN (*DEBUGGING_CALLBACK_HANDLE_DEBUG_BREAKPOINT_EXCEPTION)(UINT32 C */ typedef BOOLEAN (*DEBUGGING_CALLBACK_CHECK_THREAD_INTERCEPTION)(UINT32 CoreId); +/** + * @brief Request pool allocation + * + */ +typedef BOOLEAN (*POOL_MANAGER_REQUEST_ALLOCATION)(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention); + +/** + * @brief Request pool + * + */ +typedef UINT64 (*POOL_MANAGER_REQUEST_POOL)(POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPool, UINT32 Size); + +/** + * @brief Free pool + * + */ +typedef BOOLEAN (*POOL_MANAGER_FREE_POOL)(UINT64 AddressToFree); + /** * @brief Handle registered MTF callback * @@ -202,6 +220,13 @@ typedef struct _VMM_CALLBACKS DEBUGGING_CALLBACK_HANDLE_DEBUG_BREAKPOINT_EXCEPTION DebuggingCallbackHandleDebugBreakpointException; // Fixed DEBUGGING_CALLBACK_CHECK_THREAD_INTERCEPTION DebuggingCallbackCheckThreadInterception; // Fixed + // + // Pool manager callbacks + // + POOL_MANAGER_REQUEST_ALLOCATION PoolManagerRequestAllocation; // Fixed + POOL_MANAGER_REQUEST_POOL PoolManagerRequestPool; // Fixed + POOL_MANAGER_FREE_POOL PoolManagerFreePool; // Fixed + // // Interception callbacks // diff --git a/hyperdbg/libhyperdbg/code/app/libhyperdbg.cpp b/hyperdbg/libhyperdbg/code/app/libhyperdbg.cpp index 47f0a72b..849ffa14 100644 --- a/hyperdbg/libhyperdbg/code/app/libhyperdbg.cpp +++ b/hyperdbg/libhyperdbg/code/app/libhyperdbg.cpp @@ -18,7 +18,7 @@ using namespace std; // extern HANDLE g_DeviceHandle; extern HANDLE g_IsDriverLoadedSuccessfully; -extern BOOLEAN g_IsVmxOffProcessStart; +extern BOOLEAN g_IsMessageLoggingWindowClosed; extern TCHAR g_DriverLocation[MAX_PATH]; extern TCHAR g_DriverName[MAX_PATH]; extern BOOLEAN g_UseCustomDriverLocation; @@ -27,6 +27,50 @@ extern BOOLEAN g_IsKdModuleLoaded; extern BOOLEAN g_IsVmmModuleLoaded; extern BOOLEAN g_IsHyperTraceModuleLoaded; +/** + * @brief Install (start) VMM driver + * + * @return INT return zero if it was successful or non-zero if there + * was error + */ +INT +HyperDbgStartDriver() +{ + if (!ManageDriver(g_DriverName, g_DriverLocation, DRIVER_FUNC_INSTALL)) + { + // + // 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 Install KD (Kernel Debugger) driver * @@ -70,14 +114,9 @@ HyperDbgInstallKdDriver() strcpy_s(g_DriverName, KERNEL_DEBUGGER_DRIVER_NAME); } - if (!ManageDriver(g_DriverName, g_DriverLocation, DRIVER_FUNC_INSTALL)) + if (HyperDbgStartDriver() != 0) { - ShowMessages("unable to install VMM driver\n"); - - // - // Error - remove driver - // - ManageDriver(g_DriverName, g_DriverLocation, DRIVER_FUNC_REMOVE); + ShowMessages("unable to install KD driver\n"); return 1; } @@ -86,25 +125,14 @@ HyperDbgInstallKdDriver() } /** - * @brief Stop the driver + * @brief Start KD driver * - * @return INT return zero if it was successful or non-zero if there - * was error + * @return INT return zero if it was successful or non-zero if there was error */ INT -HyperDbgStopDriver(LPCTSTR DriverName) +HyperDbgStartKdDriver() { - // - // Unload the driver if loaded - // - if (g_DriverLocation[0] != (TCHAR)0 && ManageDriver(DriverName, g_DriverLocation, DRIVER_FUNC_STOP)) - { - return 0; - } - else - { - return 1; - } + return HyperDbgStartDriver(); } /** @@ -296,7 +324,7 @@ HyperDbgCreateHandleFromKdModule() // Make sure that this variable is false, because it might be set to // true as the result of a previous load // - g_IsVmxOffProcessStart = FALSE; + g_IsMessageLoggingWindowClosed = FALSE; // // Init entering vmx @@ -394,14 +422,40 @@ HyperDbgUnloadVmm() return 1; } + // + // Hypervisor (VMM) module is not loaded anymore + // + g_IsVmmModuleLoaded = FALSE; + + ShowMessages("you're not on HyperDbg's hypervisor anymore!\n"); + + return 0; +} + +/** + * @brief Unload KD driver + * + * @return INT return zero if it was successful or non-zero if there was error + */ +INT +HyperDbgUnloadKd() +{ + BOOL Status; + DWORD BytesReturned; + + AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnOne); + + // + // Indicate that the message logging window is closed + // + g_IsMessageLoggingWindowClosed = TRUE; + // // 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 + IOCTL_RETURN_IRP_PENDING_PACKETS_AND_DISALLOW_IOCTL, // 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) @@ -421,29 +475,9 @@ HyperDbgUnloadVmm() } // - // Indicate that the finish process start or not + // Wait for a while to make sure that all IRP pending are completed and the driver is ready to be unloaded // - g_IsVmxOffProcessStart = TRUE; - - // - // Hypervisor (VMM) module is not loaded anymore - // - g_IsVmmModuleLoaded = FALSE; - - ShowMessages("you're not on HyperDbg's hypervisor anymore!\n"); - - return 0; -} - -/** - * @brief Unload KD driver - * - * @return INT return zero if it was successful or non-zero if there was error - */ -INT -HyperDbgUnloadKd() -{ - AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnOne); + Sleep(1000); // // Send IRP_MJ_CLOSE to driver to terminate Vmxs diff --git a/hyperdbg/libhyperdbg/code/app/packets.cpp b/hyperdbg/libhyperdbg/code/app/packets.cpp index 3d74854d..e7a39339 100644 --- a/hyperdbg/libhyperdbg/code/app/packets.cpp +++ b/hyperdbg/libhyperdbg/code/app/packets.cpp @@ -18,7 +18,7 @@ using namespace std; // extern HANDLE g_DeviceHandle; extern HANDLE g_IsDriverLoadedSuccessfully; -extern BOOLEAN g_IsVmxOffProcessStart; +extern BOOLEAN g_IsMessageLoggingWindowClosed; extern BOOLEAN g_BreakPrintingOutput; extern BOOLEAN g_OutputSourcesInitialized; @@ -87,245 +87,227 @@ ReadIrpBasedBuffer() try { - while (TRUE) + while (!g_IsMessageLoggingWindowClosed) { - 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) { // - // Clear the buffer + // Error occurred for second time, and we show the error message // - ZeroMemory(OutputBuffer, UsermodeBufferSize); + // ShowMessages("ioctl failed with code 0x%x\n", GetLastError()); - 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 we reach here, the packet is probably failed, it might + // be because of using flush command + // + continue; + } - if (!Status) + // + // 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) { // - // 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 + // means that the user asserts a CTRL+C or CTRL+BREAK Signal + // we shouldn't show or save anything in this case // continue; } - // - // Compute the received buffer's operation code - // - memcpy(&OperationCode, OutputBuffer, sizeof(UINT32)); + ShowMessages("%s", OutputBuffer + sizeof(UINT32)); - // ShowMessages("Returned Length : 0x%x \n", ReturnedLength); - // ShowMessages("Operation Code : 0x%x \n", OperationCode); + break; - // - // 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) + case OPERATION_LOG_MESSAGE_MANDATORY: + + ShowMessages("%s", OutputBuffer + sizeof(UINT32)); + + break; + + case OPERATION_LOG_INFO_MESSAGE: + + if (g_BreakPrintingOutput) { - Sleep(DefaultSpeedOfReadingKernelMessages); // we're not trying to eat all of the CPU ;) + // + // means that the user asserts a CTRL+C or CTRL+BREAK Signal + // we shouldn't show or save anything in this case + // + continue; } - switch (OperationCode) + ShowMessages("%s", OutputBuffer + sizeof(UINT32)); + + break; + + case OPERATION_LOG_ERROR_MESSAGE: + if (g_BreakPrintingOutput) { - 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 + // means that the user asserts a CTRL+C or CTRL+BREAK Signal + // we shouldn't show or save anything in this case // - 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()); + continue; } - return; + 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 + // it will just end the thread at next round because of the check of + // g_IsMessageLoggingWindowClosed at the beginning of the loop + // + 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; } } } @@ -337,12 +319,12 @@ ReadIrpBasedBuffer() free(OutputBuffer); // - // closeHandle + // close handle // if (!CloseHandle(Handle)) { ShowMessages("err, closing handle 0x%x\n", GetLastError()); - }; + } } /** diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/unload.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/unload.cpp index 255e91ce..86a66b9d 100644 --- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/unload.cpp +++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/unload.cpp @@ -85,10 +85,12 @@ CommandUnload(vector CommandTokens, string Command) if (g_IsVmmModuleLoaded) { HyperDbgUnloadVmm(); + + HyperDbgUnloadKd(); // Tessssssssssssssssssssssttttttttttt } else { - ShowMessages("there is nothing to unload\n"); + ShowMessages("the vmm module is not loadedd\n"); } // @@ -99,11 +101,12 @@ CommandUnload(vector CommandTokens, string Command) // // Unload the KD module // - if (HyperDbgUnloadKd()) - { - ShowMessages("err, failed to unload the kd (kernel debugger) driver\n"); - return; - } + + // if (HyperDbgUnloadKd()) + // { + // ShowMessages("err, failed to unload the kd (kernel debugger) driver\n"); + // return; + // } // // Stop the driver diff --git a/hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp b/hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp index fdc35c08..72b1a3ff 100644 --- a/hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp +++ b/hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp @@ -626,6 +626,16 @@ ShowErrorMessage(UINT32 Error) Error); break; + case DEBUGGER_ERROR_VMM_CANNOT_BE_INITIALIZED_IF_DEBUGGER_IS_NOT_LOADED: + ShowMessages("err, the VMM module cannot be initialized because the debugger is not loaded (%x)\n", + Error); + break; + + case DEBUGGER_ERROR_CANNOT_INITIALIZE_DEBUGGER: + ShowMessages("err, cannot initialize the debugger (%x)\n", + Error); + break; + default: ShowMessages("err, error not found (%x)\n", Error); diff --git a/hyperdbg/libhyperdbg/code/export/export.cpp b/hyperdbg/libhyperdbg/code/export/export.cpp index 8328e978..72d74fd5 100644 --- a/hyperdbg/libhyperdbg/code/export/export.cpp +++ b/hyperdbg/libhyperdbg/code/export/export.cpp @@ -96,6 +96,17 @@ hyperdbg_u_uninstall_kd_driver() return HyperDbgUninstallKdDriver(); } +/** + * @brief Start the KD driver + * + * @return INT Returns 0 if it was successful and 1 if it was failed + */ +INT +hyperdbg_u_start_kd_driver() +{ + return HyperDbgStartKdDriver(); +} + /** * @brief Stop the KD driver * diff --git a/hyperdbg/libhyperdbg/header/globals.h b/hyperdbg/libhyperdbg/header/globals.h index 022fa9db..7838e15b 100644 --- a/hyperdbg/libhyperdbg/header/globals.h +++ b/hyperdbg/libhyperdbg/header/globals.h @@ -464,10 +464,10 @@ PVOID g_MessageHandler = 0; PVOID g_MessageHandlerSharedBuffer = 0; /** - * @brief Shows whether the vmxoff process start or not + * @brief Shows whether the message logging window is closed or not * */ -BOOLEAN g_IsVmxOffProcessStart; +BOOLEAN g_IsMessageLoggingWindowClosed; /** * @brief Holds the global handle of device which is used diff --git a/hyperdbg/libhyperdbg/header/libhyperdbg.h b/hyperdbg/libhyperdbg/header/libhyperdbg.h index 6d83b73c..ef0937d8 100644 --- a/hyperdbg/libhyperdbg/header/libhyperdbg.h +++ b/hyperdbg/libhyperdbg/header/libhyperdbg.h @@ -39,6 +39,9 @@ HyperDbgLoadVmmModule(); INT HyperDbgLoadHyperTraceModule(); +INT +HyperDbgStartKdDriver(); + INT HyperDbgStopKdDriver();