HyperDbg Debugger
Loading...
Searching...
No Matches
Functions.c File Reference

Script engine functions implementations. More...

#include "pch.h"

Functions

UINT64 GetValue (PGUEST_REGS GuestRegs, PACTION_BUFFER ActionBuffer, SCRIPT_ENGINE_VARIABLES_LIST *VariablesList, PSYMBOL Symbol, BOOLEAN ReturnReference, SYMBOL_BUFFER *StackBuffer, UINT64 *StackIndx, UINT64 *StackBaseIndx, UINT64 *ReturnValue)
 
BOOLEAN ScriptEngineFunctionEq (UINT64 Address, QWORD Value, BOOL *HasError)
 Implementation of eq function.
 
BOOLEAN ScriptEngineFunctionEd (UINT64 Address, DWORD Value, BOOL *HasError)
 Implementation of ed function.
 
BOOLEAN ScriptEngineFunctionEb (UINT64 Address, BYTE Value, BOOL *HasError)
 Implementation of eb function.
 
BOOLEAN ScriptEngineFunctionCheckAddress (UINT64 Address, UINT32 Length)
 Check whether the address is valid or not.
 
VOID ScriptEngineFunctionMemcpy (UINT64 Destination, UINT64 Source, UINT32 Num, BOOL *HasError)
 A VMX-compatible equivalent of memcpy function in C.
 
UINT64 ScriptEngineFunctionVirtualToPhysical (UINT64 Address)
 
UINT64 ScriptEngineFunctionPhysicalToVirtual (UINT64 Address)
 Convert physical address to virtual address.
 
VOID ScriptEngineFunctionPrint (UINT64 Tag, BOOLEAN ImmediateMessagePassing, UINT64 Value)
 Implementation of print function.
 
VOID ScriptEngineFunctionTestStatement (UINT64 Tag, BOOLEAN ImmediateMessagePassing, UINT64 Value)
 Implementation of test_statement function.
 
VOID ScriptEngineFunctionSpinlockLock (volatile LONG *Lock, BOOL *HasError)
 Implementation of spinlock_lock function.
 
VOID ScriptEngineFunctionSpinlockUnlock (volatile LONG *Lock, BOOL *HasError)
 Implementation of spinlock_unlock function.
 
VOID ScriptEngineFunctionSpinlockLockCustomWait (volatile long *Lock, unsigned MaxWait, BOOL *HasError)
 Implementation of spinlock_lock_custom_wait function.
 
UINT64 ScriptEngineFunctionStrlen (const char *Address)
 Implementation of strlen function.
 
UINT64 ScriptEngineFunctionDisassembleLen (PVOID Address, BOOLEAN Is32Bit)
 Implementation of disassemble_len function.
 
UINT64 ScriptEngineFunctionWcslen (const wchar_t *Address)
 Implementation of wcslen function.
 
long long ScriptEngineFunctionInterlockedExchange (long long volatile *Target, long long Value, BOOL *HasError)
 Implementation of interlocked_exchange function.
 
long long ScriptEngineFunctionInterlockedExchangeAdd (long long volatile *Addend, long long Value, BOOL *HasError)
 Implementation of interlocked_exchange_add function.
 
long long ScriptEngineFunctionInterlockedIncrement (long long volatile *Addend, BOOL *HasError)
 Implementation of interlocked_exchange_increment function.
 
long long ScriptEngineFunctionInterlockedDecrement (long long volatile *Addend, BOOL *HasError)
 Implementation of interlocked_exchange_decrement function.
 
long long ScriptEngineFunctionInterlockedCompareExchange (long long volatile *Destination, long long ExChange, long long Comperand, BOOL *HasError)
 Implementation of interlocked_compare_exchange function.
 
VOID ScriptEngineFunctionEventEnable (UINT64 EventId)
 Implementation of event_enable function.
 
VOID ScriptEngineFunctionEventDisable (UINT64 EventId)
 Implementation of event_disable function.
 
VOID ScriptEngineFunctionEventClear (UINT64 EventId)
 Implementation of event_clear function.
 
VOID ScriptEngineFunctionPause (ACTION_BUFFER *ActionDetail, PGUEST_REGS GuestRegs)
 Implementation of pause function.
 
VOID ScriptEngineFunctionFlush ()
 Implementation of flush function.
 
VOID ScriptEngineFunctionShortCircuitingEvent (UINT64 State, ACTION_BUFFER *ActionDetail)
 Implementation of event_ignore function.
 
VOID ScriptEngineFunctionFormats (UINT64 Tag, BOOLEAN ImmediateMessagePassing, UINT64 Value)
 Implementation of formats function.
 
UINT32 CustomStrlen (UINT64 StrAddr, BOOLEAN IsWstring)
 Custom VMX-root compatible strlen.
 
BOOLEAN CheckIfStringIsSafe (UINT64 StrAddr, BOOLEAN IsWstring)
 Check if string is safe to be accessed or not (in vmx-root mode)
 
VOID ApplyFormatSpecifier (const CHAR *CurrentSpecifier, CHAR *FinalBuffer, PUINT32 CurrentProcessedPositionFromStartOfFormat, PUINT32 CurrentPositionInFinalBuffer, UINT64 Val, UINT32 SizeOfFinalBuffer)
 Apply format specifiers (d, x, llx, etc.)
 
size_t WcharToChar (const wchar_t *src, char *dest, size_t dest_len)
 Convert WCHAR* to CHAR*.
 
BOOLEAN ApplyStringFormatSpecifier (const CHAR *CurrentSpecifier, CHAR *FinalBuffer, PUINT32 CurrentProcessedPositionFromStartOfFormat, PUINT32 CurrentPositionInFinalBuffer, UINT64 Val, BOOLEAN IsWstring, UINT32 SizeOfFinalBuffer)
 Apply string format specifiers (s, ws, etc.)
 
VOID ScriptEngineFunctionPrintf (PGUEST_REGS GuestRegs, ACTION_BUFFER *ActionDetail, SCRIPT_ENGINE_VARIABLES_LIST *VariablesList, UINT64 Tag, BOOLEAN ImmediateMessagePassing, char *Format, UINT64 ArgCount, PSYMBOL FirstArg, BOOLEAN *HasError, SYMBOL_BUFFER *StackBuffer, UINT64 *StackIndx, UINT64 *StackBaseIndx, UINT64 *ReturnValue)
 Implementation of printf function.
 
VOID ScriptEngineFunctionEventInject (UINT32 InterruptionType, UINT32 Vector, BOOL *HasError)
 Implementation of event_inject function.
 
VOID ScriptEngineFunctionEventInjectErrorCode (UINT32 InterruptionType, UINT32 Vector, UINT32 ErrorCode, BOOL *HasError)
 Implementation of event_inject_error_code function.
 
UINT64 ScriptEngineFunctionStrcmp (const char *Address1, const char *Address2)
 Implementation of strcmp function.
 
UINT64 ScriptEngineFunctionStrncmp (const char *Address1, const char *Address2, size_t Num)
 Implementation of strcmp function.
 
UINT64 ScriptEngineFunctionWcscmp (const wchar_t *Address1, const wchar_t *Address2)
 Implementation of wcscmp function.
 
UINT64 ScriptEngineFunctionWcsncmp (const wchar_t *Address1, const wchar_t *Address2, size_t Num)
 Implementation of wcsncmp function.
 
UINT64 ScriptEngineFunctionMemcmp (const char *Address1, const char *Address2, size_t Count)
 Implementation of memcmp function.
 
VOID ScriptEngineFunctionEventTraceInstrumentationStep ()
 Implementation of event_trace_instrumentation_step function.
 
VOID ScriptEngineFunctionEventTraceStepIn ()
 Implementation of event_trace_step_in function.
 

Detailed Description

Script engine functions implementations.

Author
M.H. Gholamrezaei (mh@hy.nosp@m.perd.nosp@m.bg.or.nosp@m.g)
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.2
Date
2022-06-29

Function Documentation

◆ ApplyFormatSpecifier()

VOID ApplyFormatSpecifier ( const CHAR * CurrentSpecifier,
CHAR * FinalBuffer,
PUINT32 CurrentProcessedPositionFromStartOfFormat,
PUINT32 CurrentPositionInFinalBuffer,
UINT64 Val,
UINT32 SizeOfFinalBuffer )

Apply format specifiers (d, x, llx, etc.)

Parameters
CurrentSpecifier
FinalBuffer
CurrentProcessedPositionFromStartOfFormat
CurrentPositionInFinalBuffer
Val
SizeOfFinalBuffer
Returns
VOID
1032{
1033 UINT32 TempBufferLen = 0;
1034 CHAR TempBuffer[50 + 1] = {
1035 0}; // Maximum uint64_t is 18446744073709551615 + 1 thus its 20 character
1036 // for maximum buffer + 1 end char null but we alloc 50 to be sure
1037
1038 *CurrentProcessedPositionFromStartOfFormat =
1039 *CurrentProcessedPositionFromStartOfFormat + (UINT32)strlen(CurrentSpecifier);
1040 sprintf(TempBuffer, CurrentSpecifier, Val);
1041 TempBufferLen = (UINT32)strlen(TempBuffer);
1042
1043 //
1044 // Check final buffer capacity
1045 //
1046 if (*CurrentPositionInFinalBuffer + TempBufferLen > SizeOfFinalBuffer)
1047 {
1048 //
1049 // Over passed buffer
1050 //
1051 return;
1052 }
1053
1054 memcpy(&FinalBuffer[*CurrentPositionInFinalBuffer], TempBuffer, TempBufferLen);
1055
1056 *CurrentPositionInFinalBuffer = *CurrentPositionInFinalBuffer + TempBufferLen;
1057}
unsigned int UINT32
Definition BasicTypes.h:48
char CHAR
Definition BasicTypes.h:31

◆ ApplyStringFormatSpecifier()

BOOLEAN ApplyStringFormatSpecifier ( const CHAR * CurrentSpecifier,
CHAR * FinalBuffer,
PUINT32 CurrentProcessedPositionFromStartOfFormat,
PUINT32 CurrentPositionInFinalBuffer,
UINT64 Val,
BOOLEAN IsWstring,
UINT32 SizeOfFinalBuffer )

Apply string format specifiers (s, ws, etc.)

Parameters
CurrentSpecifier
FinalBuffer
CurrentProcessedPositionFromStartOfFormat
CurrentPositionInFinalBuffer
Val
IsWstring
SizeOfFinalBuffer
Returns
BOOLEAN
1111{
1112 UINT32 StringSize;
1113 wchar_t WstrBuffer[50];
1114 CHAR AsciiBuffer[sizeof(WstrBuffer) / 2];
1115 UINT32 StringSizeInByte; /* because of wide-char */
1116 UINT32 CountOfBlocks;
1117 UINT32 CopiedBlockLen;
1118
1119 //
1120 // First we have to check if string is valid or not
1121 //
1122 if (!CheckIfStringIsSafe(Val, IsWstring))
1123 {
1124 return FALSE;
1125 }
1126
1127 //
1128 // get the length of the string (format) identifier
1129 //
1130 *CurrentProcessedPositionFromStartOfFormat += (UINT32)strlen(CurrentSpecifier);
1131
1132 //
1133 // Get string len
1134 //
1135 StringSize = CustomStrlen(Val, IsWstring);
1136
1137 //
1138 // Check final buffer capacity
1139 //
1140 if (*CurrentPositionInFinalBuffer + StringSize > SizeOfFinalBuffer)
1141 {
1142 //
1143 // Over passed buffer
1144 //
1145 return TRUE;
1146 }
1147
1148 //
1149 // Move the buffer string into the target buffer
1150 //
1151 if (IsWstring)
1152 {
1153 //
1154 // Parse wstring
1155 //
1156 StringSizeInByte = StringSize * 2; /* because of wide-char */
1157
1158 //
1159 // compute the ceiling
1160 //
1161 if (StringSizeInByte % sizeof(WstrBuffer) == 0)
1162 {
1163 CountOfBlocks = StringSizeInByte / sizeof(WstrBuffer);
1164 }
1165 else
1166 {
1167 CountOfBlocks = (StringSizeInByte / sizeof(WstrBuffer)) + 1;
1168 }
1169
1170 for (size_t i = 0; i < CountOfBlocks; i++)
1171 {
1172 //
1173 // Zero the buffers
1174 //
1175 RtlZeroMemory(WstrBuffer, sizeof(WstrBuffer));
1176 RtlZeroMemory(AsciiBuffer, sizeof(AsciiBuffer));
1177
1178 //
1179 // Check for the last block
1180 //
1181 if (i == CountOfBlocks - 1)
1182 {
1183 //
1184 // A portion of block
1185 //
1186
1187#ifdef SCRIPT_ENGINE_USER_MODE
1188 memcpy(WstrBuffer, (void *)(Val + (i * sizeof(WstrBuffer))), StringSizeInByte % sizeof(WstrBuffer));
1189#endif // SCRIPT_ENGINE_USER_MODE
1190
1191#ifdef SCRIPT_ENGINE_KERNEL_MODE
1193 (UINT64)(Val + (i * sizeof(WstrBuffer))),
1194 WstrBuffer,
1195 StringSizeInByte % sizeof(WstrBuffer));
1196#endif // SCRIPT_ENGINE_KERNEL_MODE
1197 }
1198 else
1199 {
1200 //
1201 // A complete block
1202 //
1203
1204#ifdef SCRIPT_ENGINE_USER_MODE
1205 memcpy(WstrBuffer, (void *)(Val + (i * sizeof(WstrBuffer))), sizeof(WstrBuffer));
1206#endif // SCRIPT_ENGINE_USER_MODE
1207
1208#ifdef SCRIPT_ENGINE_KERNEL_MODE
1210 (UINT64)(Val + (i * sizeof(WstrBuffer))),
1211 WstrBuffer,
1212 sizeof(WstrBuffer));
1213#endif // SCRIPT_ENGINE_KERNEL_MODE
1214 }
1215
1216 //
1217 // Here we have the filled WstrBuffer
1218 // We should convert WstrBuffer to AsciiBuffer
1219 //
1220 CopiedBlockLen =
1221 (UINT32)WcharToChar(WstrBuffer, AsciiBuffer, sizeof(AsciiBuffer) + 1);
1222
1223 //
1224 // Now we should move the AsciiBuffer to the target buffer
1225 // (when we filled AsciiBuffer the memory here is safe so we
1226 // can use memcpy in both user-mode and vmx-root mode)
1227 //
1228 memcpy(&FinalBuffer[*CurrentPositionInFinalBuffer], (void *)AsciiBuffer, CopiedBlockLen + 1);
1229
1230 *CurrentPositionInFinalBuffer += CopiedBlockLen + 1;
1231 }
1232 }
1233 else
1234 {
1235 //
1236 // Parse string
1237 //
1238#ifdef SCRIPT_ENGINE_USER_MODE
1239 memcpy(&FinalBuffer[*CurrentPositionInFinalBuffer], (void *)Val, StringSize);
1240#endif // SCRIPT_ENGINE_USER_MODE
1241
1242#ifdef SCRIPT_ENGINE_KERNEL_MODE
1244 Val,
1245 &FinalBuffer[*CurrentPositionInFinalBuffer],
1246 StringSize);
1247#endif // SCRIPT_ENGINE_KERNEL_MODE
1248
1249 *CurrentPositionInFinalBuffer += StringSize;
1250 }
1251
1252 return TRUE;
1253}
#define TRUE
Definition BasicTypes.h:55
#define FALSE
Definition BasicTypes.h:54
unsigned __int64 UINT64
Definition BasicTypes.h:21
BOOLEAN CheckIfStringIsSafe(UINT64 StrAddr, BOOLEAN IsWstring)
Check if string is safe to be accessed or not (in vmx-root mode)
Definition Functions.c:997
UINT32 CustomStrlen(UINT64 StrAddr, BOOLEAN IsWstring)
Custom VMX-root compatible strlen.
Definition Functions.c:963
size_t WcharToChar(const wchar_t *src, char *dest, size_t dest_len)
Convert WCHAR* to CHAR*.
Definition Functions.c:1068
_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafeOnTargetProcess(UINT64 VaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead)
Read memory safely by mapping the buffer on the target process memory (It's a wrapper)
Definition MemoryMapper.c:1120

◆ CheckIfStringIsSafe()

BOOLEAN CheckIfStringIsSafe ( UINT64 StrAddr,
BOOLEAN IsWstring )

Check if string is safe to be accessed or not (in vmx-root mode)

Parameters
StrAddr
IsWstring
Returns
BOOLEAN
998{
999#ifdef SCRIPT_ENGINE_USER_MODE
1000 return TRUE;
1001#endif // SCRIPT_ENGINE_USER_MODE
1002
1003#ifdef SCRIPT_ENGINE_KERNEL_MODE
1004
1005 //
1006 // At least two chars (wchar_t is 4 byte)
1007 //
1008 if (CheckAccessValidityAndSafety(StrAddr, IsWstring ? 4 : 2))
1009 {
1010 return TRUE;
1011 }
1012 else
1013 {
1014 return FALSE;
1015 }
1016#endif // SCRIPT_ENGINE_KERNEL_MODE
1017}
BOOLEAN CheckAccessValidityAndSafety(UINT64 TargetAddress, UINT32 Size)
Check the safety to access the memory.
Definition AddressCheck.c:156

◆ CustomStrlen()

UINT32 CustomStrlen ( UINT64 StrAddr,
BOOLEAN IsWstring )

Custom VMX-root compatible strlen.

Parameters
StrAddr
IsWstring
Returns
UINT32
964{
965#ifdef SCRIPT_ENGINE_USER_MODE
966
967 if (IsWstring)
968 {
969 return (UINT32)wcslen((const wchar_t *)StrAddr);
970 }
971 else
972 {
973 return (UINT32)strlen((const char *)StrAddr);
974 }
975#endif // SCRIPT_ENGINE_USER_MODE
976
977#ifdef SCRIPT_ENGINE_KERNEL_MODE
978 if (IsWstring)
979 {
980 return VmFuncVmxCompatibleWcslen((const wchar_t *)StrAddr);
981 }
982 else
983 {
984 return VmFuncVmxCompatibleStrlen((const CHAR *)StrAddr);
985 }
986#endif // SCRIPT_ENGINE_KERNEL_MODE
987}
UINT32 VmFuncVmxCompatibleStrlen(const CHAR *s)
VMX-root compatible strlen.
Definition Export.c:599
UINT32 VmFuncVmxCompatibleWcslen(const wchar_t *s)
VMX-root compatible strlen.
Definition Export.c:611

◆ GetValue()

UINT64 GetValue ( PGUEST_REGS GuestRegs,
PACTION_BUFFER ActionBuffer,
SCRIPT_ENGINE_VARIABLES_LIST * VariablesList,
PSYMBOL Symbol,
BOOLEAN ReturnReference,
SYMBOL_BUFFER * StackBuffer,
UINT64 * StackIndx,
UINT64 * StackBaseIndx,
UINT64 * ReturnValue )

◆ ScriptEngineFunctionCheckAddress()

BOOLEAN ScriptEngineFunctionCheckAddress ( UINT64 Address,
UINT32 Length )

Check whether the address is valid or not.

Parameters
Address
Length
Returns
BOOLEAN
169{
170#ifdef SCRIPT_ENGINE_USER_MODE
171
173 {
174 return TRUE;
175 }
176
177#endif // SCRIPT_ENGINE_USER_MODE
178
179#ifdef SCRIPT_ENGINE_KERNEL_MODE
180
182 {
183 return TRUE;
184 }
185
186#endif // SCRIPT_ENGINE_KERNEL_MODE
187
188 return FALSE;
189}
UINT64 Address
Definition HyperDbgScriptImports.h:67

◆ ScriptEngineFunctionDisassembleLen()

UINT64 ScriptEngineFunctionDisassembleLen ( PVOID Address,
BOOLEAN Is32Bit )

Implementation of disassemble_len function.

Parameters
Address
Is32Bit
Returns
UINT64
525{
526 UINT64 Result = 0;
527#ifdef SCRIPT_ENGINE_USER_MODE
528 Result = HyperDbgLengthDisassemblerEngine((unsigned char *)Address, MAXIMUM_INSTR_SIZE, Is32Bit ? FALSE : TRUE);
529#endif // SCRIPT_ENGINE_USER_MODE
530
531#ifdef SCRIPT_ENGINE_KERNEL_MODE
533#endif // SCRIPT_ENGINE_KERNEL_MODE
534
535 return Result;
536}
#define MAXIMUM_INSTR_SIZE
maximum instruction size in Intel
Definition Constants.h:468
UINT32 DisassemblerLengthDisassembleEngineInVmxRootOnTargetProcess(PVOID Address, BOOLEAN Is32Bit)
Disassembler length disassembler engine.
Definition Disassembler.c:297
UINT32 HyperDbgLengthDisassemblerEngine(unsigned char *BufferToDisassemble, UINT64 BuffLength, BOOLEAN Isx86_64)
Length Disassembler engine based on Zydis.
Definition disassembler.cpp:856

◆ ScriptEngineFunctionEb()

BOOLEAN ScriptEngineFunctionEb ( UINT64 Address,
BYTE Value,
BOOL * HasError )

Implementation of eb function.

Parameters
Address
Value
HasError
Returns
BOOLEAN
131{
132 UNREFERENCED_PARAMETER(HasError);
133
134#ifdef SCRIPT_ENGINE_KERNEL_MODE
135
137 {
138 //
139 // Instead of indicating an error, just return false
140 // to assign it as a return result to a variable
141 //
142 // *HasError = TRUE;
143
144 return FALSE;
145 }
146
147#endif // SCRIPT_ENGINE_KERNEL_MODE
148
149#ifdef SCRIPT_ENGINE_USER_MODE
150 *(BYTE *)Address = Value;
151#endif // SCRIPT_ENGINE_USER_MODE
152
153#ifdef SCRIPT_ENGINE_KERNEL_MODE
155#endif // SCRIPT_ENGINE_KERNEL_MODE
156
157 return TRUE;
158}
unsigned char BYTE
Definition BasicTypes.h:24
_Use_decl_annotations_ BOOLEAN MemoryMapperWriteMemorySafeOnTargetProcess(UINT64 Destination, PVOID Source, SIZE_T Size)
Write memory safely by mapping the buffer on the target process memory (It's a wrapper)
Definition MemoryMapper.c:1165
RequestedActionOfThePacket Value(0x1) 00000000

◆ ScriptEngineFunctionEd()

BOOLEAN ScriptEngineFunctionEd ( UINT64 Address,
DWORD Value,
BOOL * HasError )

Implementation of ed function.

Parameters
Address
Value
HasError
Returns
BOOLEAN
92{
93 UNREFERENCED_PARAMETER(HasError);
94
95#ifdef SCRIPT_ENGINE_KERNEL_MODE
96
98 {
99 //
100 // Instead of indicating an error, just return false
101 // to assign it as a return result to a variable
102 //
103 // *HasError = TRUE;
104
105 return FALSE;
106 }
107
108#endif // SCRIPT_ENGINE_KERNEL_MODE
109
110#ifdef SCRIPT_ENGINE_USER_MODE
111 *(DWORD *)Address = Value;
112#endif // SCRIPT_ENGINE_USER_MODE
113
114#ifdef SCRIPT_ENGINE_KERNEL_MODE
116#endif // SCRIPT_ENGINE_KERNEL_MODE
117
118 return TRUE;
119}
unsigned long DWORD
Definition BasicTypes.h:22

◆ ScriptEngineFunctionEq()

BOOLEAN ScriptEngineFunctionEq ( UINT64 Address,
QWORD Value,
BOOL * HasError )

Implementation of eq function.

Parameters
Address
Value
HasError
Returns
BOOLEAN
53{
54 UNREFERENCED_PARAMETER(HasError);
55
56#ifdef SCRIPT_ENGINE_KERNEL_MODE
57
59 {
60 //
61 // Instead of indicating an error, just return false
62 // to assign it as a return result to a variable
63 //
64 // *HasError = TRUE;
65
66 return FALSE;
67 }
68
69#endif // SCRIPT_ENGINE_KERNEL_MODE
70
71#ifdef SCRIPT_ENGINE_USER_MODE
72 *(UINT64 *)Address = Value;
73#endif // SCRIPT_ENGINE_USER_MODE
74
75#ifdef SCRIPT_ENGINE_KERNEL_MODE
77#endif // SCRIPT_ENGINE_KERNEL_MODE
78
79 return TRUE;
80}
unsigned long long QWORD
Definition BasicTypes.h:20

◆ ScriptEngineFunctionEventClear()

VOID ScriptEngineFunctionEventClear ( UINT64 EventId)

Implementation of event_clear function.

Parameters
EventId
Returns
VOID
762{
763#ifdef SCRIPT_ENGINE_USER_MODE
764 ShowMessages("err, disabling events is not possible in user-mode\n");
765#endif // SCRIPT_ENGINE_USER_MODE
766
767#ifdef SCRIPT_ENGINE_KERNEL_MODE
768
769 BOOLEAN PoolManagerAllocatedMemory = FALSE;
770
772 {
773 PoolManagerAllocatedMemory = TRUE;
774 }
775
776 if (!DebuggerClearEvent(EventId + DebuggerEventTagStartSeed, VmFuncVmxGetCurrentExecutionMode(), PoolManagerAllocatedMemory))
777 {
778 LogInfo("Invalid tag id (%x)", EventId);
779 }
780#endif // SCRIPT_ENGINE_KERNEL_MODE
781}
UCHAR BOOLEAN
Definition BasicTypes.h:39
#define EnableInstantEventMechanism
Enable or disable the instant event mechanism.
Definition Configuration.h:75
#define DebuggerEventTagStartSeed
The seeds that user-mode codes use as the starter of their events' tag.
Definition Constants.h:222
BOOLEAN DebuggerClearEvent(UINT64 Tag, BOOLEAN InputFromVmxRoot, BOOLEAN PoolManagerAllocatedMemory)
Clear an event by tag.
Definition Debugger.c:2400
BOOLEAN VmFuncVmxGetCurrentExecutionMode()
Get the current VMX operation state.
Definition Export.c:552
#define LogInfo(format,...)
Define log variables.
Definition HyperDbgHyperLogIntrinsics.h:71
BOOLEAN g_KernelDebuggerState
shows whether the kernel debugger is enabled or disabled
Definition Global.h:103
VOID ShowMessages(const char *Fmt,...)
Show messages.
Definition libhyperdbg.cpp:96

◆ ScriptEngineFunctionEventDisable()

VOID ScriptEngineFunctionEventDisable ( UINT64 EventId)

Implementation of event_disable function.

Parameters
EventId
Returns
VOID
740{
741#ifdef SCRIPT_ENGINE_USER_MODE
742 ShowMessages("err, disabling events is not possible in user-mode\n");
743#endif // SCRIPT_ENGINE_USER_MODE
744
745#ifdef SCRIPT_ENGINE_KERNEL_MODE
747 {
748 LogInfo("Invalid tag id (%x)", EventId);
749 }
750#endif // SCRIPT_ENGINE_KERNEL_MODE
751}
BOOLEAN DebuggerDisableEvent(UINT64 Tag)
Disable an event by tag.
Definition Debugger.c:2363

◆ ScriptEngineFunctionEventEnable()

VOID ScriptEngineFunctionEventEnable ( UINT64 EventId)

Implementation of event_enable function.

Parameters
EventId
Returns
VOID
718{
719#ifdef SCRIPT_ENGINE_USER_MODE
720 ShowMessages("err, enabling events is not possible in user-mode\n");
721#endif // SCRIPT_ENGINE_USER_MODE
722
723#ifdef SCRIPT_ENGINE_KERNEL_MODE
725 {
726 LogInfo("Invalid tag id (%x)", EventId);
727 }
728#endif // SCRIPT_ENGINE_KERNEL_MODE
729}
BOOLEAN DebuggerEnableEvent(UINT64 Tag)
Enable an event by tag.
Definition Debugger.c:2302

◆ ScriptEngineFunctionEventInject()

VOID ScriptEngineFunctionEventInject ( UINT32 InterruptionType,
UINT32 Vector,
BOOL * HasError )

Implementation of event_inject function.

Parameters
InterruptionType
Vector
HasError
Returns
VOID
1505{
1506 UNREFERENCED_PARAMETER(HasError);
1507
1508#ifdef SCRIPT_ENGINE_USER_MODE
1509
1510 ShowMessages("err, event_inject is not supported in user-mode\n");
1511
1512#endif // SCRIPT_ENGINE_USER_MODE
1513
1514#ifdef SCRIPT_ENGINE_KERNEL_MODE
1515
1516 //
1517 // Validate the arguments
1518 //
1519 if (Vector >= 256 || InterruptionType >= 8)
1520 {
1521 LogInfo("Err, invalid event vector or interruption type is specified");
1522 return;
1523 }
1524 else
1525 {
1526 VmFuncEventInjectInterruption(InterruptionType, Vector, FALSE, 0);
1527 }
1528
1529#endif // SCRIPT_ENGINE_KERNEL_MODE
1530}
VOID VmFuncEventInjectInterruption(UINT32 InterruptionType, UINT32 Vector, BOOLEAN DeliverErrorCode, UINT32 ErrorCode)
Inject interrupt/faults/exceptions.
Definition Export.c:662

◆ ScriptEngineFunctionEventInjectErrorCode()

VOID ScriptEngineFunctionEventInjectErrorCode ( UINT32 InterruptionType,
UINT32 Vector,
UINT32 ErrorCode,
BOOL * HasError )

Implementation of event_inject_error_code function.

Parameters
InterruptionType
Vector
ErrorCode
HasError
Returns
VOID
1543{
1544 UNREFERENCED_PARAMETER(HasError);
1545
1546#ifdef SCRIPT_ENGINE_USER_MODE
1547
1548 ShowMessages("err, event_inject is not supported in user-mode\n");
1549
1550#endif // SCRIPT_ENGINE_USER_MODE
1551
1552#ifdef SCRIPT_ENGINE_KERNEL_MODE
1553
1554 //
1555 // Validate the arguments
1556 //
1557 if (Vector >= 256 || InterruptionType >= 8)
1558 {
1559 LogInfo("Err, invalid event vector or interruption type is specified");
1560 return;
1561 }
1562 else
1563 {
1564 VmFuncEventInjectInterruption(InterruptionType, Vector, TRUE, ErrorCode);
1565 }
1566
1567#endif // SCRIPT_ENGINE_KERNEL_MODE
1568}

◆ ScriptEngineFunctionEventTraceInstrumentationStep()

VOID ScriptEngineFunctionEventTraceInstrumentationStep ( )

Implementation of event_trace_instrumentation_step function.

Returns
VOID
1694{
1695#ifdef SCRIPT_ENGINE_USER_MODE
1696 ShowMessages("err, it's not possible to call event_trace_instrumentation_step function in the user-mode\n");
1697#endif // SCRIPT_ENGINE_USER_MODE
1698
1699#ifdef SCRIPT_ENGINE_KERNEL_MODE
1700
1701 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
1702
1703 //
1704 // Call instrumentation step in
1705 //
1707
1708#endif // SCRIPT_ENGINE_KERNEL_MODE
1709}
unsigned long ULONG
Definition BasicTypes.h:37
VOID TracingPerformInstrumentationStepIn(PROCESSOR_DEBUGGING_STATE *DbgState)
Perform tracing of instructions (instrumentation step-in)
Definition Tracing.c:22
PROCESSOR_DEBUGGING_STATE * g_DbgState
Save the state and variables related to debugging on each to logical core.
Definition Global.h:17

◆ ScriptEngineFunctionEventTraceStepIn()

VOID ScriptEngineFunctionEventTraceStepIn ( )

Implementation of event_trace_step_in function.

Returns
VOID
1718{
1719#ifdef SCRIPT_ENGINE_USER_MODE
1720 ShowMessages("err, it's not possible to call event_trace_instrumentation_step function in the user-mode\n");
1721#endif // SCRIPT_ENGINE_USER_MODE
1722
1723#ifdef SCRIPT_ENGINE_KERNEL_MODE
1724
1725 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
1726
1727 //
1728 // Call instrumentation step in
1729 //
1731
1732#endif // SCRIPT_ENGINE_KERNEL_MODE
1733}
VOID TracingPerformRegularStepInInstruction(PROCESSOR_DEBUGGING_STATE *DbgState)
Regular step-in | step one instruction to the debuggee.
Definition Tracing.c:113

◆ ScriptEngineFunctionFlush()

VOID ScriptEngineFunctionFlush ( )

Implementation of flush function.

Returns
VOID
867{
868#ifdef SCRIPT_ENGINE_USER_MODE
869 ShowMessages("err, it's not possible to flush buffers in user-mode\n");
870#endif // SCRIPT_ENGINE_USER_MODE
871
872#ifdef SCRIPT_ENGINE_KERNEL_MODE
873
874 //
875 // Mark all buffers as read
876 //
879
880#endif // SCRIPT_ENGINE_KERNEL_MODE
881}
UINT32 LogMarkAllAsRead(BOOLEAN IsVmxRoot)
Mark all buffers as read.
Definition Logging.c:558

◆ ScriptEngineFunctionFormats()

VOID ScriptEngineFunctionFormats ( UINT64 Tag,
BOOLEAN ImmediateMessagePassing,
UINT64 Value )

Implementation of formats function.

Parameters
Tag
ImmediateMessagePassing
Value
Returns
VOID
930{
931#ifdef SCRIPT_ENGINE_USER_MODE
932
933 ScriptEngineFunctionTestStatement(Tag, ImmediateMessagePassing, Value);
934
935#endif // SCRIPT_ENGINE_USER_MODE
936
937#ifdef SCRIPT_ENGINE_KERNEL_MODE
939 {
941 }
942 else
943 {
944 //
945 // Prepare a buffer to bypass allocating a huge stack space for logging
946 //
947 char TempBuffer[20] = {0};
948 UINT32 TempBufferLen = sprintf(TempBuffer, "%llx\n", Value);
949
950 LogSimpleWithTag((UINT32)Tag, ImmediateMessagePassing, TempBuffer, TempBufferLen + 1);
951 }
952#endif // SCRIPT_ENGINE_KERNEL_MODE
953}
VOID ScriptEngineFunctionTestStatement(UINT64 Tag, BOOLEAN ImmediateMessagePassing, UINT64 Value)
Implementation of test_statement function.
Definition Functions.c:392
POOL_TYPE SIZE_T ULONG Tag
Definition Hooks.h:168
#define LogSimpleWithTag(tag, isimmdte, buffer, len)
Log without any prefix and bypass the stack problem (getting two temporary stacks in preparing phase)
Definition HyperDbgHyperLogIntrinsics.h:142
VOID KdSendFormatsFunctionResult(UINT64 Value)
Notify user-mode to unload the debuggee and close the connections.
Definition Kd.c:900

◆ ScriptEngineFunctionInterlockedCompareExchange()

long long ScriptEngineFunctionInterlockedCompareExchange ( long long volatile * Destination,
long long ExChange,
long long Comperand,
BOOL * HasError )

Implementation of interlocked_compare_exchange function.

Parameters
Destination
ExChange
Comperand
HasError
Returns
long long
691{
692 long long Result = 0;
693
694#ifdef SCRIPT_ENGINE_KERNEL_MODE
695
696 if (!CheckAccessValidityAndSafety((UINT64)Destination, sizeof(long long)))
697 {
698 *HasError = TRUE;
699 return (long long)NULL;
700 }
701
702#endif // SCRIPT_ENGINE_KERNEL_MODE
703
704 Result = InterlockedCompareExchange64(Destination, ExChange, Comperand);
705
706 return Result;
707}
NULL()
Definition test-case-generator.py:530

◆ ScriptEngineFunctionInterlockedDecrement()

long long ScriptEngineFunctionInterlockedDecrement ( long long volatile * Addend,
BOOL * HasError )

Implementation of interlocked_exchange_decrement function.

Parameters
Addend
HasError
Returns
long long
658{
659 long long Result = 0;
660
661#ifdef SCRIPT_ENGINE_KERNEL_MODE
662
663 if (!CheckAccessValidityAndSafety((UINT64)Addend, sizeof(long long)))
664 {
665 *HasError = TRUE;
666 return (long long)NULL;
667 }
668
669#endif // SCRIPT_ENGINE_KERNEL_MODE
670
671 Result = InterlockedDecrement64(Addend);
672
673 return Result;
674}

◆ ScriptEngineFunctionInterlockedExchange()

long long ScriptEngineFunctionInterlockedExchange ( long long volatile * Target,
long long Value,
BOOL * HasError )

Implementation of interlocked_exchange function.

Parameters
Target
Value
HasError
Returns
long long
572{
573 long long Result = 0;
574
575#ifdef SCRIPT_ENGINE_KERNEL_MODE
576
577 if (!CheckAccessValidityAndSafety((UINT64)Target, sizeof(long long)))
578 {
579 *HasError = TRUE;
580 return (long long)NULL;
581 }
582
583#endif // SCRIPT_ENGINE_KERNEL_MODE
584
585 Result = InterlockedExchange64(Target, Value);
586
587 return Result;
588}

◆ ScriptEngineFunctionInterlockedExchangeAdd()

long long ScriptEngineFunctionInterlockedExchangeAdd ( long long volatile * Addend,
long long Value,
BOOL * HasError )

Implementation of interlocked_exchange_add function.

Parameters
Addend
Value
HasError
Returns
long long
602{
603 long long Result = 0;
604
605#ifdef SCRIPT_ENGINE_KERNEL_MODE
606
607 if (!CheckAccessValidityAndSafety((UINT64)Addend, sizeof(long long)))
608 {
609 *HasError = TRUE;
610 return (long long)NULL;
611 }
612
613#endif // SCRIPT_ENGINE_KERNEL_MODE
614
615 Result = InterlockedExchangeAdd64(Addend, Value);
616
617 return Result;
618}

◆ ScriptEngineFunctionInterlockedIncrement()

long long ScriptEngineFunctionInterlockedIncrement ( long long volatile * Addend,
BOOL * HasError )

Implementation of interlocked_exchange_increment function.

Parameters
Addend
HasError
Returns
long long
630{
631 long long Result = 0;
632
633#ifdef SCRIPT_ENGINE_KERNEL_MODE
634
635 if (!CheckAccessValidityAndSafety((UINT64)Addend, sizeof(long long)))
636 {
637 *HasError = TRUE;
638 return (long long)NULL;
639 }
640
641#endif // SCRIPT_ENGINE_KERNEL_MODE
642
643 Result = InterlockedIncrement64(Addend);
644
645 return Result;
646}

◆ ScriptEngineFunctionMemcmp()

UINT64 ScriptEngineFunctionMemcmp ( const char * Address1,
const char * Address2,
size_t Count )

Implementation of memcmp function.

Parameters
Address1
Address2
Count
Returns
UINT64
1674{
1675 UINT64 Result = 0;
1676#ifdef SCRIPT_ENGINE_USER_MODE
1677 Result = memcmp(Address1, Address2, Count);
1678#endif // SCRIPT_ENGINE_USER_MODE
1679
1680#ifdef SCRIPT_ENGINE_KERNEL_MODE
1681 Result = VmFuncVmxCompatibleMemcmp(Address1, Address2, Count);
1682#endif // SCRIPT_ENGINE_KERNEL_MODE
1683
1684 return Result;
1685}
INT32 VmFuncVmxCompatibleMemcmp(const CHAR *Address1, const CHAR *Address2, size_t Count)
VMX-root compatible memcmp.
Definition Export.c:787

◆ ScriptEngineFunctionMemcpy()

VOID ScriptEngineFunctionMemcpy ( UINT64 Destination,
UINT64 Source,
UINT32 Num,
BOOL * HasError )

A VMX-compatible equivalent of memcpy function in C.

Parameters
Destination
Source
Num
HasError
Returns
VOID
202{
203 UINT64 PrevReadLen = 0;
205
206#ifdef SCRIPT_ENGINE_USER_MODE
207
208 //
209 // Check the destination address
210 //
211 if (!CheckAccessValidityAndSafety(Destination, Num))
212 {
213 *HasError = TRUE;
214 return;
215 }
216
217 //
218 // Check the source address
219 //
220 if (!CheckAccessValidityAndSafety(Source, Num))
221 {
222 *HasError = TRUE;
223 return;
224 }
225
226 //
227 // Address is valid, perform the memcpy in user-mode
228 //
229 memcpy((void *)Destination, (void *)Source, Num);
230
231#endif // SCRIPT_ENGINE_USER_MODE
232
233#ifdef SCRIPT_ENGINE_KERNEL_MODE
234
235 //
236 // Check the destination address
237 //
238 if (!CheckAccessValidityAndSafety(Destination, Num))
239 {
240 *HasError = TRUE;
241 return;
242 }
243
244 //
245 // Check the source address
246 //
247 if (!CheckAccessValidityAndSafety(Source, Num))
248 {
249 *HasError = TRUE;
250 return;
251 }
252
253 //
254 // Address is valid, perform the memcpy in kernel-mode (VMX-root mode)
255 //
256 while (Num > 0)
257 {
258 //
259 // Check the target buffer size
260 //
262 {
263 //
264 // *** The size of read buffer is greater to maximum the moving buffer size ***
265 //
266
267 //
268 // Read memory into the buffer
269 //
271
272 //
273 // Write the moving buffer into the target buffer
274 //
276
277 //
278 // Computing the bytes that we read
279 //
282 }
283 else
284 {
285 //
286 // *** The size of read buffer is lower than or equal to the moving buffer size ***
287 //
288
289 //
290 // Read memory into the buffer
291 //
292 MemoryMapperReadMemorySafeOnTargetProcess(Source + PrevReadLen, MovingBuffer, Num);
293
294 //
295 // Write the moving buffer into the target buffer
296 //
297 MemoryMapperWriteMemorySafeOnTargetProcess(Destination + PrevReadLen, MovingBuffer, Num);
298
299 //
300 // Computing the bytes that we gonna read
301 //
302 PrevReadLen += Num;
303 Num = 0; // or Num -= Num;
304 }
305 }
306
307#endif // SCRIPT_ENGINE_KERNEL_MODE
308}
#define DebuggerScriptEngineMemcpyMovingBufferSize
The size of each chunk of memory used in the 'memcpy' function of the script engine for transferring ...
Definition Constants.h:250

◆ ScriptEngineFunctionPause()

VOID ScriptEngineFunctionPause ( ACTION_BUFFER * ActionDetail,
PGUEST_REGS GuestRegs )

Implementation of pause function.

Parameters
ActionDetail
GuestRegs
Returns
VOID
795{
796#ifdef SCRIPT_ENGINE_USER_MODE
797 ShowMessages("err, breaking is not possible in user-mode\n");
798#endif // SCRIPT_ENGINE_USER_MODE
799
800#ifdef SCRIPT_ENGINE_KERNEL_MODE
801
802 //
803 // pause(); function is only working when kernel debugger is working
804 // it's not designed to work on vmi-mode (local debugging)
805 //
807 {
808 DEBUGGER_TRIGGERED_EVENT_DETAILS TriggeredEventDetail = {0};
809 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
810
811 //
812 // Make the details of context
813 //
814 TriggeredEventDetail.Tag = ActionDetail->Tag;
815 TriggeredEventDetail.Context = (PVOID)ActionDetail->Context;
816
817 if (ActionDetail->CallingStage == 1)
818 {
819 TriggeredEventDetail.Stage = VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION;
820 }
821 else
822 {
823 TriggeredEventDetail.Stage = VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION;
824 }
825
827 {
828 //
829 // The guest is already in vmx-root mode
830 // Halt other cores
831 //
832
834 CurrentCore,
836 &TriggeredEventDetail);
837 }
838 else
839 {
840 //
841 // The guest is on vmx non-root mode, the first parameter
842 // is context and the second parameter is tag
843 //
845 (UINT64)&TriggeredEventDetail,
846 (UINT64)GuestRegs,
847 (UINT64)NULL);
848 }
849 }
850 else
851 {
852 LogInfo("The 'pause();' function is either called from the vmi-mode or is "
853 "evaluated by the '?' command. It's not allowed to use it on vmi-mode "
854 "(local debugging) or by the '?' command");
855 }
856
857#endif // SCRIPT_ENGINE_KERNEL_MODE
858}
@ DEBUGGEE_PAUSING_REASON_DEBUGGEE_EVENT_TRIGGERED
Definition Connection.h:35
@ DEBUGGEE_PAUSING_REASON_NOT_PAUSED
Definition Connection.h:24
@ VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION
Definition DataTypes.h:93
@ VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION
Definition DataTypes.h:94
#define DEBUGGER_VMCALL_VM_EXIT_HALT_SYSTEM_AS_A_RESULT_OF_TRIGGERING_EVENT
VMCALL to cause vm-exit and halt the system because of triggering an event.
Definition DebuggerVmcalls.h:29
NTSTATUS VmFuncVmxVmcall(unsigned long long VmcallNumber, unsigned long long OptionalParam1, unsigned long long OptionalParam2, unsigned long long OptionalParam3)
Export for running VMX VMCALLs.
Definition Export.c:683
_Use_decl_annotations_ VOID KdHandleBreakpointAndDebugBreakpointsCallback(UINT32 CoreId, DEBUGGEE_PAUSING_REASON Reason, PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails)
Handle #DBs and #BPs for kernel debugger.
Definition Kd.c:1124
DEBUGGEE_PAUSING_REASON g_DebuggeeHaltReason
Reason that the debuggee is halted.
Definition Global.h:127
The structure of detail of a triggered event in HyperDbg.
Definition DataTypes.h:192
UINT64 Tag
Definition DataTypes.h:193
PVOID Context
Definition DataTypes.h:194
long long unsigned Context
Definition ScriptEngineCommonDefinitions.h:38
long long unsigned Tag
Definition ScriptEngineCommonDefinitions.h:35
char CallingStage
Definition ScriptEngineCommonDefinitions.h:39

◆ ScriptEngineFunctionPhysicalToVirtual()

UINT64 ScriptEngineFunctionPhysicalToVirtual ( UINT64 Address)

Convert physical address to virtual address.

Parameters
Address
Returns
UINT64
339{
340#ifdef SCRIPT_ENGINE_USER_MODE
341
342 //
343 // There is no conversion in user-mode
344 //
345 return NULL;
346#endif // SCRIPT_ENGINE_USER_MODE
347
348#ifdef SCRIPT_ENGINE_KERNEL_MODE
349
351
352#endif // SCRIPT_ENGINE_KERNEL_MODE
353}
_Use_decl_annotations_ UINT64 PhysicalAddressToVirtualAddressOnTargetProcess(PVOID PhysicalAddress)
Converts Physical Address to Virtual Address based on current process's kernel cr3.
Definition Conversion.c:137

◆ ScriptEngineFunctionPrint()

VOID ScriptEngineFunctionPrint ( UINT64 Tag,
BOOLEAN ImmediateMessagePassing,
UINT64 Value )

Implementation of print function.

Parameters
Tag
ImmediateMessagePassing
Value
Returns
VOID
365{
366#ifdef SCRIPT_ENGINE_USER_MODE
367 ShowMessages("%llx\n", Value);
368#endif // SCRIPT_ENGINE_USER_MODE
369
370#ifdef SCRIPT_ENGINE_KERNEL_MODE
371
372 //
373 // Prepare a buffer to bypass allocating a huge stack space for logging
374 //
375 char TempBuffer[20] = {0};
376 UINT32 TempBufferLen = sprintf(TempBuffer, "%llx", Value);
377
378 LogSimpleWithTag((UINT32)Tag, ImmediateMessagePassing, TempBuffer, TempBufferLen + 1);
379
380#endif // SCRIPT_ENGINE_KERNEL_MODE
381}

◆ ScriptEngineFunctionPrintf()

VOID ScriptEngineFunctionPrintf ( PGUEST_REGS GuestRegs,
ACTION_BUFFER * ActionDetail,
SCRIPT_ENGINE_VARIABLES_LIST * VariablesList,
UINT64 Tag,
BOOLEAN ImmediateMessagePassing,
char * Format,
UINT64 ArgCount,
PSYMBOL FirstArg,
BOOLEAN * HasError,
SYMBOL_BUFFER * StackBuffer,
UINT64 * StackIndx,
UINT64 * StackBaseIndx,
UINT64 * ReturnValue )

Implementation of printf function.

Parameters
GuestRegs
ActionDetail
VariablesList
Tag
ImmediateMessagePassing
Format
ArgCount
FirstArg
HasError
Returns
VOID
1283{
1284 //
1285 // *** The printf function ***
1286 //
1287
1288 char FinalBuffer[PacketChunkSize] = {0};
1289 UINT32 CurrentPositionInFinalBuffer = 0;
1290 UINT32 CurrentProcessedPositionFromStartOfFormat = 0;
1291 BOOLEAN WithoutAnyFormatSpecifier = TRUE;
1292
1293 UINT64 Val;
1294 UINT32 Position;
1295 UINT32 LenOfFormats = (UINT32)strlen(Format) + 1;
1296 PSYMBOL Symbol;
1297
1298 *HasError = FALSE;
1299
1300 for (int i = 0; i < ArgCount; i++)
1301 {
1302 WithoutAnyFormatSpecifier = FALSE;
1303 Symbol = FirstArg + i;
1304
1305 //
1306 // Address is either wstring (%ws) or string (%s)
1307 //
1308
1309 Position = (Symbol->Type >> 32) + 1;
1310
1311 SYMBOL TempSymbol = {0};
1312 memcpy(&TempSymbol, Symbol, sizeof(SYMBOL));
1313 TempSymbol.Type &= 0x7fffffff;
1314
1315 Val = GetValue(GuestRegs, ActionDetail, VariablesList, &TempSymbol, FALSE, StackBuffer, StackIndx, StackBaseIndx, ReturnValue);
1316
1317 CHAR PercentageChar = Format[Position];
1318
1319 /*
1320 printf("position = %d is %c%c \n", Position, PercentageChar,
1321 IndicatorChar1);
1322 */
1323
1324 if (CurrentProcessedPositionFromStartOfFormat != Position)
1325 {
1326 //
1327 // There is some strings before this format specifier
1328 // we should move it to the buffer
1329 //
1330 UINT32 StringLen = Position - CurrentProcessedPositionFromStartOfFormat;
1331
1332 //
1333 // Check final buffer capacity
1334 //
1335 if (CurrentPositionInFinalBuffer + StringLen < sizeof(FinalBuffer))
1336 {
1337 memcpy(&FinalBuffer[CurrentPositionInFinalBuffer],
1338 &Format[CurrentProcessedPositionFromStartOfFormat],
1339 StringLen);
1340
1341 CurrentProcessedPositionFromStartOfFormat += StringLen;
1342 CurrentPositionInFinalBuffer += StringLen;
1343 }
1344 }
1345
1346 //
1347 // Double check and apply
1348 //
1349 if (PercentageChar == '%')
1350 {
1351 //
1352 // Set first character of specifier
1353 //
1354 CHAR FormatSpecifier[5] = {0};
1355 FormatSpecifier[0] = '%';
1356
1357 //
1358 // Read second char
1359 //
1360 CHAR IndicatorChar2 = Format[Position + 1];
1361
1362 //
1363 // Check if IndicatorChar2 is 2 character long or more
1364 //
1365 if (IndicatorChar2 == 'l' || IndicatorChar2 == 'w' ||
1366 IndicatorChar2 == 'h')
1367 {
1368 //
1369 // Set second char in format specifier
1370 //
1371 FormatSpecifier[1] = IndicatorChar2;
1372
1373 if (IndicatorChar2 == 'l' && Format[Position + 2] == 'l')
1374 {
1375 //
1376 // Set third character in format specifier "ll"
1377 //
1378 FormatSpecifier[2] = 'l';
1379
1380 //
1381 // Set last character
1382 //
1383 FormatSpecifier[3] = Format[Position + 3];
1384 }
1385 else
1386 {
1387 //
1388 // Set last character
1389 //
1390 FormatSpecifier[2] = Format[Position + 2];
1391 }
1392 }
1393 else
1394 {
1395 //
1396 // It's a one char specifier (Set last character)
1397 //
1398 FormatSpecifier[1] = IndicatorChar2;
1399 }
1400
1401 //
1402 // Apply the specifier
1403 //
1404 if (!strncmp(FormatSpecifier, "%s", 2))
1405 {
1406 //
1407 // for string
1408 //
1410 "%s",
1411 FinalBuffer,
1412 &CurrentProcessedPositionFromStartOfFormat,
1413 &CurrentPositionInFinalBuffer,
1414 Val,
1415 FALSE,
1416 sizeof(FinalBuffer)))
1417 {
1418 *HasError = TRUE;
1419 return;
1420 }
1421 }
1422 else if (!strncmp(FormatSpecifier, "%ls", 3) ||
1423 !strncmp(FormatSpecifier, "%ws", 3))
1424 {
1425 //
1426 // for wide string (not important if %ls or %ws , only the length is
1427 // important)
1428 //
1430 "%ws",
1431 FinalBuffer,
1432 &CurrentProcessedPositionFromStartOfFormat,
1433 &CurrentPositionInFinalBuffer,
1434 Val,
1435 TRUE,
1436 sizeof(FinalBuffer)))
1437 {
1438 *HasError = TRUE;
1439 return;
1440 }
1441 }
1442 else
1443 {
1444 ApplyFormatSpecifier(FormatSpecifier, FinalBuffer, &CurrentProcessedPositionFromStartOfFormat, &CurrentPositionInFinalBuffer, Val, sizeof(FinalBuffer));
1445 }
1446 }
1447 }
1448
1449 if (WithoutAnyFormatSpecifier)
1450 {
1451 //
1452 // Means that it's just a simple print without any format specifier
1453 //
1454 if (LenOfFormats < sizeof(FinalBuffer))
1455 {
1456 memcpy(FinalBuffer, Format, LenOfFormats);
1457 }
1458 }
1459 else
1460 {
1461 //
1462 // Check if there is anything after the last format specifier
1463 //
1464 if (LenOfFormats > CurrentProcessedPositionFromStartOfFormat)
1465 {
1466 UINT32 RemainedLen =
1467 LenOfFormats - CurrentProcessedPositionFromStartOfFormat;
1468
1469 if (CurrentPositionInFinalBuffer + RemainedLen < sizeof(FinalBuffer))
1470 {
1471 memcpy(&FinalBuffer[CurrentPositionInFinalBuffer],
1472 &Format[CurrentProcessedPositionFromStartOfFormat],
1473 RemainedLen);
1474 }
1475 }
1476 }
1477
1478//
1479// Print final result
1480//
1481#ifdef SCRIPT_ENGINE_USER_MODE
1482 printf("%s", FinalBuffer);
1483#endif // SCRIPT_ENGINE_USER_MODE
1484
1485#ifdef SCRIPT_ENGINE_KERNEL_MODE
1486
1487 //
1488 // Prepare a buffer to bypass allocating a huge stack space for logging
1489 //
1490 LogSimpleWithTag((UINT32)Tag, ImmediateMessagePassing, FinalBuffer, (UINT32)strlen(FinalBuffer) + 1);
1491
1492#endif // SCRIPT_ENGINE_KERNEL_MODE
1493}
#define PacketChunkSize
Size of each packet.
Definition Constants.h:179
BOOLEAN ApplyStringFormatSpecifier(const CHAR *CurrentSpecifier, CHAR *FinalBuffer, PUINT32 CurrentProcessedPositionFromStartOfFormat, PUINT32 CurrentPositionInFinalBuffer, UINT64 Val, BOOLEAN IsWstring, UINT32 SizeOfFinalBuffer)
Apply string format specifiers (s, ws, etc.)
Definition Functions.c:1110
UINT64 GetValue(PGUEST_REGS GuestRegs, PACTION_BUFFER ActionBuffer, SCRIPT_ENGINE_VARIABLES_LIST *VariablesList, PSYMBOL Symbol, BOOLEAN ReturnReference, SYMBOL_BUFFER *StackBuffer, UINT64 *StackIndx, UINT64 *StackBaseIndx, UINT64 *ReturnValue)
VOID ApplyFormatSpecifier(const CHAR *CurrentSpecifier, CHAR *FinalBuffer, PUINT32 CurrentProcessedPositionFromStartOfFormat, PUINT32 CurrentPositionInFinalBuffer, UINT64 Val, UINT32 SizeOfFinalBuffer)
Apply format specifiers (d, x, llx, etc.)
Definition Functions.c:1031
Definition ScriptEngineCommonDefinitions.h:6
long long unsigned Type
Definition ScriptEngineCommonDefinitions.h:7

◆ ScriptEngineFunctionShortCircuitingEvent()

VOID ScriptEngineFunctionShortCircuitingEvent ( UINT64 State,
ACTION_BUFFER * ActionDetail )

Implementation of event_ignore function.

Parameters
State
ActionDetail
Returns
VOID
892{
893#ifdef SCRIPT_ENGINE_USER_MODE
894 ShowMessages("err, it's not possible to short-circuit events in user-mode\n");
895#endif // SCRIPT_ENGINE_USER_MODE
896
897#ifdef SCRIPT_ENGINE_KERNEL_MODE
898
899 if (ActionDetail->CallingStage == 1)
900 {
901 LogWarning("Warning, calling the 'event_sc' function in the 'post' calling stage doesn't make sense as the emulation is already performed!\n"
902 "You can use this function in the 'pre' calling stage");
903 return;
904 }
905
906 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
907
908 if (State != 0)
909 {
910 g_DbgState[CurrentCore].ShortCircuitingEvent = TRUE;
911 }
912 else
913 {
915 }
916
917#endif // SCRIPT_ENGINE_KERNEL_MODE
918}
#define LogWarning(format,...)
Log in the case of warning.
Definition HyperDbgHyperLogIntrinsics.h:99
BOOLEAN ShortCircuitingEvent
Definition State.h:170

◆ ScriptEngineFunctionSpinlockLock()

VOID ScriptEngineFunctionSpinlockLock ( volatile LONG * Lock,
BOOL * HasError )

Implementation of spinlock_lock function.

Parameters
Lock
HasError
Returns
VOID
415{
416#ifdef SCRIPT_ENGINE_USER_MODE
417
418 SpinlockLock(Lock);
419
420#endif // SCRIPT_ENGINE_USER_MODE
421
422#ifdef SCRIPT_ENGINE_KERNEL_MODE
423
424 if (!CheckAccessValidityAndSafety((UINT64)Lock, sizeof(LONG)))
425 {
426 *HasError = TRUE;
427 return;
428 }
429
430 SpinlockLock(Lock);
431
432#endif // SCRIPT_ENGINE_KERNEL_MODE
433}
void SpinlockLock(volatile LONG *Lock)
Tries to get the lock and won't return until successfully get the lock.
Definition Spinlock.c:52

◆ ScriptEngineFunctionSpinlockLockCustomWait()

VOID ScriptEngineFunctionSpinlockLockCustomWait ( volatile long * Lock,
unsigned MaxWait,
BOOL * HasError )

Implementation of spinlock_lock_custom_wait function.

Parameters
Lock
MaxWait
HasError
Returns
VOID
474{
475#ifdef SCRIPT_ENGINE_USER_MODE
476
477 SpinlockLockWithCustomWait(Lock, MaxWait);
478
479#endif // SCRIPT_ENGINE_USER_MODE
480
481#ifdef SCRIPT_ENGINE_KERNEL_MODE
482
483 if (!CheckAccessValidityAndSafety((UINT64)Lock, sizeof(LONG)))
484 {
485 *HasError = TRUE;
486 return;
487 }
488
489 SpinlockLockWithCustomWait(Lock, MaxWait);
490
491#endif // SCRIPT_ENGINE_KERNEL_MODE
492}
void SpinlockLockWithCustomWait(volatile LONG *Lock, unsigned MaximumWait)
Tries to get the lock and won't return until successfully get the lock.
Definition Spinlock.c:125

◆ ScriptEngineFunctionSpinlockUnlock()

VOID ScriptEngineFunctionSpinlockUnlock ( volatile LONG * Lock,
BOOL * HasError )

Implementation of spinlock_unlock function.

Parameters
Lock
HasError
Returns
VOID
444{
445#ifdef SCRIPT_ENGINE_USER_MODE
446
447 SpinlockUnlock(Lock);
448
449#endif // SCRIPT_ENGINE_USER_MODE
450
451#ifdef SCRIPT_ENGINE_KERNEL_MODE
452
453 if (!CheckAccessValidityAndSafety((UINT64)Lock, sizeof(LONG)))
454 {
455 *HasError = TRUE;
456 return;
457 }
458
459 SpinlockUnlock(Lock);
460
461#endif // SCRIPT_ENGINE_KERNEL_MODE
462}
void SpinlockUnlock(volatile LONG *Lock)
Release the lock.
Definition Spinlock.c:158

◆ ScriptEngineFunctionStrcmp()

UINT64 ScriptEngineFunctionStrcmp ( const char * Address1,
const char * Address2 )

Implementation of strcmp function.

Parameters
Address1
Address2
Returns
UINT64
1580{
1581 UINT64 Result = 0;
1582#ifdef SCRIPT_ENGINE_USER_MODE
1583 Result = strcmp(Address1, Address2);
1584#endif // SCRIPT_ENGINE_USER_MODE
1585
1586#ifdef SCRIPT_ENGINE_KERNEL_MODE
1587 Result = VmFuncVmxCompatibleStrcmp(Address1, Address2);
1588#endif // SCRIPT_ENGINE_KERNEL_MODE
1589
1590 return Result;
1591}
INT32 VmFuncVmxCompatibleStrcmp(const CHAR *Address1, const CHAR *Address2)
VMX-root compatible strcmp.
Definition Export.c:732

◆ ScriptEngineFunctionStrlen()

UINT64 ScriptEngineFunctionStrlen ( const char * Address)

Implementation of strlen function.

Parameters
Address
Returns
UINT64
502{
503 UINT64 Result = 0;
504#ifdef SCRIPT_ENGINE_USER_MODE
505 Result = strlen(Address);
506#endif // SCRIPT_ENGINE_USER_MODE
507
508#ifdef SCRIPT_ENGINE_KERNEL_MODE
510#endif // SCRIPT_ENGINE_KERNEL_MODE
511
512 return Result;
513}

◆ ScriptEngineFunctionStrncmp()

UINT64 ScriptEngineFunctionStrncmp ( const char * Address1,
const char * Address2,
size_t Num )

Implementation of strcmp function.

Parameters
Address1
Address2
Num
Returns
UINT64
1604{
1605 UINT64 Result = 0;
1606#ifdef SCRIPT_ENGINE_USER_MODE
1607 Result = strncmp(Address1, Address2, Num);
1608#endif // SCRIPT_ENGINE_USER_MODE
1609
1610#ifdef SCRIPT_ENGINE_KERNEL_MODE
1611 Result = VmFuncVmxCompatibleStrncmp(Address1, Address2, Num);
1612#endif // SCRIPT_ENGINE_KERNEL_MODE
1613
1614 return Result;
1615}
INT32 VmFuncVmxCompatibleStrncmp(const CHAR *Address1, const CHAR *Address2, SIZE_T Num)
VMX-root compatible strncmp.
Definition Export.c:746

◆ ScriptEngineFunctionTestStatement()

VOID ScriptEngineFunctionTestStatement ( UINT64 Tag,
BOOLEAN ImmediateMessagePassing,
UINT64 Value )

Implementation of test_statement function.

Parameters
Tag
ImmediateMessagePassing
Value
Returns
VOID
393{
394 UNREFERENCED_PARAMETER(Tag);
395 UNREFERENCED_PARAMETER(ImmediateMessagePassing);
396 UNREFERENCED_PARAMETER(Value);
397
398#ifdef SCRIPT_ENGINE_USER_MODE
399
402
403#endif // SCRIPT_ENGINE_USER_MODE
404}
BOOLEAN g_CurrentExprEvalResultHasError
global variable to detect if there was an error in the result of script-engine statement tests
Definition globals.h:671
UINT64 g_CurrentExprEvalResult
global variable to save the result of script-engine statement tests
Definition globals.h:664

◆ ScriptEngineFunctionVirtualToPhysical()

UINT64 ScriptEngineFunctionVirtualToPhysical ( UINT64 Address)
315{
316#ifdef SCRIPT_ENGINE_USER_MODE
317
318 //
319 // There is no conversion in user-mode
320 //
321 return NULL;
322#endif // SCRIPT_ENGINE_USER_MODE
323
324#ifdef SCRIPT_ENGINE_KERNEL_MODE
325
327
328#endif // SCRIPT_ENGINE_KERNEL_MODE
329}
_Use_decl_annotations_ UINT64 VirtualAddressToPhysicalAddressOnTargetProcess(PVOID VirtualAddress)
Converts Virtual Address to Physical Address based on the current process's kernel cr3.
Definition Conversion.c:258

◆ ScriptEngineFunctionWcscmp()

UINT64 ScriptEngineFunctionWcscmp ( const wchar_t * Address1,
const wchar_t * Address2 )

Implementation of wcscmp function.

Parameters
Address1
Address2
Returns
UINT64
1627{
1628 UINT64 Result = 0;
1629#ifdef SCRIPT_ENGINE_USER_MODE
1630 Result = wcscmp(Address1, Address2);
1631#endif // SCRIPT_ENGINE_USER_MODE
1632
1633#ifdef SCRIPT_ENGINE_KERNEL_MODE
1634 Result = VmFuncVmxCompatibleWcscmp(Address1, Address2);
1635#endif // SCRIPT_ENGINE_KERNEL_MODE
1636
1637 return Result;
1638}
INT32 VmFuncVmxCompatibleWcscmp(const wchar_t *Address1, const wchar_t *Address2)
VMX-root compatible wcscmp.
Definition Export.c:759

◆ ScriptEngineFunctionWcslen()

UINT64 ScriptEngineFunctionWcslen ( const wchar_t * Address)

Implementation of wcslen function.

Parameters
Address
Returns
UINT64
546{
547 UINT64 Result = 0;
548
549#ifdef SCRIPT_ENGINE_USER_MODE
550 Result = wcslen(Address);
551#endif // SCRIPT_ENGINE_USER_MODE
552
553#ifdef SCRIPT_ENGINE_KERNEL_MODE
555#endif // SCRIPT_ENGINE_KERNEL_MODE
556
557 return Result;
558}

◆ ScriptEngineFunctionWcsncmp()

UINT64 ScriptEngineFunctionWcsncmp ( const wchar_t * Address1,
const wchar_t * Address2,
size_t Num )

Implementation of wcsncmp function.

Parameters
Address1
Address2
Num
Returns
UINT64
1651{
1652 UINT64 Result = 0;
1653#ifdef SCRIPT_ENGINE_USER_MODE
1654 Result = wcsncmp(Address1, Address2, Num);
1655#endif // SCRIPT_ENGINE_USER_MODE
1656
1657#ifdef SCRIPT_ENGINE_KERNEL_MODE
1658 Result = VmFuncVmxCompatibleWcsncmp(Address1, Address2, Num);
1659#endif // SCRIPT_ENGINE_KERNEL_MODE
1660
1661 return Result;
1662}
INT32 VmFuncVmxCompatibleWcsncmp(const wchar_t *Address1, const wchar_t *Address2, SIZE_T Num)
VMX-root compatible wcsncmp.
Definition Export.c:773

◆ WcharToChar()

size_t WcharToChar ( const wchar_t * src,
char * dest,
size_t dest_len )

Convert WCHAR* to CHAR*.

Parameters
src
dest
dest_len
Returns
size_t
1069{
1070 wchar_t Code;
1071 size_t i;
1072
1073 i = 0;
1074
1075 while ((src[i] != '\0') && i < (dest_len - 1))
1076 {
1077 Code = src[i];
1078 if (Code < 128)
1079 dest[i] = (char)Code;
1080 else
1081 {
1082 dest[i] = '?';
1083 if (Code >= 0xD800 && Code <= 0xD8FF)
1084 {
1085 //
1086 // Lead surrogate, skip the next code unit, which is the trail
1087 //
1088 i++;
1089 }
1090 }
1091 i++;
1092 }
1093
1094 return i - 1;
1095}