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

Implementation of kernel debugger functions for threads. More...

#include "pch.h"

Functions

BOOLEAN ThreadHandleThreadChange (PROCESSOR_DEBUGGING_STATE *DbgState)
 handle thread changes
 
BOOLEAN ThreadSwitch (PROCESSOR_DEBUGGING_STATE *DbgState, UINT32 ThreadId, PETHREAD EThread, BOOLEAN CheckByClockInterrupt)
 make evnvironment ready to change the thread
 
BOOLEAN ThreadShowList (PDEBUGGEE_THREAD_LIST_NEEDED_DETAILS ThreadListSymbolInfo, DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_ACTIONS QueryAction, UINT32 *CountOfThreads, PVOID ListSaveBuffer, UINT64 ListSaveBuffSize)
 shows the threads list
 
BOOLEAN ThreadInterpretThread (PROCESSOR_DEBUGGING_STATE *DbgState, PDEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET TidRequest)
 change the current thread
 
VOID ThreadDetectChangeByDebugRegisterOnGs (PROCESSOR_DEBUGGING_STATE *DbgState, BOOLEAN Enable)
 Enable or disable the thread change monitoring detection on the running core based on putting a HW breakpoint on the gs:[188].
 
VOID ThreadDetectChangeByInterceptingClockInterrupts (PROCESSOR_DEBUGGING_STATE *DbgState, BOOLEAN Enable)
 Enable or disable the thread change monitoring detection on the running core based on intercepting clock interrupts.
 
VOID ThreadEnableOrDisableThreadChangeMonitor (PROCESSOR_DEBUGGING_STATE *DbgState, BOOLEAN Enable, BOOLEAN IsSwitchByClockIntrrupt)
 Enable or disable the thread change monitoring detection on the running core.
 
BOOLEAN ThreadQueryCount (PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS DebuggerUsermodeProcessOrThreadQueryRequest)
 Query thread details (count)
 
BOOLEAN ThreadQueryList (PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS DebuggerUsermodeProcessOrThreadQueryRequest, PVOID AddressToSaveDetail, UINT32 BufferSize)
 Query thread details (list)
 
BOOLEAN ThreadQueryDetails (PDEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET GetInformationThreadRequest)
 Query thread details.
 

Detailed Description

Implementation of kernel debugger functions for threads.

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.1
Date
2021-11-23

Function Documentation

◆ ThreadDetectChangeByDebugRegisterOnGs()

VOID ThreadDetectChangeByDebugRegisterOnGs ( PROCESSOR_DEBUGGING_STATE * DbgState,
BOOLEAN Enable )

Enable or disable the thread change monitoring detection on the running core based on putting a HW breakpoint on the gs:[188].

should be called on vmx root

Parameters
DbgStateThe state of the debugger on the current core
Enable
Returns
VOID
426{
427 UINT64 MsrGsBase;
428
429 if (Enable)
430 {
431 //
432 // Enable Thread Change Detection
433 // *** Read the address of GS:188 to g_CurrentThreadLocation ***
434 //
435
436 //
437 // We are in kernel, so we should read MSR GS_BASE
438 // IA32_GS_BASE 0xC0000101
439 // IA32_KERNEL_GS_BASE 0xC0000102
440 // IA32_KERNEL_GS_BASE is currently user's gs as
441 // we are in the kernel-mode, if we need to intercept
442 // from user-mode then IA32_KERNEL_GS_BASE should be used
443 // but it's not for our case
444 //
445 MsrGsBase = __readmsr(IA32_GS_BASE);
446
447 //
448 // Now, we have the gs base on MSR
449 // while in Windows gs:188 has the address
450 // of where the store current _ETHREAD, so
451 // we have to 188 to the gs base
452 //
453 MsrGsBase += 0x188;
454
455 //
456 // Set the global value for current thread of this processor
457 //
459
460 //
461 // Set interception state
462 //
464
465 //
466 // Enable load debug controls and save debug controls because we don't
467 // want dr7 and dr0 remove their configuration on vm-exits and also
468 // we'll be able to change the dr7 of the guest on VMCS
469 //
472
473 //
474 // Intercept #DBs by changing exception bitmap (one core)
475 //
477
478 //
479 // Note, this function is running as a DPC routines, means that
480 // we're currently on DISPATCH_LEVEL so after modifying debug
481 // registers and after disabling mov to dr (using vmcall),
482 // nothing is able to change debug registers so it's safe
483 //
484
485 //
486 // Set debug register to fire an exception in the case of
487 // read/write on the gs:188 as we intercept it on
488 // hypervisor side by exception bitmap on #DBs
489 // However, this call is somehow useless because I also set it
490 // on Mov 2 Debug regs handler (vm-exit), but we set from here
491 // to make sure that the vm-exit handler set this break on access
492 //
496 TRUE,
498
499 //
500 // Enables mov to debug registers exitings in primary cpu-based controls
501 // it is because I realized that some other routines in Windows like
502 // KiSaveProcessorControlState and KiRestoreProcessorControlState and
503 // other functions directly change the debug registers, probably
504 // because we should not modify debug registers directly, by the way, we
505 // are hypervisor and we can easily ignore mov to debug register (0 in
506 // this case), however we should somehow hide this process in the future
507 //
509 }
510 else
511 {
512 //
513 // Disable Thread Change Detection
514 // *** Remove side changes ***
515 //
516
517 //
518 // We should not ignore debug registers change anymore
519 //
521
522 //
523 // Disable mov to debug regs vm-exit
524 //
526
527 //
528 // Disable load debug controls and save debug controls because
529 // no longer needed
530 //
533
534 //
535 // Disable intercepting #DBs
536 //
538
539 //
540 // No longer need to store such gs:188 value
541 //
543 }
544}
#define TRUE
Definition BasicTypes.h:55
#define FALSE
Definition BasicTypes.h:54
unsigned __int64 UINT64
Definition BasicTypes.h:21
@ BREAK_ON_WRITE_ONLY
Definition DataTypes.h:71
BOOLEAN SetDebugRegisters(UINT32 DebugRegNum, DEBUG_REGISTER_TYPE ActionType, BOOLEAN ApplyToVmcs, UINT64 TargetAddress)
Configure hardware debug register for access, write and fetch breakpoints.
Definition DebugRegisters.c:37
VOID VmFuncSetSaveDebugControls(BOOLEAN Set)
Set SAVE DEBUG CONTROLS on Vm-exit controls.
Definition Export.c:134
VOID VmFuncSetMovDebugRegsExiting(UINT32 CoreId, BOOLEAN Set)
Set or unset the Mov to Debug Registers Exiting.
Definition Export.c:306
VOID VmFuncSetLoadDebugControls(BOOLEAN Set)
Set LOAD DEBUG CONTROLS on Vm-entry controls.
Definition Export.c:122
VOID VmFuncSetExceptionBitmap(UINT32 CoreId, UINT32 IdtIndex)
Set exception bitmap in VMCS.
Definition Export.c:253
VOID VmFuncUnsetExceptionBitmap(UINT32 CoreId, UINT32 IdtIndex)
Unset exception bitmap in VMCS.
Definition Export.c:267
#define DEBUGGER_DEBUG_REGISTER_FOR_THREAD_MANAGEMENT
debug register to monitor thread changes
Definition Debugger.h:26
@ EXCEPTION_VECTOR_DEBUG_BREAKPOINT
Definition Events.h:25
UINT64 CurrentThreadLocationOnGs
Definition State.h:55
BOOLEAN DebugRegisterInterceptionState
Definition State.h:56
UINT32 CoreId
Definition State.h:169
DEBUGGEE_PROCESS_OR_THREAD_TRACING_DETAILS ThreadOrProcessTracingDetails
Definition State.h:178

◆ ThreadDetectChangeByInterceptingClockInterrupts()

VOID ThreadDetectChangeByInterceptingClockInterrupts ( PROCESSOR_DEBUGGING_STATE * DbgState,
BOOLEAN Enable )

Enable or disable the thread change monitoring detection on the running core based on intercepting clock interrupts.

should be called on vmx root

Parameters
DbgStateThe state of the debugger on the current core
Enable
Returns
VOID
558{
559 if (Enable)
560 {
561 //
562 // We should get the clock interrupts
563 //
565
566 //
567 // Intercept external interrupts (for monitoring clock interrupts)
568 //
570 }
571 else
572 {
573 //
574 // We should ignore intercepting any further clock interrupts
575 //
577
578 //
579 // Undo intercepting external interrupts
580 //
582 }
583}
VOID VmFuncSetExternalInterruptExiting(UINT32 CoreId, BOOLEAN Set)
Set the External Interrupt Exiting.
Definition Export.c:280
BOOLEAN InterceptClockInterruptsForThreadChange
Definition State.h:57

◆ ThreadEnableOrDisableThreadChangeMonitor()

VOID ThreadEnableOrDisableThreadChangeMonitor ( PROCESSOR_DEBUGGING_STATE * DbgState,
BOOLEAN Enable,
BOOLEAN IsSwitchByClockIntrrupt )

Enable or disable the thread change monitoring detection on the running core.

should be called on vmx root

Parameters
DbgStateThe state of the debugger on the current core
Enable
IsSwitchByClockIntrrupt
Returns
VOID
600{
601 if (Enable)
602 {
604 DbgState->ThreadOrProcessTracingDetails.InitialSetByClockInterrupt = IsSwitchByClockIntrrupt;
605 }
606 else
607 {
608 //
609 // Avoid future sets/unsets
610 //
613 }
614
615 //
616 // Check if it's a HW breakpoint on gs:[188] or a clock interception
617 //
618 if (!IsSwitchByClockIntrrupt)
619 {
621 }
622 else
623 {
625 }
626}
VOID ThreadDetectChangeByDebugRegisterOnGs(PROCESSOR_DEBUGGING_STATE *DbgState, BOOLEAN Enable)
Enable or disable the thread change monitoring detection on the running core based on putting a HW br...
Definition Thread.c:424
VOID ThreadDetectChangeByInterceptingClockInterrupts(PROCESSOR_DEBUGGING_STATE *DbgState, BOOLEAN Enable)
Enable or disable the thread change monitoring detection on the running core based on intercepting cl...
Definition Thread.c:556
BOOLEAN InitialSetByClockInterrupt
Definition State.h:50
BOOLEAN InitialSetThreadChangeEvent
Definition State.h:48

◆ ThreadHandleThreadChange()

BOOLEAN ThreadHandleThreadChange ( PROCESSOR_DEBUGGING_STATE * DbgState)

handle thread changes

Parameters
DbgStateThe state of the debugger on the current core
Returns
BOOLEAN
23{
24 //
25 // Check if we reached to the target thread or not
26 //
27 if ((g_ThreadSwitch.ThreadId != NULL_ZERO && g_ThreadSwitch.ThreadId == HANDLE_TO_UINT32(PsGetCurrentThreadId())) ||
28 (g_ThreadSwitch.Thread != NULL64_ZERO && g_ThreadSwitch.Thread == PsGetCurrentThread()))
29 {
30 //
31 // Halt the debuggee, we have found the target thread
32 //
34
35 //
36 // Found
37 //
38 return TRUE;
39 }
40
41 //
42 // Not found
43 //
44 return FALSE;
45}
#define NULL_ZERO
Definition BasicTypes.h:51
#define NULL64_ZERO
Definition BasicTypes.h:52
@ DEBUGGEE_PAUSING_REASON_DEBUGGEE_THREAD_SWITCHED
Definition Connection.h:33
_Use_decl_annotations_ VOID KdHandleBreakpointAndDebugBreakpoints(PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGEE_PAUSING_REASON Reason, PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails)
Handle #DBs and #BPs for kernel debugger.
Definition Kd.c:1214
#define HANDLE_TO_UINT32(_var)
Definition MetaMacros.h:39
DEBUGGEE_REQUEST_TO_CHANGE_THREAD g_ThreadSwitch
Thread switch to ETHREAD or Thread ID.
Definition Global.h:73
PVOID Thread
Definition Kd.h:52
UINT32 ThreadId
Definition Kd.h:51

◆ ThreadInterpretThread()

BOOLEAN ThreadInterpretThread ( PROCESSOR_DEBUGGING_STATE * DbgState,
PDEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET TidRequest )

change the current thread

Parameters
DbgStateThe state of the debugger on the current core
TidRequest
Returns
BOOLEAN
327{
328 switch (TidRequest->ActionType)
329 {
331
332 //
333 // Debugger wants to know current tid, nt!_ETHREAD and process name, etc.
334 //
335 TidRequest->ProcessId = HANDLE_TO_UINT32(PsGetCurrentProcessId());
336 TidRequest->ThreadId = HANDLE_TO_UINT32(PsGetCurrentThreadId());
337 TidRequest->Process = (UINT64)PsGetCurrentProcess();
338 TidRequest->Thread = (UINT64)PsGetCurrentThread();
340
341 //
342 // Operation was successful
343 //
345
346 break;
347
349
350 //
351 // Perform the thread switch
352 //
353 if (!ThreadSwitch(DbgState,
354 TidRequest->ThreadId,
355 (PETHREAD)TidRequest->Thread,
356 TidRequest->CheckByClockInterrupt))
357 {
359 break;
360 }
361
362 //
363 // Operation was successful
364 //
366
367 break;
368
370
371 //
372 // Show the threads list
373 //
374 if (!ThreadShowList(&TidRequest->ThreadListSymDetails,
376 NULL,
377 NULL,
378 (UINT64)NULL))
379 {
381 break;
382 }
383
384 //
385 // Operation was successful
386 //
388
389 break;
390
391 default:
392
393 //
394 // Invalid type of action
395 //
397
398 break;
399 }
400
401 //
402 // Check if the above operation contains error
403 //
404 if (TidRequest->Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
405 {
406 return TRUE;
407 }
408 else
409 {
410 return FALSE;
411 }
412}
#define DEBUGGER_ERROR_DETAILS_OR_SWITCH_THREAD_INVALID_PARAMETER
error, for thread switch or thread details, invalid parameter
Definition ErrorCodes.h:239
#define DEBUGGER_OPERATION_WAS_SUCCESSFUL
General value to indicate that the operation or request was successful.
Definition ErrorCodes.h:23
_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafe(UINT64 VaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead)
Read memory safely by mapping the buffer (It's a wrapper)
Definition MemoryMapper.c:1101
@ DEBUGGEE_DETAILS_AND_SWITCH_THREAD_GET_THREAD_LIST
Definition RequestStructures.h:954
@ DEBUGGEE_DETAILS_AND_SWITCH_THREAD_PERFORM_SWITCH
Definition RequestStructures.h:952
@ DEBUGGEE_DETAILS_AND_SWITCH_THREAD_GET_THREAD_DETAILS
Definition RequestStructures.h:953
@ DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_ACTION_SHOW_INSTANTLY
Definition RequestStructures.h:672
BOOLEAN ThreadShowList(PDEBUGGEE_THREAD_LIST_NEEDED_DETAILS ThreadListSymbolInfo, DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_ACTIONS QueryAction, UINT32 *CountOfThreads, PVOID ListSaveBuffer, UINT64 ListSaveBuffSize)
shows the threads list
Definition Thread.c:122
BOOLEAN ThreadSwitch(PROCESSOR_DEBUGGING_STATE *DbgState, UINT32 ThreadId, PETHREAD EThread, BOOLEAN CheckByClockInterrupt)
make evnvironment ready to change the thread
Definition Thread.c:58
PCHAR CommonGetProcessNameFromProcessControlBlock(PEPROCESS Eprocess)
Get process name by eprocess.
Definition Common.c:48
DEBUGGEE_DETAILS_AND_SWITCH_THREAD_TYPE ActionType
Definition RequestStructures.h:964
UINT64 Thread
Definition RequestStructures.h:967
DEBUGGEE_THREAD_LIST_NEEDED_DETAILS ThreadListSymDetails
Definition RequestStructures.h:971
UINT64 Process
Definition RequestStructures.h:968
UINT32 ProcessId
Definition RequestStructures.h:966
UCHAR ProcessName[16]
Definition RequestStructures.h:970
UINT32 ThreadId
Definition RequestStructures.h:965
BOOLEAN CheckByClockInterrupt
Definition RequestStructures.h:969
UINT32 Result
Definition RequestStructures.h:972

◆ ThreadQueryCount()

BOOLEAN ThreadQueryCount ( PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS DebuggerUsermodeProcessOrThreadQueryRequest)

Query thread details (count)

Parameters
DebuggerUsermodeProcessOrThreadQueryRequest
Returns
BOOLEAN
637{
638 BOOLEAN Result = FALSE;
639
640 //
641 // Getting the count results
642 //
643 Result = ThreadShowList(&DebuggerUsermodeProcessOrThreadQueryRequest->ThreadListNeededDetails,
645 &DebuggerUsermodeProcessOrThreadQueryRequest->Count,
646 NULL,
647 (UINT64)NULL);
648
649 if (Result && DebuggerUsermodeProcessOrThreadQueryRequest->Count != 0)
650 {
651 DebuggerUsermodeProcessOrThreadQueryRequest->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
652 return TRUE;
653 }
654
655 DebuggerUsermodeProcessOrThreadQueryRequest->Result = DEBUGGER_ERROR_UNABLE_TO_QUERY_COUNT_OF_PROCESSES_OR_THREADS;
656 return FALSE;
657}
UCHAR BOOLEAN
Definition BasicTypes.h:39
#define DEBUGGER_ERROR_UNABLE_TO_QUERY_COUNT_OF_PROCESSES_OR_THREADS
error, unable to query count of processes or threads
Definition ErrorCodes.h:386
@ DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_ACTION_QUERY_COUNT
Definition RequestStructures.h:673
UINT32 Count
Definition RequestStructures.h:747
DEBUGGEE_THREAD_LIST_NEEDED_DETAILS ThreadListNeededDetails
Definition RequestStructures.h:744
UINT64 Result
Definition RequestStructures.h:748

◆ ThreadQueryDetails()

BOOLEAN ThreadQueryDetails ( PDEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET GetInformationThreadRequest)

Query thread details.

Parameters
GetInformationThreadRequest
Returns
BOOLEAN
696{
697 GetInformationThreadRequest->ProcessId = HANDLE_TO_UINT32(PsGetCurrentProcessId());
698 GetInformationThreadRequest->Process = (UINT64)PsGetCurrentProcess();
699 GetInformationThreadRequest->Thread = (UINT64)PsGetCurrentThread();
700 GetInformationThreadRequest->ThreadId = HANDLE_TO_UINT32(PsGetCurrentThreadId());
701
702 RtlCopyMemory(&GetInformationThreadRequest->ProcessName,
703 CommonGetProcessNameFromProcessControlBlock(PsGetCurrentProcess()),
704 15);
705
706 GetInformationThreadRequest->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
707
708 return TRUE;
709}

◆ ThreadQueryList()

BOOLEAN ThreadQueryList ( PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS DebuggerUsermodeProcessOrThreadQueryRequest,
PVOID AddressToSaveDetail,
UINT32 BufferSize )

Query thread details (list)

Parameters
DebuggerUsermodeProcessOrThreadQueryRequest
AddressToSaveDetail
BufferSize
Returns
BOOLEAN
672{
673 BOOLEAN Result = FALSE;
674
675 //
676 // Getting the list of threads
677 //
678 Result = ThreadShowList(&DebuggerUsermodeProcessOrThreadQueryRequest->ThreadListNeededDetails,
680 NULL,
681 AddressToSaveDetail,
682 BufferSize);
683
684 return Result;
685}
@ DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_ACTION_QUERY_SAVE_DETAILS
Definition RequestStructures.h:674

◆ ThreadShowList()

BOOLEAN ThreadShowList ( PDEBUGGEE_THREAD_LIST_NEEDED_DETAILS ThreadListSymbolInfo,
DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_ACTIONS QueryAction,
UINT32 * CountOfThreads,
PVOID ListSaveBuffer,
UINT64 ListSaveBuffSize )

shows the threads list

Parameters
ThreadListSymbolInfo
QueryAction
CountOfThreads
ListSaveBuffer
ListSaveBuffSize
Returns
BOOLEAN
127{
128 UINT64 ThreadListHead;
129 UINT32 EnumerationCount = 0;
130 UINT64 Thread = (UINT64)NULL;
131 LIST_ENTRY ThreadLinks = {0};
132 CLIENT_ID ThreadCid = {0};
133 UINT32 MaximumBufferCount = 0;
134 PDEBUGGEE_THREAD_LIST_DETAILS_ENTRY SavingEntries = ListSaveBuffer;
135
136 //
137 // validate parameters
138 //
140 CountOfThreads == NULL)
141 {
142 return FALSE;
143 }
144
146 (ListSaveBuffer == NULL || ListSaveBuffSize == 0))
147 {
148 return FALSE;
149 }
150
151 //
152 // compute size to avoid overflow
153 //
155 {
156 MaximumBufferCount = (UINT32)(ListSaveBuffSize / sizeof(DEBUGGEE_THREAD_LIST_DETAILS_ENTRY));
157 }
158
159 UINT32 ThreadListHeadOffset = ThreadListSymbolInfo->ThreadListHeadOffset; // nt!_EPROCESS.ThreadListHead
160 UINT32 ThreadListEntryOffset = ThreadListSymbolInfo->ThreadListEntryOffset; // nt!_ETHREAD.ThreadListEntry
161 UINT32 CidOffset = ThreadListSymbolInfo->CidOffset; // nt!_ETHREAD.Cid
162 UINT32 ActiveProcessLinksOffset = ThreadListSymbolInfo->ActiveProcessLinksOffset; // nt!_EPROCESS.ActiveProcessLinks
163 UINT64 PsActiveProcessHeadAddress = ThreadListSymbolInfo->PsActiveProcessHead; // nt!PsActiveProcessHead
164
165 //
166 // Validate params
167 //
168 if (ThreadListHeadOffset == NULL_ZERO ||
169 ThreadListEntryOffset == NULL_ZERO ||
170 CidOffset == NULL_ZERO ||
171 ActiveProcessLinksOffset == NULL_ZERO ||
172 PsActiveProcessHeadAddress == NULL64_ZERO)
173 {
174 return FALSE;
175 }
176
177 //
178 // Set the target process
179 //
180 if (ThreadListSymbolInfo->Process == NULL64_ZERO)
181 {
182 //
183 // Means that it's for the current process
184 //
185 ThreadListSymbolInfo->Process = (UINT64)PsGetCurrentProcess();
186 ThreadListHead = (UINT64)PsGetCurrentProcess() + ThreadListHeadOffset;
187 }
188 else
189 {
190 //
191 // Means that the user specified a special process
192 //
193 ThreadListHead = (UINT64)ThreadListSymbolInfo->Process + ThreadListHeadOffset;
194 }
195
196 //
197 // Check if the process's thread list head is valid or not
198 //
199 if (!CheckAccessValidityAndSafety(ThreadListHead, sizeof(BYTE)))
200 {
201 return FALSE;
202 }
203
204 //
205 // Check if the nt!_EPROCESS is valid or not (available in the system or not)
206 //
207 if (!ProcessCheckIfEprocessIsValid(ThreadListSymbolInfo->Process,
208 PsActiveProcessHeadAddress,
209 ActiveProcessLinksOffset))
210 {
211 return FALSE;
212 }
213
215 {
216 //
217 // Show the message of show the process
218 //
219 Log("PROCESS\t%llx\tIMAGE\t%s\n",
220 ThreadListSymbolInfo->Process,
221 CommonGetProcessNameFromProcessControlBlock((PEPROCESS)ThreadListSymbolInfo->Process));
222 }
223
224 //
225 // Show thread list, we read everything from the view of system process
226 //
227 MemoryMapperReadMemorySafe(ThreadListHead, &ThreadLinks, sizeof(ThreadLinks));
228
229 //
230 // Find the top of ETHREAD from nt!_ETHREAD.ThreadListEntry
231 //
232 Thread = (UINT64)ThreadLinks.Flink - ThreadListEntryOffset;
233
234 do
235 {
236 //
237 // Show thread list, we read everything from the view of system process
238 //
239 MemoryMapperReadMemorySafe(Thread + CidOffset,
240 &ThreadCid,
241 sizeof(ThreadCid));
242
243 switch (QueryAction)
244 {
246
247 //
248 // Show the list of process
249 //
250 Log("\tTHREAD\t%llx (%llx.%llx)\n", Thread, ThreadCid.UniqueProcess, ThreadCid.UniqueThread);
251
252 break;
253
255
256 EnumerationCount++;
257
258 break;
259
261
262 EnumerationCount++;
263
264 //
265 // Check to avoid overflow
266 //
267 if (EnumerationCount == MaximumBufferCount - 1)
268 {
269 //
270 // buffer is full
271 //
272 goto ReturnEnd;
273 }
274
275 //
276 // Save the details
277 //
278 SavingEntries[EnumerationCount - 1].Eprocess = ThreadListSymbolInfo->Process;
279 SavingEntries[EnumerationCount - 1].ProcessId = HANDLE_TO_UINT32(ThreadCid.UniqueProcess);
280 SavingEntries[EnumerationCount - 1].ThreadId = HANDLE_TO_UINT32(ThreadCid.UniqueThread);
281 SavingEntries[EnumerationCount - 1].Ethread = Thread;
282
283 RtlCopyMemory(&SavingEntries[EnumerationCount - 1].ImageFileName,
284 CommonGetProcessNameFromProcessControlBlock((PEPROCESS)ThreadListSymbolInfo->Process),
285 15);
286
287 break;
288
289 default:
290 break;
291 }
292
293 MemoryMapperReadMemorySafe(Thread + ThreadListEntryOffset,
294 &ThreadLinks,
295 sizeof(ThreadLinks));
296
297 //
298 // Find the next process from the list of this process
299 //
300 Thread = (UINT64)ThreadLinks.Flink - ThreadListEntryOffset;
301
302 } while ((UINT64)ThreadLinks.Flink != ThreadListHead);
303
304ReturnEnd:
305 //
306 // In case of query count of Threads, we'll set this parameter
307 //
309 {
310 *CountOfThreads = EnumerationCount;
311 }
312
313 return TRUE;
314}
BOOLEAN CheckAccessValidityAndSafety(UINT64 TargetAddress, UINT32 Size)
Check the safety to access the memory.
Definition AddressCheck.c:156
unsigned char BYTE
Definition BasicTypes.h:24
unsigned int UINT32
Definition BasicTypes.h:48
#define Log(format,...)
Log without any prefix.
Definition HyperDbgHyperLogIntrinsics.h:129
BOOLEAN ProcessCheckIfEprocessIsValid(UINT64 Eprocess, UINT64 ActiveProcessHead, ULONG ActiveProcessLinksOffset)
checks whether the given nt!_EPROCESS is valid or not
Definition Process.c:264
The structure showing list of threads (details of each entry)
Definition RequestStructures.h:728
UINT64 Ethread
Definition RequestStructures.h:730
UINT32 ThreadId
Definition RequestStructures.h:732
UINT64 Eprocess
Definition RequestStructures.h:729
UINT32 ProcessId
Definition RequestStructures.h:731
UINT32 ThreadListHeadOffset
Definition RequestStructures.h:699
UINT32 CidOffset
Definition RequestStructures.h:701
UINT32 ThreadListEntryOffset
Definition RequestStructures.h:700
UINT64 PsActiveProcessHead
Definition RequestStructures.h:702
UINT64 Process
Definition RequestStructures.h:704
ULONG ActiveProcessLinksOffset
Definition RequestStructures.h:703

◆ ThreadSwitch()

BOOLEAN ThreadSwitch ( PROCESSOR_DEBUGGING_STATE * DbgState,
UINT32 ThreadId,
PETHREAD EThread,
BOOLEAN CheckByClockInterrupt )

make evnvironment ready to change the thread

Parameters
DbgStateThe state of the debugger on the current core
ThreadId
EThread
CheckByClockInterrupt
Returns
BOOLEAN
62{
63 //
64 // Initialized with NULL
65 //
68
69 //
70 // Check to avoid invalid switch
71 //
72 if (ThreadId == NULL_ZERO && EThread == NULL64_ZERO)
73 {
74 return FALSE;
75 }
76
77 //
78 // Set the target thread id, ethread to switch
79 //
80 if (EThread != NULL)
81 {
82 if (CheckAccessValidityAndSafety((UINT64)EThread, sizeof(BYTE)))
83 {
84 g_ThreadSwitch.Thread = EThread;
85 }
86 else
87 {
88 //
89 // An invalid address is specified by user
90 //
91 return FALSE;
92 }
93 }
94 else if (ThreadId != NULL_ZERO)
95 {
96 g_ThreadSwitch.ThreadId = ThreadId;
97 }
98
99 //
100 // Send request for the target task to the halted cores (synchronized)
101 //
104 TRUE,
105 TRUE,
106 (PVOID)CheckByClockInterrupt);
107
108 return TRUE;
109}
BOOLEAN HaltedCoreBroadcastTaskAllCores(PROCESSOR_DEBUGGING_STATE *DbgState, UINT64 TargetTask, BOOLEAN LockAgainAfterTask, BOOLEAN Synchronize, PVOID Context)
Broadcast tasks to halted cores.
Definition HaltedCore.c:399
#define DEBUGGER_HALTED_CORE_TASK_SET_THREAD_INTERCEPTION
Halted core task for setting thread interception.
Definition HaltedCore.h:40