HyperDbg/hyperdbg/libhyperdbg/header/common/common.h
Max Raulea 2a2425dc68
Some checks failed
vs2026-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2026-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2026-ci / Deploy release (push) Has been cancelled
compiling kd.cpp on linux
2026-07-16 15:00:03 +02:00

326 lines
13 KiB
C++

/**
* @file common.h
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief header for HyperDbg's general functions for reading and converting and
* etc
* @details
* @version 0.1
* @date 2020-05-27
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#pragma once
//////////////////////////////////////////////////
// Definitions //
//////////////////////////////////////////////////
#define AssertReturn return;
#define AssertReturnFalse return FALSE;
#define AssertReturnOne return 1;
#define PAUSE_MESSAGE_IN_USER_DEBUGGER "\nTo pause the target process, run the 'pause' command"
#define ASSERT_MESSAGE_DRIVER_NOT_LOADED "handle of the driver not found, probably the driver is not loaded. Did you use 'load' command?\n"
#define ASSERT_MESSAGE_KD_NOT_LOADED "the kd (kernel debugger) module is not loaded. Did you use 'load kd' command?\n"
#define ASSERT_MESSAGE_VMM_NOT_LOADED "the vmm (virtualization) module is not loaded. Did you use 'load vmm' command?\n"
#define ASSERT_MESSAGE_HYPERTRACE_NOT_LOADED "the trace (hypertrace) module is not loaded. Did you use 'load trace' command?\n"
#define ASSERT_MESSAGE_BUILD_SIGNATURE_DOESNT_MATCH "the handshaking process was successful; however, there is a mismatch between " \
"the version/build of the debuggee and the debugger. please use the same " \
"version/build for both the debuggee and debugger\n"
#define ASSERT_MESSAGE_CANNOT_SPECIFY_PID "err, since HyperDbg won't context-switch to keep the system in a halted state, " \
"you cannot specify 'pid' for this command in the debugger mode. You can switch to the target process " \
"memory layout using the '.process' or the '.thread' command. After that, you can use " \
"this command without specifying the process ID. Alternatively, you can modify the current " \
"CR3 register to achieve the same functionality\n"
#define AssertReturnStmt(expr, stmt, rc) \
do \
{ \
if (expr) \
{ \
/* likely */ \
} \
else \
{ \
stmt; \
rc; \
} \
} while (0)
#define AssertShowMessageReturnStmt(expr1, expr2, message1, message2, rc) \
do \
{ \
if (expr1 && expr2) \
{ \
/* likely */ \
} \
else \
{ \
if (!expr1) \
ShowMessages(message1); \
else if (!expr2) \
ShowMessages(message2); \
rc; \
} \
} while (0)
/**
* @brief Size of each page (4096 bytes)
*
*/
#define PAGE_SIZE 0x1000
/**
* @brief Aligning a page
*
*/
#define PAGE_ALIGN(Va) ((PVOID)((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1)))
/**
* @brief Cpuid to get virtual address width
*
*/
#define CPUID_ADDR_WIDTH 0x80000008
//////////////////////////////////////////////////
// Kernel & User Synchronization //
//////////////////////////////////////////////////
#define DbgWaitForKernelResponse(KernelSyncObjectId) \
do \
{ \
DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
&g_KernelSyncronizationObjectsHandleTable[KernelSyncObjectId]; \
\
SyncronizationObject->IsOnWaitingState = TRUE; \
PlatformWaitForSingleObject(SyncronizationObject->EventHandle, INFINITE); \
\
} while (FALSE);
#define DbgWaitForUserResponse(UserSyncObjectId) \
do \
{ \
DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
&g_UserSyncronizationObjectsHandleTable[UserSyncObjectId]; \
\
SyncronizationObject->IsOnWaitingState = TRUE; \
PlatformWaitForSingleObject(SyncronizationObject->EventHandle, INFINITE); \
\
} while (FALSE);
#define DbgWaitSetKernelRequestData(KernelSyncObjectId, ReqData, ReqSize) \
do \
{ \
DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
&g_KernelSyncronizationObjectsHandleTable[KernelSyncObjectId]; \
\
SyncronizationObject->RequestData = (PVOID)ReqData; \
SyncronizationObject->RequestSize = (UINT32)ReqSize; \
\
} while (FALSE);
#define DbgWaitSetUserRequestData(UserSyncObjectId, ReqData, ReqSize) \
do \
{ \
DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
&g_UserSyncronizationObjectsHandleTable[UserSyncObjectId]; \
\
SyncronizationObject->RequestData = (PVOID)ReqData; \
SyncronizationObject->RequestSize = (UINT32)ReqSize; \
\
} while (FALSE);
#define DbgWaitGetKernelRequestData(KernelSyncObjectId, ReqData, ReqSize) \
do \
{ \
DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
&g_KernelSyncronizationObjectsHandleTable[KernelSyncObjectId]; \
\
*ReqData = SyncronizationObject->RequestData; \
*ReqSize = SyncronizationObject->RequestSize; \
SyncronizationObject->RequestData = NULL; \
SyncronizationObject->RequestSize = NULL_ZERO; \
\
} while (FALSE);
#define DbgWaitGetUserRequestData(UserSyncObjectId, ReqData, ReqSize) \
do \
{ \
DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
&g_UserSyncronizationObjectsHandleTable[UserSyncObjectId]; \
\
*ReqData = SyncronizationObject->RequestData; \
*ReqSize = SyncronizationObject->RequestSize; \
SyncronizationObject->RequestData = NULL; \
SyncronizationObject->RequestSize = NULL_ZERO; \
\
} while (FALSE);
#define DbgReceivedKernelResponse(KernelSyncObjectId) \
do \
{ \
DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
&g_KernelSyncronizationObjectsHandleTable[KernelSyncObjectId]; \
\
SyncronizationObject->IsOnWaitingState = FALSE; \
PlatformSetEvent(SyncronizationObject->EventHandle); \
} while (FALSE);
#define DbgReceivedUserResponse(UserSyncObjectId) \
do \
{ \
DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
&g_UserSyncronizationObjectsHandleTable[UserSyncObjectId]; \
\
SyncronizationObject->IsOnWaitingState = FALSE; \
PlatformSetEvent(SyncronizationObject->EventHandle); \
} while (FALSE);
//////////////////////////////////////////////////
// Assembly Functions //
//////////////////////////////////////////////////
#ifdef __cplusplus
extern "C" {
#endif
extern BOOLEAN
AsmVmxSupportDetection();
#ifdef __cplusplus
}
#endif
//////////////////////////////////////////////////
// Spinlocks //
//////////////////////////////////////////////////
VOID
SpinlockLock(volatile LONG * Lock);
VOID
SpinlockLockWithCustomWait(volatile LONG * Lock, UINT32 MaximumWait);
VOID
SpinlockUnlock(volatile LONG * Lock);
//////////////////////////////////////////////////
// Functions //
//////////////////////////////////////////////////
VOID
PrintBits(const UINT32 size, const VOID * ptr);
BOOL
Replace(std::string & str, const std::string & from, const std::string & to);
VOID
ReplaceAll(string & str, const string & from, const string & to);
const vector<string>
Split(const string & s, const CHAR & c);
BOOLEAN
IsNumber(const string & str);
UINT32
Log2Ceil(UINT32 n);
BOOLEAN
IsHexNotation(const string & s);
vector<CHAR>
HexToBytes(const string & hex);
BOOLEAN
ConvertStringToUInt64(string TextToConvert, PUINT64 Result);
BOOLEAN
ConvertStringToUInt32(string TextToConvert, PUINT32 Result);
BOOLEAN
ConvertTokenToUInt64(CommandToken TargetToken, PUINT64 Result);
BOOLEAN
ConvertTokenToUInt32(CommandToken TargetToken, PUINT32 Result);
std::string
GetCaseSensitiveStringFromCommandToken(CommandToken TargetToken);
std::string
GetLowerStringFromCommandToken(CommandToken TargetToken);
BOOLEAN
CompareLowerCaseStrings(CommandToken TargetToken, const CHAR * StringToCompare);
BOOLEAN
IsTokenBracketString(CommandToken TargetToken);
BOOLEAN
HasEnding(string const & fullString, string const & ending);
BOOLEAN
ValidateIP(const string & ip);
BOOL
SetPrivilege(HANDLE Token, // access token handle
LPCTSTR Privilege, // name of privilege to enable/disable
BOOL EnablePrivilege // to enable or disable privilege
);
VOID
Trim(std::string & s);
std::string
RemoveSpaces(std::string str);
BOOLEAN
IsFileExistA(const CHAR * FileName);
BOOLEAN
IsFileExistW(const WCHAR * FileName);
VOID
GetConfigFilePath(PWCHAR ConfigPath);
VOID
StringToWString(std::wstring & ws, const std::string & s);
SIZE_T
FindCaseInsensitive(std::string Input, std::string ToSearch, SIZE_T Pos);
SIZE_T
FindCaseInsensitiveW(std::wstring Input, std::wstring ToSearch, SIZE_T Pos);
CHAR *
ConvertStringVectorToCharPointerArray(const std::string & s);
std::vector<std::string>
ListDirectory(const std::string & Directory, const std::string & Extension);
BOOLEAN
IsEmptyString(CHAR * Text);
VOID
CommonCpuidInstruction(UINT32 Func, UINT32 SubFunc, INT * CpuInfo);
BOOLEAN
CheckCpuSupportRtm();
UINT32
Getx86VirtualAddressWidth();
BOOLEAN
CheckAccessValidityAndSafety(UINT64 TargetAddress, UINT32 Size);
BOOLEAN
VmxSupportDetection();