Merge pull request #603 from HyperDbg/trace-module
Some checks failed
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled

Trace module
This commit is contained in:
Sina Karvandi 2026-06-06 00:34:16 +02:00 committed by GitHub
commit 67d8d461bd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
39 changed files with 1392 additions and 808 deletions

View file

@ -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.

View file

@ -106,7 +106,7 @@ DrvUnload(PDRIVER_OBJECT DriverObject)
//
// Unloading VMM and Debugger
//
LoaderUninitializeLogTracer();
LoaderUninitLogTracer();
}
/**

View file

@ -36,7 +36,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
//
PoolManagerCheckAndPerformAllocationAndDeallocation();
if (g_AllowIoctlFromUsermode)
if (g_VmmInitialized)
{
IrpStack = IoGetCurrentIrpStackLocation(Irp);

View file

@ -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");

View file

@ -17,7 +17,7 @@
//////////////////////////////////////////////////
VOID
LoaderUninitializeLogTracer();
LoaderUninitLogTracer();
BOOLEAN
LoaderInitVmmAndReversingMachine();

View file

@ -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;

View file

@ -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");
}

View file

@ -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
*

View file

@ -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
{

View file

@ -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
//

View file

@ -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
//

View file

@ -165,7 +165,6 @@
<ClCompile Include="code\memory\Layout.c" />
<ClCompile Include="code\memory\MemoryManager.c" />
<ClCompile Include="code\memory\MemoryMapper.c" />
<ClCompile Include="code\memory\PoolManager.c" />
<ClCompile Include="code\memory\Segmentation.c" />
<ClCompile Include="code\memory\SwitchLayout.c" />
<ClCompile Include="code\mmio\MmioShadowing.c" />
@ -272,7 +271,6 @@
<ClInclude Include="header\memory\Conversion.h" />
<ClInclude Include="header\memory\Layout.h" />
<ClInclude Include="header\memory\MemoryMapper.h" />
<ClInclude Include="header\memory\PoolManager.h" />
<ClInclude Include="header\memory\Segmentation.h" />
<ClInclude Include="header\memory\SwitchLayout.h" />
<ClInclude Include="header\mmio\MmioShadowing.h" />

View file

@ -203,9 +203,6 @@
<ClCompile Include="code\memory\MemoryMapper.c">
<Filter>code\memory</Filter>
</ClCompile>
<ClCompile Include="code\memory\PoolManager.c">
<Filter>code\memory</Filter>
</ClCompile>
<ClCompile Include="code\components\registers\DebugRegisters.c">
<Filter>code\components\registers</Filter>
</ClCompile>
@ -394,9 +391,6 @@
<ClInclude Include="header\memory\MemoryMapper.h">
<Filter>header\memory</Filter>
</ClInclude>
<ClInclude Include="header\memory\PoolManager.h">
<Filter>header\memory</Filter>
</ClInclude>
<ClInclude Include="header\vmm\vmx\VmxMechanisms.h">
<Filter>header\vmm\vmx</Filter>
</ClInclude>

View file

@ -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"

View file

@ -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

View file

@ -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;
}

View file

@ -103,7 +103,7 @@ DrvUnload(PDRIVER_OBJECT DriverObject)
//
// Unloading Log Tracer
//
LoaderUninitializeLogTracer();
LoaderUninitLogTracer();
}
/**

View file

@ -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;

View file

@ -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

View file

@ -188,9 +188,21 @@ DebuggerGetLastError();
VOID
DebuggerSetLastError(UINT32 LastError);
BOOLEAN
DebuggerInitializeScriptEngine();
BOOLEAN
DebuggerInitializeTrapsAndBreakpoints();
BOOLEAN
DebuggerInitializeVmmOperations();
BOOLEAN
DebuggerInitialize();
VOID
DebuggerUninitializeVmmOperations();
VOID
DebuggerUninitialize();

View file

@ -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);

View file

@ -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);

View file

@ -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();

View file

@ -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

View file

@ -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"

View file

@ -137,6 +137,7 @@
<ClCompile Include="code\debugger\events\ValidateEvents.c" />
<ClCompile Include="code\debugger\kernel-level\Kd.c" />
<ClCompile Include="code\debugger\memory\Allocations.c" />
<ClCompile Include="code\debugger\memory\PoolManager.c" />
<ClCompile Include="code\debugger\meta-events\MetaDispatch.c" />
<ClCompile Include="code\debugger\meta-events\Tracing.c" />
<ClCompile Include="code\debugger\objects\Process.c" />
@ -185,6 +186,7 @@
<ClInclude Include="header\debugger\kernel-level\Kd.h" />
<ClInclude Include="header\debugger\memory\Allocations.h" />
<ClInclude Include="header\debugger\memory\Memory.h" />
<ClInclude Include="header\debugger\memory\PoolManager.h" />
<ClInclude Include="header\debugger\meta-events\MetaDispatch.h" />
<ClInclude Include="header\debugger\meta-events\Tracing.h" />
<ClInclude Include="header\debugger\objects\Process.h" />

View file

@ -279,6 +279,9 @@
<ClCompile Include="..\include\platform\kernel\code\PlatformCpu.c">
<Filter>code\platform</Filter>
</ClCompile>
<ClCompile Include="code\debugger\memory\PoolManager.c">
<Filter>code\debugger\memory</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="header\pch.h">
@ -422,6 +425,9 @@
<ClInclude Include="..\include\platform\kernel\header\PlatformCpu.h">
<Filter>header\platform</Filter>
</ClInclude>
<ClInclude Include="header\debugger\memory\PoolManager.h">
<Filter>header\debugger\memory</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<MASM Include="code\assembly\AsmDebugger.asm">

View file

@ -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)

View file

@ -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)

View file

@ -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 //
//////////////////////////////////////////////////

View file

@ -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();

View file

@ -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
//

View file

@ -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

View file

@ -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());
};
}
}
/**

View file

@ -85,10 +85,12 @@ CommandUnload(vector<CommandToken> 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<CommandToken> 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

View file

@ -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);

View file

@ -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
*

View file

@ -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

View file

@ -39,6 +39,9 @@ HyperDbgLoadVmmModule();
INT
HyperDbgLoadHyperTraceModule();
INT
HyperDbgStartKdDriver();
INT
HyperDbgStopKdDriver();