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

Implementation of the functions related to the callback for Syscall. More...

#include "pch.h"

Functions

BOOLEAN SyscallCallbackInitialize ()
 Initialize the syscall callback.
BOOLEAN SyscallCallbackIsInitialized ()
 Check whether the syscall callback is initialized.
BOOLEAN SyscallCallbackUninitialize ()
 Uninitialize the syscall callback.
BOOLEAN SyscallCallbackStoreProcessInformation (UINT32 ProcessId, UINT32 ThreadId, UINT64 Context, SYSCALL_CALLBACK_CONTEXT_PARAMS *Params)
 This function makes sure to unset the RFLAGS.TF on next trigger of #DB on the target process/thread.
BOOLEAN SyscallCallbackSetTrapFlagAfterSyscall (GUEST_REGS *Regs, UINT32 ProcessId, UINT32 ThreadId, UINT64 Context, SYSCALL_CALLBACK_CONTEXT_PARAMS *Params)
 Set the trap flag in the guest after a syscall.
BOOLEAN SyscallCallbackCheckAndHandleAfterSyscallTrapFlags (VIRTUAL_MACHINE_STATE *VCpu, UINT32 ProcessId, UINT32 ThreadId)
 Handle the trap flags as the result of interception of the return of the system-call.
VOID SyscallCallbackHandleSystemCallHook (VIRTUAL_MACHINE_STATE *VCpu)
 Handle the system call hook callback.

Detailed Description

Implementation of the functions related to the callback for Syscall.

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
jtaw5649
Version
0.14
Date
2025-06-07

Function Documentation

◆ SyscallCallbackCheckAndHandleAfterSyscallTrapFlags()

BOOLEAN SyscallCallbackCheckAndHandleAfterSyscallTrapFlags ( VIRTUAL_MACHINE_STATE * VCpu,
UINT32 ProcessId,
UINT32 ThreadId )

Handle the trap flags as the result of interception of the return of the system-call.

Parameters
VCpuThe virtual processor's state
ProcessIdThe process id of the thread
ThreadIdThe thread id of the thread
Returns
BOOLEAN
288{
289 RFLAGS Rflags = {0};
290 UINT32 Index;
291 UINT64 Context = NULL64_ZERO;
294 BOOLEAN Result;
295 BOOLEAN ResultToReturn;
296
297 //
298 // Read the trap flag
299 //
300 Rflags.AsUInt = HvGetRflags();
301
302 if (!Rflags.TrapFlag)
303 {
304 //
305 // The trap flag is not set, so we don't need to do anything
306 //
307 return FALSE;
308 }
309
310 //
311 // Form the process id and thread id into a 64-bit value
312 //
313 ProcThrdInfo.Fields.ProcessId = ProcessId;
314 ProcThrdInfo.Fields.ThreadId = ThreadId;
315
316 //
317 // Make sure, nobody is in the middle of modifying the list
318 //
320
321 //
322 // *** Search the list of processes/threads for the current process's trap flag state ***
323 //
324 Result = BinarySearchPerformSearchItem((UINT64 *)&g_SyscallCallbackTrapFlagState->ThreadInformation[0],
325 g_SyscallCallbackTrapFlagState->NumberOfItems,
326 &Index,
327 ProcThrdInfo.asUInt);
328
329 //
330 // Check whether this thread is expected to have trap flag
331 // by the syscall callback or not
332 //
333 if (Result)
334 {
335 //
336 // Read the context of the caller
337 //
338 Context = g_SyscallCallbackTrapFlagState->Context[Index];
339
340 //
341 // Read the (optional) parameters of the caller
342 //
343 memcpy(&Params, &g_SyscallCallbackTrapFlagState->Params[Index], sizeof(SYSCALL_CALLBACK_CONTEXT_PARAMS));
344
345 //
346 // Clear the trap flag from the RFLAGS register
347 //
349
350 //
351 // Remove the thread/process from the list of processes/threads
352 //
353 InsertionSortDeleteItem((UINT64 *)&g_SyscallCallbackTrapFlagState->ThreadInformation[0],
354 &g_SyscallCallbackTrapFlagState->NumberOfItems,
355 Index);
356
357 //
358 // Handled by the syscall callback
359 //
360 ResultToReturn = TRUE;
361
362 goto ReturnResult;
363 }
364 else
365 {
366 //
367 // Not related to the syscall callback
368 //
369 ResultToReturn = FALSE;
370
371 goto ReturnResult;
372 }
373
374ReturnResult:
375
376 //
377 // Unlock the list modification lock
378 //
380
381 //
382 // Call the callback function to handle the trap flag if its needed
383 // Note that we call it here so we already unlocked the list lock
384 // to optimize the performance (avoid holding the lock for a long time)
385 //
386 if (ResultToReturn)
387 {
388 TransparentCallbackHandleAfterSyscall(VCpu->Regs, ProcessId, ThreadId, Context, &Params);
389 }
390
391 return ResultToReturn;
392}
BOOLEAN BinarySearchPerformSearchItem(UINT64 ArrayPtr[], UINT32 NumberOfItems, UINT32 *ResultIndex, UINT64 Key)
A utility function to perform the binary search.
Definition BinarySearch.c:46
UINT64 HvGetRflags()
Read guest's RFLAGS.
Definition Hv.c:1197
VOID HvSetRflagTrapFlag(BOOLEAN Set)
Set the rflag's trap flag.
Definition Hv.c:377
BOOLEAN InsertionSortDeleteItem(UINT64 ArrayPtr[], UINT32 *NumberOfItems, UINT32 Index)
Function to implement insertion sort.
Definition InsertionSort.c:69
VOID SpinlockLock(volatile LONG *Lock)
Tries to get the lock and won't return until successfully get the lock.
Definition Spinlock.c:53
VOID SpinlockUnlock(volatile LONG *Lock)
Release the lock.
Definition Spinlock.c:162
volatile LONG SyscallCallbackModeTrapListLock
The lock for modifying list of process/thread for syscall callback trap flags.
Definition SyscallCallback.h:24
struct _SYSCALL_CALLBACK_PROCESS_THREAD_INFORMATION SYSCALL_CALLBACK_PROCESS_THREAD_INFORMATION
The thread/process information.
UCHAR BOOLEAN
Definition BasicTypes.h:35
#define NULL64_ZERO
Definition BasicTypes.h:111
#define TRUE
Definition BasicTypes.h:114
#define FALSE
Definition BasicTypes.h:113
unsigned int UINT32
Definition BasicTypes.h:54
struct _SYSCALL_CALLBACK_CONTEXT_PARAMS SYSCALL_CALLBACK_CONTEXT_PARAMS
The (optional) context parameters for the transparent-mode.
IMPORT_EXPORT_HYPEREVADE VOID TransparentCallbackHandleAfterSyscall(GUEST_REGS *Regs, UINT32 ProcessId, UINT32 ThreadId, UINT64 Context, SYSCALL_CALLBACK_CONTEXT_PARAMS *Params)
Callback function to handle returns from the syscall.
Definition SyscallFootprints.c:1768
SYSCALL_CALLBACK_TRAP_FLAG_STATE * g_SyscallCallbackTrapFlagState
State of syscall callback trap flags.
Definition GlobalVariables.h:112
UINT32 ProcessId
Definition SyscallCallback.h:53
struct _SYSCALL_CALLBACK_PROCESS_THREAD_INFORMATION::@244024325212031003046334246141250140302062174051::@007354050331305204056110162336245215053072211114 Fields
UINT64 asUInt
Definition SyscallCallback.h:49
UINT32 ThreadId
Definition SyscallCallback.h:54
GUEST_REGS * Regs
Definition State.h:326

◆ SyscallCallbackHandleSystemCallHook()

VOID SyscallCallbackHandleSystemCallHook ( VIRTUAL_MACHINE_STATE * VCpu)

Handle the system call hook callback.

Parameters
VCpuThe virtual processor's state
Returns
VOID
403{
405}
IMPORT_EXPORT_HYPEREVADE VOID TransparentHandleSystemCallHook(GUEST_REGS *Regs)
Handle The triggered hook on KiSystemCall64 system call handler when the Transparency mode is enabled...
Definition SyscallFootprints.c:65

◆ SyscallCallbackInitialize()

BOOLEAN SyscallCallbackInitialize ( )

Initialize the syscall callback.

Returns
BOOLEAN
23{
24 MSR Msr = {0};
25
26 //
27 // Check whether the syscall callback was already initialized or not
28 //
30 {
31 //
32 // Insert EPT memory page hook for Windows system call handler, KiSystemCall64()
33 //
34 Msr.Flags = CpuReadMsr(IA32_LSTAR);
35
36 //
37 // We set the hook at the address of the system call handler + 3
38 // because we don't want to hook the first 3 bytes of the system call handler
39 // which is SWAPGS instruction
40 //
42
43 //
44 // Apply the hook from vmx non-root mode
45 //
46 if (!ConfigureEptHook(g_SystemCallHookAddress, (UINT32)(ULONG_PTR)PsGetCurrentProcessId()))
47 {
48 // LogInfo("Error while inserting EPT page hook for Windows system call handler at address 0x%p+3", Msr.Flags);
49
50 return FALSE;
51 }
52
53 //
54 // Allocate buffer for the syscall callback trap flag state
55 //
57
58 //
59 // Intercept trap flags #DBs and #BPs for the syscall callback
60 //
62
63 //
64 // Enable the syscall callback
65 //
67
68 //
69 // Successfully enabled the syscall callback
70 //
71 return TRUE;
72 }
73 else
74 {
75 return FALSE;
76 }
77}
union _MSR MSR
General MSR Structure.
UINT64 CpuReadMsr(ULONG MsrAddress)
Read an MSR.
Definition PlatformIntrinsics.c:213
PVOID PlatformMemAllocateZeroedNonPagedPool(SIZE_T NumberOfBytes)
Allocates zeroed non-paged pool memory.
Definition PlatformMem.c:248
struct _SYSCALL_CALLBACK_TRAP_FLAG_STATE SYSCALL_CALLBACK_TRAP_FLAG_STATE
The threads that we expect to get the trap flag.
void * PVOID
Definition BasicTypes.h:56
IMPORT_EXPORT_VMM VOID BroadcastEnableDbAndBpExitingAllCores()
routines to set vm-exit on all DBs and BP on all cores
Definition Broadcast.c:35
IMPORT_EXPORT_VMM BOOLEAN ConfigureEptHook(PVOID TargetAddress, UINT32 ProcessId)
This function invokes a VMCALL to set the hook and broadcast the exiting for the breakpoints on excep...
Definition Configuration.c:263
BOOLEAN g_SyscallCallbackStatus
Shows whether the syscall callback is enabled or not.
Definition GlobalVariables.h:118
PVOID g_SystemCallHookAddress
Target hook address for the system call handler.
Definition GlobalVariables.h:124
UINT64 Flags
Definition Msr.h:42

◆ SyscallCallbackIsInitialized()

BOOLEAN SyscallCallbackIsInitialized ( )

Check whether the syscall callback is initialized.

Returns
BOOLEAN
86{
88}

◆ SyscallCallbackSetTrapFlagAfterSyscall()

BOOLEAN SyscallCallbackSetTrapFlagAfterSyscall ( GUEST_REGS * Regs,
UINT32 ProcessId,
UINT32 ThreadId,
UINT64 Context,
SYSCALL_CALLBACK_CONTEXT_PARAMS * Params )

Set the trap flag in the guest after a syscall.

Parameters
RegsThe virtual processor's state of registers
ProcessIdThe process id of the thread
ThreadIdThe thread id of the thread
ContextThe context of the caller
ParamsThe (optional) parameters of the caller
Returns
BOOLEAN
231{
232 //
233 // Do not add anything to the list if the syscall callback is not enabled (or disabled by the user)
234 //
236 {
237 //
238 // syscall callback is not enabled
239 //
240 return FALSE;
241 }
242
243 //
244 // Insert the thread/process into the list of processes/threads
245 //
246 if (!SyscallCallbackStoreProcessInformation(ProcessId, ThreadId, Context, Params))
247 {
248 //
249 // Failed to store the process/thread information
250 //
251 return FALSE;
252 }
253
254 //
255 // *** Successfully stored the process/thread information ***
256 //
257
258 //
259 // Set the trap flag to TRUE because we want to intercept the thread again
260 // once it returns to the user-mode (SYSRET) instruction
261 //
262 // Here the RFLAGS is in the R11 register (See Intel manual about the SYSCALL register)
263 //
264 Regs->r11 |= X86_FLAGS_TF;
265
266 //
267 // Create log message for the syscall
268 //
269 // LogInfo("Syscall callback set trap flag for process: %x, thread: %x\n", ProcessId, ThreadId);
270
271 return TRUE;
272}
BOOLEAN SyscallCallbackStoreProcessInformation(UINT32 ProcessId, UINT32 ThreadId, UINT64 Context, SYSCALL_CALLBACK_CONTEXT_PARAMS *Params)
This function makes sure to unset the RFLAGS.TF on next trigger of DB on the target process/thread.
Definition SyscallCallback.c:143
#define X86_FLAGS_TF
Definition Constants.h:531
UINT64 r11
Definition BasicTypes.h:152

◆ SyscallCallbackStoreProcessInformation()

BOOLEAN SyscallCallbackStoreProcessInformation ( UINT32 ProcessId,
UINT32 ThreadId,
UINT64 Context,
SYSCALL_CALLBACK_CONTEXT_PARAMS * Params )

This function makes sure to unset the RFLAGS.TF on next trigger of #DB on the target process/thread.

Parameters
ProcessId
ThreadId
Context
Params
Returns
BOOLEAN
147{
148 UINT32 Index;
149 BOOLEAN Result;
150 BOOLEAN SuccessfullyStored;
152
153 //
154 // Form the process id and thread id into a 64-bit value
155 //
156 ProcThrdInfo.Fields.ProcessId = ProcessId;
157 ProcThrdInfo.Fields.ThreadId = ThreadId;
158
159 //
160 // Make sure, nobody is in the middle of modifying the list
161 //
163
164 //
165 // *** Search the list of processes/threads for the current process's trap flag state ***
166 //
167 Result = BinarySearchPerformSearchItem((UINT64 *)&g_SyscallCallbackTrapFlagState->ThreadInformation[0],
168 g_SyscallCallbackTrapFlagState->NumberOfItems,
169 &Index,
170 ProcThrdInfo.asUInt);
171
172 if (Result)
173 {
174 //
175 // It means that we already find this entry in the stored list
176 // so, just imply that the addition was successful (no need for extra addition)
177 //
178 SuccessfullyStored = TRUE;
179 goto Return;
180 }
181 else
182 {
183 //
184 // Insert the thread into the list as the item is not already present
185 //
186 SuccessfullyStored = InsertionSortInsertItem((UINT64 *)&g_SyscallCallbackTrapFlagState->ThreadInformation[0],
187 &g_SyscallCallbackTrapFlagState->NumberOfItems,
189 &Index,
190 ProcThrdInfo.asUInt);
191
192 if (SuccessfullyStored)
193 {
194 //
195 // Successfully inserted the thread/process into the list
196 // Now let's store the context of the caller along with parameters
197 //
198 g_SyscallCallbackTrapFlagState->Context[Index] = Context;
199 memcpy(&g_SyscallCallbackTrapFlagState->Params[Index], Params, sizeof(SYSCALL_CALLBACK_CONTEXT_PARAMS));
200 }
201
202 goto Return;
203 }
204
205Return:
206 //
207 // Unlock the list modification lock
208 //
210
211 return SuccessfullyStored;
212}
BOOLEAN InsertionSortInsertItem(UINT64 ArrayPtr[], UINT32 *NumberOfItems, UINT32 MaxNumOfItems, UINT32 *Index, UINT64 Key)
Function to implement insertion sort.
Definition InsertionSort.c:26
#define MAXIMUM_NUMBER_OF_THREAD_INFORMATION_FOR_SYSCALL_CALLBACK_TRAPS
maximum number of thread/process ids to be allocated for keeping track of of the trap flag
Definition SyscallCallback.h:35

◆ SyscallCallbackUninitialize()

BOOLEAN SyscallCallbackUninitialize ( )

Uninitialize the syscall callback.

Returns
BOOLEAN
97{
99 {
100 //
101 // Unset the EPT hook from the syscall entry before disabling state.
102 //
103 if (!ConfigureEptHookUnHookSingleAddress((UINT64)g_SystemCallHookAddress, (UINT64)NULL, (UINT32)(ULONG_PTR)PsGetCurrentProcessId()))
104 {
105 LogInfo("Error while removing the EPT hook from windows syscall handler at address 0x%p", g_SystemCallHookAddress);
106
107 return FALSE;
108 }
109
110 //
111 // Unset the trap flags #DBs and #BPs for the syscall callback
112 //
114
115 //
116 // Free the buffer for the syscall callback trap flag state
117 //
119
123
124 return TRUE;
125 }
126 else
127 {
128 return FALSE;
129 }
130}
PVOID PlatformMemFreePool(PVOID BufferAddress)
Frees a memory pool.
Definition PlatformMem.c:269
#define LogInfo(format,...)
Define log variables.
Definition HyperDbgHyperLogIntrinsics.h:71
IMPORT_EXPORT_VMM VOID BroadcastDisableDbAndBpExitingAllCores()
routines to unset vm-exit on all DBs and BP on all cores
Definition Broadcast.c:49
IMPORT_EXPORT_VMM BOOLEAN ConfigureEptHookUnHookSingleAddress(UINT64 VirtualAddress, UINT64 PhysAddress, UINT32 ProcessId)
Remove single hook from the hooked pages list and invalidate TLB.
Definition Configuration.c:190
NULL()
Definition test-case-generator.py:530