mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-07-18 13:34:37 +00:00
326 lines
13 KiB
C++
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();
|