diff --git a/CHANGELOG.md b/CHANGELOG.md index 677a7c1a..89a9adf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 New release of the HyperDbg Debugger. ### Added +- Added structure for the hyperperf (Hardware Performance Counter) project ### Changed +- Separated SDK libraries for user mode and kernel mode modules +- Added hypertrace, hyperevade, and hyperperf DLL files to SDK ## [0.20.0.0-beta] - 2026-06-21 New release of the HyperDbg Debugger. diff --git a/hyperdbg/hyperdbg-cli/hyperdbg-cli.vcxproj b/hyperdbg/hyperdbg-cli/hyperdbg-cli.vcxproj index 958dcc98..5b16f0d4 100644 --- a/hyperdbg/hyperdbg-cli/hyperdbg-cli.vcxproj +++ b/hyperdbg/hyperdbg-cli/hyperdbg-cli.vcxproj @@ -84,14 +84,19 @@ xcopy /E /I /Y "$(SolutionDir)include\SDK" "$(OutDir)SDK" xcopy /E /I /Y "$(SolutionDir)..\examples" "$(OutDir)SDK\examples" mkdir "$(OutDir)SDK\libraries" -copy "$(OutDir)pdbex.lib" "$(OutDir)SDK\libraries\pdbex.lib" -copy "$(OutDir)kdserial.lib" "$(OutDir)SDK\libraries\kdserial.lib" -copy "$(OutDir)libhyperdbg.dll" "$(OutDir)SDK\libraries\libhyperdbg.dll" -copy "$(OutDir)script-engine.dll" "$(OutDir)SDK\libraries\script-engine.dll" -copy "$(OutDir)symbol-parser.dll" "$(OutDir)SDK\libraries\symbol-parser.dll" -copy "$(OutDir)hyperlog.dll" "$(OutDir)SDK\libraries\hyperlog.dll" -copy "$(OutDir)hyperhv.dll" "$(OutDir)SDK\libraries\hyperhv.dll" -copy "$(OutDir)libipt.dll" "$(OutDir)SDK\libraries\libipt.dll" +mkdir "$(OutDir)SDK\libraries\kernel" +mkdir "$(OutDir)SDK\libraries\user" +copy "$(OutDir)pdbex.dll" "$(OutDir)SDK\libraries\user\pdbex.dll" +copy "$(OutDir)libipt.dll" "$(OutDir)SDK\libraries\user\libipt.dll" +copy "$(OutDir)script-engine.dll" "$(OutDir)SDK\libraries\user\script-engine.dll" +copy "$(OutDir)symbol-parser.dll" "$(OutDir)SDK\libraries\user\symbol-parser.dll" +copy "$(OutDir)libhyperdbg.dll" "$(OutDir)SDK\libraries\user\libhyperdbg.dll" +copy "$(OutDir)hyperlog.dll" "$(OutDir)SDK\libraries\kernel\hyperlog.dll" +copy "$(OutDir)hyperhv.dll" "$(OutDir)SDK\libraries\kernel\hyperhv.dll" +copy "$(OutDir)hypertrace.dll" "$(OutDir)SDK\libraries\kernel\hyperevade.dll" +copy "$(OutDir)hypertrace.dll" "$(OutDir)SDK\libraries\kernel\hypertrace.dll" +copy "$(OutDir)hyperperf.dll" "$(OutDir)SDK\libraries\kernel\hyperperf.dll" +copy "$(OutDir)kdserial.dll" "$(OutDir)SDK\libraries\kernel\kdserial.dll" if exist "$(OutDir)constants\" rd /q /s "$(OutDir)constants\" mkdir "$(OutDir)constants" copy "$(SolutionDir)miscellaneous\constants\pciid\pci.ids" "$(OutDir)constants\pci.ids" @@ -129,14 +134,19 @@ copy "$(SolutionDir)miscellaneous\constants\pciid\pci.ids" "$(OutDir)constants\p xcopy /E /I /Y "$(SolutionDir)include\SDK" "$(OutDir)SDK" xcopy /E /I /Y "$(SolutionDir)..\examples" "$(OutDir)SDK\examples" mkdir "$(OutDir)SDK\libraries" -copy "$(OutDir)pdbex.lib" "$(OutDir)SDK\libraries\pdbex.lib" -copy "$(OutDir)kdserial.lib" "$(OutDir)SDK\libraries\kdserial.lib" -copy "$(OutDir)libhyperdbg.dll" "$(OutDir)SDK\libraries\libhyperdbg.dll" -copy "$(OutDir)script-engine.dll" "$(OutDir)SDK\libraries\script-engine.dll" -copy "$(OutDir)symbol-parser.dll" "$(OutDir)SDK\libraries\symbol-parser.dll" -copy "$(OutDir)hyperlog.dll" "$(OutDir)SDK\libraries\hyperlog.dll" -copy "$(OutDir)hyperhv.dll" "$(OutDir)SDK\libraries\hyperhv.dll" -copy "$(OutDir)libipt.dll" "$(OutDir)SDK\libraries\libipt.dll" +mkdir "$(OutDir)SDK\libraries\kernel" +mkdir "$(OutDir)SDK\libraries\user" +copy "$(OutDir)pdbex.dll" "$(OutDir)SDK\libraries\user\pdbex.dll" +copy "$(OutDir)libipt.dll" "$(OutDir)SDK\libraries\user\libipt.dll" +copy "$(OutDir)script-engine.dll" "$(OutDir)SDK\libraries\user\script-engine.dll" +copy "$(OutDir)symbol-parser.dll" "$(OutDir)SDK\libraries\user\symbol-parser.dll" +copy "$(OutDir)libhyperdbg.dll" "$(OutDir)SDK\libraries\user\libhyperdbg.dll" +copy "$(OutDir)hyperlog.dll" "$(OutDir)SDK\libraries\kernel\hyperlog.dll" +copy "$(OutDir)hyperhv.dll" "$(OutDir)SDK\libraries\kernel\hyperhv.dll" +copy "$(OutDir)hypertrace.dll" "$(OutDir)SDK\libraries\kernel\hyperevade.dll" +copy "$(OutDir)hypertrace.dll" "$(OutDir)SDK\libraries\kernel\hypertrace.dll" +copy "$(OutDir)hyperperf.dll" "$(OutDir)SDK\libraries\kernel\hyperperf.dll" +copy "$(OutDir)kdserial.dll" "$(OutDir)SDK\libraries\kernel\kdserial.dll" if exist "$(OutDir)constants\" rd /q /s "$(OutDir)constants\" mkdir "$(OutDir)constants" copy "$(SolutionDir)miscellaneous\constants\pciid\pci.ids" "$(OutDir)constants\pci.ids" diff --git a/hyperdbg/hyperdbg.sln b/hyperdbg/hyperdbg.sln index fff4dc56..9d71b79f 100644 --- a/hyperdbg/hyperdbg.sln +++ b/hyperdbg/hyperdbg.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.2.32602.215 +# Visual Studio Version 18 +VisualStudioVersion = 18.7.11911.148 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperdbg-cli", "hyperdbg-cli\hyperdbg-cli.vcxproj", "{FBCBBBAD-4EAE-469E-827F-F59FE9E7375B}" ProjectSection(ProjectDependencies) = postProject @@ -90,6 +90,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "imports", "imports", "{B3D9 EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperkd", "hyperkd\hyperkd.vcxproj", "{AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}" ProjectSection(ProjectDependencies) = postProject + {360E54B1-0B92-4BCA-8111-4BF384292621} = {360E54B1-0B92-4BCA-8111-4BF384292621} {9FA45E25-DAEB-4C2D-806C-7908A180195D} = {9FA45E25-DAEB-4C2D-806C-7908A180195D} {AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D} = {AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D} {BB17323A-2460-4AE1-8AFE-B367400B934F} = {BB17323A-2460-4AE1-8AFE-B367400B934F} @@ -101,6 +102,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{13E4 ProjectSection(SolutionItems) = preProject include\SDK\modules\HyperEvade.h = include\SDK\modules\HyperEvade.h include\SDK\Modules\HyperLog.h = include\SDK\Modules\HyperLog.h + include\SDK\modules\HyperPerf.h = include\SDK\modules\HyperPerf.h include\SDK\modules\HyperTrace.h = include\SDK\modules\HyperTrace.h include\SDK\Modules\VMM.h = include\SDK\Modules\VMM.h EndProjectSection @@ -207,6 +209,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "kernel", "kernel", "{947577 include\SDK\imports\kernel\HyperDbgHyperEvade.h = include\SDK\imports\kernel\HyperDbgHyperEvade.h include\SDK\Imports\Kernel\HyperDbgHyperLogImports.h = include\SDK\Imports\Kernel\HyperDbgHyperLogImports.h include\SDK\Imports\Kernel\HyperDbgHyperLogIntrinsics.h = include\SDK\Imports\Kernel\HyperDbgHyperLogIntrinsics.h + include\SDK\imports\kernel\HyperDbgHyperPerf.h = include\SDK\imports\kernel\HyperDbgHyperPerf.h include\SDK\imports\kernel\HyperDbgHyperTrace.h = include\SDK\imports\kernel\HyperDbgHyperTrace.h include\SDK\Imports\Kernel\HyperDbgVmmImports.h = include\SDK\Imports\Kernel\HyperDbgVmmImports.h EndProjectSection @@ -327,6 +330,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "header", "header", "{CA2D9C include\components\pe\header\pe-image-reader.h = include\components\pe\header\pe-image-reader.h EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperperf", "hyperperf\hyperperf.vcxproj", "{360E54B1-0B92-4BCA-8111-4BF384292621}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution debug|x64 = debug|x64 @@ -384,6 +389,12 @@ Global {9FA45E25-DAEB-4C2D-806C-7908A180195D}.debug|x64.Build.0 = debug|x64 {9FA45E25-DAEB-4C2D-806C-7908A180195D}.release|x64.ActiveCfg = release|x64 {9FA45E25-DAEB-4C2D-806C-7908A180195D}.release|x64.Build.0 = release|x64 + {360E54B1-0B92-4BCA-8111-4BF384292621}.debug|x64.ActiveCfg = debug|x64 + {360E54B1-0B92-4BCA-8111-4BF384292621}.debug|x64.Build.0 = debug|x64 + {360E54B1-0B92-4BCA-8111-4BF384292621}.debug|x64.Deploy.0 = debug|x64 + {360E54B1-0B92-4BCA-8111-4BF384292621}.release|x64.ActiveCfg = release|x64 + {360E54B1-0B92-4BCA-8111-4BF384292621}.release|x64.Build.0 = release|x64 + {360E54B1-0B92-4BCA-8111-4BF384292621}.release|x64.Deploy.0 = release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/hyperdbg/hyperperf/CMakeLists.txt b/hyperdbg/hyperperf/CMakeLists.txt new file mode 100644 index 00000000..d6b1310f --- /dev/null +++ b/hyperdbg/hyperperf/CMakeLists.txt @@ -0,0 +1,22 @@ +# Code generated by Visual Studio kit, DO NOT EDIT. +set(SourceFiles + "../include/components/spinlock/code/Spinlock.c" + "../include/platform/kernel/code/PlatformMem.c" + "code/Logging.c" + "code/UnloadDll.c" + "../include/components/spinlock/header/Spinlock.h" + "../include/platform/kernel/header/Environment.h" + "../include/platform/kernel/header/PlatformMem.h" + "header/Logging.h" + "header/pch.h" + "header/UnloadDll.h" + "hyperperf.def" +) +include_directories( + "../include" + "header" +) +wdk_add_library(hyperperf SHARED + KMDF 1.15 + ${SourceFiles} +) diff --git a/hyperdbg/hyperperf/code/api/PerfApi.c b/hyperdbg/hyperperf/code/api/PerfApi.c new file mode 100644 index 00000000..59cef4c4 --- /dev/null +++ b/hyperdbg/hyperperf/code/api/PerfApi.c @@ -0,0 +1,84 @@ +/** + * @file PerfApi.c + * @author Sina Karvandi (sina@hyperdbg.org) + * @brief PMU routines for HyperPerf module + * @details + * @version 0.21 + * @date 2026-06-22 + * + * @copyright This project is released under the GNU Public License v3. + */ +#include "pch.h" + +/** + * @brief Initialize the hyperperf module callbacks + * @details This only for callback initialization, not for PMU, etc. initialization + * + * @param HyperPerfCallbacks Pointer to the HyperPerf callbacks structure to be registered + * @param RunningOnHypervisorEnvironment Whether the initialization is being done for hypervisor environment or not, + * it can be used to skip some of the initialization steps if it is not for hypervisor environment and behave differently based on that + * + * @return BOOLEAN + */ +BOOLEAN +HyperPerfInitCallback(HYPERPERF_CALLBACKS * HyperPerfCallbacks, + BOOLEAN RunningOnHypervisorEnvironment) +{ + // + // Check if any of the required callbacks are NULL + // + for (UINT32 i = 0; i < sizeof(HYPERPERF_CALLBACKS) / sizeof(UINT64); i++) + { + if (((PVOID *)HyperPerfCallbacks)[i] == NULL) + { + // + // The callback has null entry, so we cannot proceed + // + return FALSE; + } + } + + // + // Save the callbacks + // + PlatformWriteMemory(&g_Callbacks, HyperPerfCallbacks, sizeof(HYPERPERF_CALLBACKS)); + + // + // Set the flag to indicate whether the initialization is being done for hypervisor environment or not + // + g_RunningOnHypervisorEnvironment = RunningOnHypervisorEnvironment; + + // + // Enable callbacks and set the initialized flag + // + g_HyperPerfCallbacksInitialized = TRUE; + + return TRUE; +} + +/** + * @brief Uninitialize the hypertrace module + * + * @return VOID + */ +VOID +HyperPerfUninit() +{ + // + // Check if the callbacks are initialized, if not, we don't need to handle anymore + // + if (!g_HyperPerfCallbacksInitialized) + { + return; + } + + // + // Reset the environment flag to default value + // + g_RunningOnHypervisorEnvironment = FALSE; + + // + // Set callbacks to not initialized + // + g_HyperPerfCallbacksInitialized = FALSE; +} diff --git a/hyperdbg/hyperperf/code/broadcast/Broadcast.c b/hyperdbg/hyperperf/code/broadcast/Broadcast.c new file mode 100644 index 00000000..ad97bd34 --- /dev/null +++ b/hyperdbg/hyperperf/code/broadcast/Broadcast.c @@ -0,0 +1,26 @@ +/** + * @file Broadcast.c + * @author Sina Karvandi (sina@hyperdbg.org) + * @brief Broadcasting functions + * @details + * @version 0.21 + * @date 2026-06-22 + * + * @copyright This project is released under the GNU Public License v3. + * + */ +#include "pch.h" + +/** + * @brief Routines to enable LBR on all cores + * + * @return VOID + */ +VOID +BroadcastEnableLbrOnAllCores() +{ + // + // Broadcast to all cores + // + KeGenericCallDpc(DpcRoutineTestPmu, NULL); +} diff --git a/hyperdbg/hyperperf/code/broadcast/DpcRoutines.c b/hyperdbg/hyperperf/code/broadcast/DpcRoutines.c new file mode 100644 index 00000000..f5443618 --- /dev/null +++ b/hyperdbg/hyperperf/code/broadcast/DpcRoutines.c @@ -0,0 +1,35 @@ +/** + * @file DpcRoutines.c + * @author Sina Karvandi (sina@hyperdbg.org) + * @brief DPC routines + * @details + * @version 0.21 + * @date 2026-06-22 + * + * @copyright This project is released under the GNU Public License v3. + * + */ +#include "pch.h" + +/** + * @brief Broadcast enabling LBR + * + * @param Dpc + * @param DeferredContext + * @param SystemArgument1 + * @param SystemArgument2 + * @return BOOLEAN + */ +BOOLEAN +DpcRoutineTestPmu(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2) +{ + UNREFERENCED_PARAMETER(Dpc); + UNREFERENCED_PARAMETER(DeferredContext); + + // ------------------------------------------------------------------------------ + // Synchronize the end of this routine with the caller + // + PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2); + + return TRUE; +} diff --git a/hyperdbg/hyperperf/code/common/UnloadDll.c b/hyperdbg/hyperperf/code/common/UnloadDll.c new file mode 100644 index 00000000..17321dbf --- /dev/null +++ b/hyperdbg/hyperperf/code/common/UnloadDll.c @@ -0,0 +1,45 @@ +/** + * @file UnloadDll.c + * @author Sina Karvandi (sina@hyperdbg.org) + * @brief Unloading DLL in the target Windows + * @details + * @version 0.4 + * @date 2023-07-06 + * + * @copyright This project is released under the GNU Public License v3. + * + */ +#include "pch.h" + +// +// We'll add these functions, so whenever HyperDbg's driver is unloaded +// DllUnload will be called to unload this dll from the memory. +// this way we can remove the HyperDbg after unloading as there is no +// other module remains loaded in the memory. +// + +/** + * @brief Routine called on DLL initialization + * + * @param RegistryPath The registry path of the driver + * @return NTSTATUS + */ +NTSTATUS +DllInitialize( + _In_ PUNICODE_STRING RegistryPath) +{ + UNREFERENCED_PARAMETER(RegistryPath); + + return STATUS_SUCCESS; +} + +/** + * @brief Routine called on DLL unload + * + * @return NTSTATUS + */ +NTSTATUS +DllUnload(VOID) +{ + return STATUS_SUCCESS; +} diff --git a/hyperdbg/hyperperf/header/api/PerfApi.h b/hyperdbg/hyperperf/header/api/PerfApi.h new file mode 100644 index 00000000..660f4d20 --- /dev/null +++ b/hyperdbg/hyperperf/header/api/PerfApi.h @@ -0,0 +1,19 @@ +/** + * @file PerfApi.h + * @author + * @brief Header for general PMU routines for HyperPerf module + * @details + * @version 0.21 + * @date 2026-06-22 + * + * @copyright This project is released under the GNU Public License v3. + */ +#pragma once + +////////////////////////////////////////////////// +// Functions // +////////////////////////////////////////////////// + +// +// Most of the functions are defined and exported +// diff --git a/hyperdbg/hyperperf/header/broadcast/Broadcast.h b/hyperdbg/hyperperf/header/broadcast/Broadcast.h new file mode 100644 index 00000000..8698872f --- /dev/null +++ b/hyperdbg/hyperperf/header/broadcast/Broadcast.h @@ -0,0 +1,20 @@ + +/** + * @file Broadcast.h + * @author Sina Karvandi (sina@hyperdbg.org) + * @brief Headers for broadcasting functions + * @details + * @version 0.21 + * @date 2026-06-22 + * + * @copyright This project is released under the GNU Public License v3. + * + */ +#pragma once + +////////////////////////////////////////////////// +// Functions // +////////////////////////////////////////////////// + +VOID +BroadcastTestPmuOnAllCores(); diff --git a/hyperdbg/hyperperf/header/broadcast/DpcRoutines.h b/hyperdbg/hyperperf/header/broadcast/DpcRoutines.h new file mode 100644 index 00000000..397ef8b1 --- /dev/null +++ b/hyperdbg/hyperperf/header/broadcast/DpcRoutines.h @@ -0,0 +1,20 @@ + +/** + * @file DpcRoutines.h + * @author Sina Karvandi (sina@hyperdbg.org) + * @brief Definition for DPC functions + * @details + * @version 0.21 + * @date 2026-06-22 + * + * @copyright This project is released under the GNU Public License v3. + * + */ +#pragma once + +////////////////////////////////////////////////// +// Functions // +////////////////////////////////////////////////// + +BOOLEAN +DpcRoutineTestPmu(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2); diff --git a/hyperdbg/hyperperf/header/common/UnloadDll.h b/hyperdbg/hyperperf/header/common/UnloadDll.h new file mode 100644 index 00000000..9bb252d2 --- /dev/null +++ b/hyperdbg/hyperperf/header/common/UnloadDll.h @@ -0,0 +1,22 @@ +/** + * @file UnloadDll.h + * @author Sina Karvandi (sina@hyperdbg.org) + * @brief Headers for unloading DLL in the target Windows + * + * @version 0.4 + * @date 2023-07-06 + * + * @copyright This project is released under the GNU Public License v3. + * + */ +#pragma once + +////////////////////////////////////////////////// +// Exported Functions // +////////////////////////////////////////////////// + +__declspec(dllexport) NTSTATUS +DllInitialize(_In_ PUNICODE_STRING RegistryPath); + +__declspec(dllexport) NTSTATUS + DllUnload(VOID); diff --git a/hyperdbg/hyperperf/header/globals/GlobalVariables.h b/hyperdbg/hyperperf/header/globals/GlobalVariables.h new file mode 100644 index 00000000..79c0f02e --- /dev/null +++ b/hyperdbg/hyperperf/header/globals/GlobalVariables.h @@ -0,0 +1,35 @@ + +/** + * @file GlobalVariables.h + * @author Sina Karvandi (sina@hyperdbg.org) + * @brief Definition for global variables + * @details + * @version 0.21 + * @date 2026-06-22 + * + * @copyright This project is released under the GNU Public License v3. + * + */ +#pragma once + +////////////////////////////////////////////////// +// Global Variables // +////////////////////////////////////////////////// + +/** + * @brief List of callbacks + * + */ +HYPERPERF_CALLBACKS g_Callbacks; + +/** + * @brief The flag indicating whether the hyperperf module callbacks is initialized or not + * + */ +BOOLEAN g_HyperPerfCallbacksInitialized; + +/** + * @brief The flag indicating whether the initialization is being done for hypervisor environment or not + * + */ +BOOLEAN g_RunningOnHypervisorEnvironment; diff --git a/hyperdbg/hyperperf/header/pch.h b/hyperdbg/hyperperf/header/pch.h new file mode 100644 index 00000000..35e14b66 --- /dev/null +++ b/hyperdbg/hyperperf/header/pch.h @@ -0,0 +1,111 @@ + +/** + * @file pch.h + * @author Sina Karvandi (sina@hyperdbg.org) + * @brief Headers of Message logging and tracing + * @details + * @version 0.21 + * @date 2026-06-22 + * + * @copyright This project is released under the GNU Public License v3. + * + */ +#pragma once + +#define _NO_CRT_STDIO_INLINE + +#pragma warning(disable : 4201) // Suppress nameless struct/union warning + +// +// Environment headers +// +#include "platform/general/header/Environment.h" + +#ifdef HYPERDBG_ENV_WINDOWS + +// +// Windows defined functions +// +# include +# include +# include + +#endif // HYPERDBG_ENV_WINDOWS + +// +// Scope definitions +// +#define HYPERDBG_KERNEL_MODE +#define HYPERDBG_HYPERPERF + +// +// Add ia32-doc +// +#include "ia32-doc/out/ia32.h" + +// +// SDK headers +// +#include "SDK/HyperDbgSdk.h" + +// +// Configuration +// +#include "config/Configuration.h" + +// +// Platform independent headers +// +#include "platform/kernel/header/PlatformMem.h" +#include "platform/kernel/header/PlatformIntrinsics.h" +#include "platform/kernel/header/PlatformBroadcast.h" +#include "platform/kernel/header/PlatformCpu.h" +#include "platform/kernel/header/PlatformSpinlock.h" +#include "platform/kernel/header/PlatformIrql.h" +#include "platform/kernel/header/PlatformDpc.h" +#include "platform/kernel/header/PlatformTime.h" +#include "platform/kernel/header/PlatformDbg.h" +#include "platform/kernel/header/PlatformIo.h" +#include "platform/kernel/header/PlatformEvent.h" + +// +// Unload function (to be called when the driver is unloaded) +// +#include "common/UnloadDll.h" + +// +// Hyperlog headers +// +#include "components/callback/header/HyperLogCallback.h" +#include "SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h" + +// +// Spinlock headers +// +#include "components/spinlock/header/Spinlock.h" + +// +// HyperPerf Callbacks +// +#include "SDK/modules/HyperPerf.h" + +// +// Definition of general tracing types +// +#include "api/PerfApi.h" + +// +// DPC and broadcasting function headers +// +#include "broadcast/DpcRoutines.h" +#include "broadcast/Broadcast.h" + +// +// Export functions +// +#include "SDK/imports/kernel/HyperDbgHyperPerf.h" + +// +// Global variables +// +#include "globals/GlobalVariables.h" diff --git a/hyperdbg/hyperperf/header/pt/Pt.h b/hyperdbg/hyperperf/header/pt/Pt.h new file mode 100644 index 00000000..07a10506 --- /dev/null +++ b/hyperdbg/hyperperf/header/pt/Pt.h @@ -0,0 +1,167 @@ +/** + * @file Pt.h + * @author Masoud Rahimi Jafari (Masoodrahimy1379@gmail.com) + * @brief Header for Processor Trace (PT) tracing routines for HyperTrace module + * @details Engine that programs Intel PT MSRs from VMX root or kernel context. + * Buffer / ToPA management is kept here; user-visible PT structures + * live in the SDK header [PtDefinitions.h]. + * @version 0.19 + * @date 2026-04-29 + * + * @copyright This project is released under the GNU Public License v3. + */ +#pragma once + +////////////////////////////////////////////////// +// Constants // +////////////////////////////////////////////////// + +// +// Pool tag for PT contiguous allocations (ASCII "PtHd") +// +#define POOL_TAG_PT 'dHtP' + +////////////////////////////////////////////////// +// Structures // +////////////////////////////////////////////////// + +/** + * @brief Narrow input descriptor for PtFilter. + * + * These are the only fields a caller is allowed to set per-CPU + * when reconfiguring an active PT trace. Engine-internal options + * (BranchEn, TscEn, MtcEn, CycEn, RetCompression, *Freq, etc.) + * stay under the engine's control and are NOT exposed here. + * + * BufferSize == 0 means "keep whatever the per-CPU slot already + * has" — pure filter changes don't touch the ToPA / output / + * overflow buffers and can run from a DPC. + */ +typedef struct _PT_FILTER_OPTIONS +{ + BOOLEAN TraceUser; + BOOLEAN TraceKernel; + UINT64 TargetCr3; + UINT64 BufferSize; + UINT32 NumAddrRanges; + PT_ADDR_RANGE AddrRanges[PT_MAX_ADDR_RANGES]; + +} PT_FILTER_OPTIONS, *PPT_FILTER_OPTIONS; + +/** + * @brief Per-CPU bookkeeping for the user-mode mmap surface. + * + * One MDL + user VA per CPU describes the main output buffer + * immediately followed by the 4 KB overflow page as a single + * virtually contiguous region in the mapping process. Lives in + * g_PtUserMappings; lifetime tied to the PT enable cycle. + */ +typedef struct _PT_USER_MAPPING +{ + PMDL Mdl; + PVOID UserVa; + +} PT_USER_MAPPING, *PPT_USER_MAPPING; + +////////////////////////////////////////////////// +// Functions // +////////////////////////////////////////////////// + +// +// HyperDbg-style wrappers (mirroring Lbr*) +// + +BOOLEAN +PtCheck(); + +BOOLEAN +PtStart(); + +VOID +PtStop(); + +VOID +PtPause(); + +VOID +PtResume(); + +UINT64 +PtSize(); + +VOID +PtDump(); + +VOID +PtFlush(); + +// +// LBR-style filter wrapper, one CPU at a time. Mirrors LbrFilter in shape: +// caller passes a PT_FILTER_OPTIONS describing only the user-tunable bits +// (TraceUser, TraceKernel, TargetCr3, BufferSize, NumAddrRanges, AddrRanges), +// and PtFilter handles the stop / config-update / start sequence on the +// CURRENT CPU. Engine-internal config (BranchEn, TscEn, etc.) is left +// untouched in the per-CPU PT_TRACE_CONFIG. +// +VOID +PtFilter(const PT_FILTER_OPTIONS * FilterOptions); + +// +// PASSIVE_LEVEL helpers — call before / after the per-core DPC broadcasts. +// Required because MmAllocateContiguousMemorySpecifyCache and +// MmFreeContiguousMemory must run at IRQL == PASSIVE_LEVEL. +// + +BOOLEAN +PtAllocateAllCpuBuffers(); + +VOID +PtFreeAllCpuBuffers(); + +// +// User-mode mmap surface: map every per-CPU main output + overflow +// buffer into the calling user process. Idempotent within an enable +// cycle; torn down by PtFreeAllCpuBuffers (i.e. PT disable / flush). +// +INT32 +PtMmapAllCpuBuffersToUser(PT_USER_BUFFER_DESC * OutDescs, UINT32 MaxDescs, UINT32 * OutNumCpus); + +VOID +PtUnmapAllCpuBuffersFromUser(); + +// +// Engine routines (operate on a specific PT_PER_CPU instance) +// + +INT32 +PtEngineQueryCapabilities(PT_CAPABILITIES * OutCaps); + +VOID +PtEngineInitDefaultConfig(PT_TRACE_CONFIG * Config); + +INT32 +PtEngineAllocateBuffers(PT_PER_CPU * Cpu, const PT_TRACE_CONFIG * Config); + +VOID +PtEngineFreeBuffers(PT_PER_CPU * Cpu); + +INT32 +PtEngineStart(PT_PER_CPU * Cpu); + +UINT64 +PtEngineStop(PT_PER_CPU * Cpu, PT_OUTPUT_BUFFER * Out); + +INT32 +PtEnginePause(PT_PER_CPU * Cpu); + +INT32 +PtEngineResume(PT_PER_CPU * Cpu); + +UINT64 +PtEngineHandlePmi(PT_PER_CPU * Cpu, PT_OUTPUT_BUFFER * Out); + +BOOLEAN +PtEngineIsPtPmi(); + +INT32 +PtEngineSizeToTopaEncoding(UINT64 SizeInBytes); diff --git a/hyperdbg/hyperperf/hyperperf.def b/hyperdbg/hyperperf/hyperperf.def new file mode 100644 index 00000000..1415f880 --- /dev/null +++ b/hyperdbg/hyperperf/hyperperf.def @@ -0,0 +1,6 @@ +LIBRARY hyperperf + +EXPORTS + + DllInitialize PRIVATE + DllUnload PRIVATE \ No newline at end of file diff --git a/hyperdbg/hyperperf/hyperperf.vcxproj b/hyperdbg/hyperperf/hyperperf.vcxproj new file mode 100644 index 00000000..20624659 --- /dev/null +++ b/hyperdbg/hyperperf/hyperperf.vcxproj @@ -0,0 +1,145 @@ + + + + + + + + debug + x64 + + + release + x64 + + + + {360E54B1-0B92-4BCA-8111-4BF384292621} + {1bc93793-694f-48fe-9372-81e2b05556fd} + v4.5 + 12.0 + Debug + x64 + hyperperf + $(LatestTargetPlatformVersion) + + + + Windows10 + true + WindowsKernelModeDriver10.0 + DynamicLibrary + KMDF + Desktop + false + + + Windows10 + false + WindowsKernelModeDriver10.0 + DynamicLibrary + KMDF + Desktop + false + + + + + + + + + + + DbgengKernelDebugger + $(SolutionDir)build\bin\$(Configuration)\ + $(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\ + false + + + DbgengKernelDebugger + $(SolutionDir)build\bin\$(Configuration)\ + $(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\ + false + + + + sha256 + + + $(SolutionDir)\include;$(ProjectDir)header;$(SolutionDir)dependencies;%(AdditionalIncludeDirectories) + true + Create + pch.h + stdcpp20 + + + true + + true + hyperperf.def + + + + + sha256 + + + $(SolutionDir)\include;$(ProjectDir)header;$(SolutionDir)dependencies;%(AdditionalIncludeDirectories) + true + Create + pch.h + stdcpp20 + Full + + + true + + true + hyperperf.def + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + \ No newline at end of file diff --git a/hyperdbg/hyperperf/hyperperf.vcxproj.filters b/hyperdbg/hyperperf/hyperperf.vcxproj.filters new file mode 100644 index 00000000..d4254192 --- /dev/null +++ b/hyperdbg/hyperperf/hyperperf.vcxproj.filters @@ -0,0 +1,119 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {1ab177b4-9e6c-460e-834a-8fced04b42a3} + + + {21f0281e-fc2a-4e13-97ac-e4b35a05a31e} + + + {09d5457a-bade-4a3f-a171-641110492d57} + + + {b8b32a09-61fb-433a-ad79-eb7cfc5f3437} + + + {32ea8333-847b-443d-8992-4140d54dc1d3} + + + {df6eb164-34b2-4f2a-9530-b88443662fb7} + + + {cb4e742a-6e43-4798-af4a-72bcb11089c9} + + + {ab21116d-5f5b-4ef8-82bb-6585ac3dec95} + + + {57d56081-eede-41a3-b9f0-e7019d32c986} + + + {4f62540b-d186-479e-83a0-1b550134f487} + + + {9fe877a7-e261-4579-9752-a3156b6e69d9} + + + {8bc2336a-b1c5-4e93-9793-23a5cfdc741d} + + + {fc73555b-2be3-4898-bcdb-df83fa3e1388} + + + + + code\platform + + + code\broadcast + + + code\broadcast + + + code\common + + + code\api + + + code\platform + + + code\broadcast + + + code\platform + + + code\components\callback + + + + + header\platform + + + header\broadcast + + + header\broadcast + + + header\common + + + header\globals + + + header\api + + + header\platform + + + header\platform + + + header\platform + + + header\components\callback + + + header + + + + + + \ No newline at end of file diff --git a/hyperdbg/hyperperf/packages.config b/hyperdbg/hyperperf/packages.config new file mode 100644 index 00000000..eb276766 --- /dev/null +++ b/hyperdbg/hyperperf/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/hyperdbg/hypertrace/code/api/TraceApi.c b/hyperdbg/hypertrace/code/api/TraceApi.c index 709f5c6f..94f3e961 100644 --- a/hyperdbg/hypertrace/code/api/TraceApi.c +++ b/hyperdbg/hypertrace/code/api/TraceApi.c @@ -11,7 +11,7 @@ #include "pch.h" /** - * @brief Initialize the hyper trace module callbacks + * @brief Initialize the hypertrace module callbacks * @details This only for callback initialization, not for LBR, PT, etc. initialization * * @param HyperTraceCallbacks Pointer to the HyperTrace callbacks structure to be registered diff --git a/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperPerf.h b/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperPerf.h new file mode 100644 index 00000000..f6997795 --- /dev/null +++ b/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperPerf.h @@ -0,0 +1,33 @@ +/** + * @file HyperDbgHyperPerf.h + * @author Sina Karvandi (sina@hyperdbg.org) + * @brief Headers relating exported functions from hyperperf (pmu) module + * @version 0.21 + * @date 2026-06-22 + * + * @copyright This project is released under the GNU Public License v3. + * + */ +#pragma once + +#ifdef HYPERDBG_HYPERPERF +# define IMPORT_EXPORT_HYPERPERF __declspec(dllexport) +#else +# define IMPORT_EXPORT_HYPERPERF __declspec(dllimport) +#endif + +////////////////////////////////////////////////// +// HyperPerf Functions // +////////////////////////////////////////////////// + +// +// Initialize the hyperperf module with the provided callbacks +// +IMPORT_EXPORT_HYPERPERF BOOLEAN +HyperPerfInitCallback(HYPERPERF_CALLBACKS * HyperPerfCallbacks, BOOLEAN RunningOnHypervisorEnvironment); + +// +// Uninitialize the HyperPerf module +// +IMPORT_EXPORT_HYPERPERF VOID +HyperPerfUninit(); diff --git a/hyperdbg/include/SDK/modules/HyperPerf.h b/hyperdbg/include/SDK/modules/HyperPerf.h new file mode 100644 index 00000000..fe76e097 --- /dev/null +++ b/hyperdbg/include/SDK/modules/HyperPerf.h @@ -0,0 +1,80 @@ +/** + * @file HyperPerf.h + * @author Sina Karvandi (sina@hyperdbg.org) + * @brief HyperDbg's SDK for hyperperf project + * @details This file contains definitions of HyperPerf routines + * @version 0.21 + * @date 2026-06-22 + * + * @copyright This project is released under the GNU Public License v3. + * + */ +#pragma once + +////////////////////////////////////////////////// +// Callback Types // +////////////////////////////////////////////////// + +/** + * @brief A function from the message tracer that send the inputs to the + * queue of the messages + * + */ +typedef BOOLEAN (*LOG_CALLBACK_PREPARE_AND_SEND_MESSAGE_TO_QUEUE)(UINT32 OperationCode, + BOOLEAN IsImmediateMessage, + BOOLEAN ShowCurrentSystemTime, + BOOLEAN Priority, + const CHAR * Fmt, + va_list ArgList); + +/** + * @brief A function that sends the messages to message tracer buffers + * + */ +typedef BOOLEAN (*LOG_CALLBACK_SEND_MESSAGE_TO_QUEUE)(UINT32 OperationCode, BOOLEAN IsImmediateMessage, CHAR * LogMessage, UINT32 BufferLen, BOOLEAN Priority); + +/** + * @brief A function that sends the messages to message tracer buffers + * + */ +typedef BOOLEAN (*LOG_CALLBACK_SEND_BUFFER)(_In_ UINT32 OperationCode, + _In_reads_bytes_(BufferLength) PVOID Buffer, + _In_ UINT32 BufferLength, + _In_ BOOLEAN Priority); + +/** + * @brief A function that checks whether the priority or regular buffer is full or not + * + */ +typedef BOOLEAN (*LOG_CALLBACK_CHECK_IF_BUFFER_IS_FULL)(BOOLEAN Priority); + +/** + * @brief A function that checks whether the current execution mode is VMX-root mode or not + * + */ +typedef BOOLEAN (*VM_FUNC_VMX_GET_CURRENT_EXECUTION_MODE)(); + +////////////////////////////////////////////////// +// Callback Structure // +////////////////////////////////////////////////// + +/** + * @brief Prototype of each function needed by hyperperf module + * + */ +typedef struct _HYPERPERF_CALLBACKS +{ + // + // *** Log (Hyperlog) callbacks *** + // + LOG_CALLBACK_PREPARE_AND_SEND_MESSAGE_TO_QUEUE LogCallbackPrepareAndSendMessageToQueueWrapper; + LOG_CALLBACK_SEND_MESSAGE_TO_QUEUE LogCallbackSendMessageToQueue; + LOG_CALLBACK_SEND_BUFFER LogCallbackSendBuffer; + LOG_CALLBACK_CHECK_IF_BUFFER_IS_FULL LogCallbackCheckIfBufferIsFull; + + // + // *** Hypervisor (Hyperhv) callbacks *** + // + VM_FUNC_VMX_GET_CURRENT_EXECUTION_MODE VmFuncVmxGetCurrentExecutionMode; + +} HYPERPERF_CALLBACKS, *PHYPERPERF_CALLBACKS;