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

User debugger's thread holder. More...

#include "pch.h"

Functions

VOID ThreadHolderAllocateThreadHoldingBuffers ()
 Pre allocate buffer for thread holder.
 
BOOLEAN ThreadHolderAssignThreadHolderToProcessDebuggingDetails (PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail)
 Assign a thread holder to process debugging details.
 
BOOLEAN ThreadHolderIsAnyPausedThreadInProcess (PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail)
 Check if there is any thread paused by checking process debugging details.
 
PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadHolderGetProcessThreadDetailsByProcessIdAndThreadId (UINT32 ProcessId, UINT32 ThreadId)
 Find the active threads of the process from process id.
 
PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadHolderGetProcessFirstThreadDetailsByProcessId (UINT32 ProcessId)
 Find the first active threads of the process from process id.
 
PUSERMODE_DEBUGGING_PROCESS_DETAILS ThreadHolderGetProcessDebuggingDetailsByThreadId (UINT32 ThreadId)
 Find the active process debugging detail from the thread id.
 
PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadHolderFindOrCreateThreadDebuggingDetail (UINT32 ThreadId, PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail)
 Find or create user-mode debugging details for threads.
 
BOOLEAN ThreadHolderApplyActionToPausedThreads (PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetails, PDEBUGGER_UD_COMMAND_PACKET ActionRequest)
 Apply the action of the user debugger to a specific thread or all threads.
 
VOID ThreadHolderFreeHoldingStructures (PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail)
 Free all of thread holder structures.
 
UINT32 ThreadHolderQueryCountOfActiveDebuggingThreadsAndProcesses ()
 Query count of active debugging threads and processes.
 
VOID ThreadHolderQueryDetailsOfActiveDebuggingThreadsAndProcesses (USERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS *BufferToStoreDetails, UINT32 MaxCount)
 Query details of active debugging threads and processes.
 

Detailed Description

User debugger's thread holder.

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.1
Date
2022-01-28

Function Documentation

◆ ThreadHolderAllocateThreadHoldingBuffers()

VOID ThreadHolderAllocateThreadHoldingBuffers ( )

Pre allocate buffer for thread holder.

Returns
VOID
22{
23 //
24 // Request to allocate two buffer for holder of threads
25 //
27
28 //
29 // As it might be called from an attaching request and never find a
30 // a chance to allocate it, we allocate it here as it's safe at PASSIVE_LEVEL
31 //
33}
@ PROCESS_THREAD_HOLDER
Definition DataTypes.h:46
BOOLEAN PoolManagerCheckAndPerformAllocationAndDeallocation()
This function performs allocations from VMX non-root based on g_RequestNewAllocation.
Definition PoolManager.c:302
BOOLEAN PoolManagerRequestAllocation(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention)
Request to allocate new buffers.
Definition PoolManager.c:415
The holder for detail of each thread in process.
Definition ThreadHolder.h:46

◆ ThreadHolderApplyActionToPausedThreads()

BOOLEAN ThreadHolderApplyActionToPausedThreads ( PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetails,
PDEBUGGER_UD_COMMAND_PACKET ActionRequest )

Apply the action of the user debugger to a specific thread or all threads.

Parameters
ProcessDebuggingDetails
ActionRequest
Returns
BOOLEAN Shows whether the command is applied or not
366{
367 PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetails;
368 BOOLEAN CommandApplied = FALSE;
369
370 if (!ActionRequest->ApplyToAllPausedThreads)
371 {
372 //
373 // *** only the active thread ***
374 //
375
376 ThreadDebuggingDetails = ThreadHolderGetProcessThreadDetailsByProcessIdAndThreadId(ProcessDebuggingDetails->ProcessId,
377 ActionRequest->TargetThreadId);
378
379 //
380 // Apply the command
381 //
382 for (size_t i = 0; i < MAX_USER_ACTIONS_FOR_THREADS; i++)
383 {
384 if (ThreadDebuggingDetails->UdAction[i].ActionType == DEBUGGER_UD_COMMAND_ACTION_TYPE_NONE)
385 {
386 //
387 // Set the action
388 //
389 ThreadDebuggingDetails->UdAction[i].OptionalParam1 = ActionRequest->UdAction.OptionalParam1;
390 ThreadDebuggingDetails->UdAction[i].OptionalParam2 = ActionRequest->UdAction.OptionalParam2;
391 ThreadDebuggingDetails->UdAction[i].OptionalParam3 = ActionRequest->UdAction.OptionalParam3;
392 ThreadDebuggingDetails->UdAction[i].OptionalParam4 = ActionRequest->UdAction.OptionalParam4;
393
394 //
395 // At last we set the action type to make it valid
396 //
397 ThreadDebuggingDetails->UdAction[i].ActionType = ActionRequest->UdAction.ActionType;
398
399 //
400 // Command is applied
401 //
402 return TRUE;
403 }
404 }
405 }
406 else
407 {
408 //
409 // *** apply to all paused threads ***
410 //
411 PLIST_ENTRY TempList = 0;
412
413 TempList = &ProcessDebuggingDetails->ThreadsListHead;
414
415 while (&ProcessDebuggingDetails->ThreadsListHead != TempList->Flink)
416 {
417 TempList = TempList->Flink;
419 CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
420
421 for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
422 {
423 if (ThreadHolder->Threads[i].ThreadId != NULL_ZERO &&
424 ThreadHolder->Threads[i].IsPaused)
425 {
426 for (size_t j = 0; j < MAX_USER_ACTIONS_FOR_THREADS; j++)
427 {
429 {
430 //
431 // Set the action
432 //
433 ThreadHolder->Threads[i].UdAction[j].OptionalParam1 = ActionRequest->UdAction.OptionalParam1;
434 ThreadHolder->Threads[i].UdAction[j].OptionalParam2 = ActionRequest->UdAction.OptionalParam2;
435 ThreadHolder->Threads[i].UdAction[j].OptionalParam3 = ActionRequest->UdAction.OptionalParam3;
436 ThreadHolder->Threads[i].UdAction[j].OptionalParam4 = ActionRequest->UdAction.OptionalParam4;
437
438 //
439 // At last we set the action type to make it valid
440 //
441 ThreadHolder->Threads[i].UdAction[j].ActionType = ActionRequest->UdAction.ActionType;
442
443 CommandApplied = TRUE;
444 break;
445 }
446 }
447 }
448 }
449 }
450 }
451
452 //
453 // Return the result of applying the command
454 //
455 return CommandApplied;
456}
#define MAX_THREADS_IN_A_PROCESS_HOLDER
Maximum threads that a process thread holder might have.
Definition Attaching.h:28
#define MAX_USER_ACTIONS_FOR_THREADS
Maximum actions in paused threads storage.
Definition Attaching.h:22
UCHAR BOOLEAN
Definition BasicTypes.h:39
#define NULL_ZERO
Definition BasicTypes.h:51
#define TRUE
Definition BasicTypes.h:55
#define FALSE
Definition BasicTypes.h:54
@ DEBUGGER_UD_COMMAND_ACTION_TYPE_NONE
Definition RequestStructures.h:867
PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadHolderGetProcessThreadDetailsByProcessIdAndThreadId(UINT32 ProcessId, UINT32 ThreadId)
Find the active threads of the process from process id.
Definition ThreadHolder.c:109
DEBUGGER_UD_COMMAND_ACTION_TYPE ActionType
Definition RequestStructures.h:880
UINT64 OptionalParam1
Definition RequestStructures.h:881
UINT64 OptionalParam3
Definition RequestStructures.h:883
UINT64 OptionalParam4
Definition RequestStructures.h:884
UINT64 OptionalParam2
Definition RequestStructures.h:882
DEBUGGER_UD_COMMAND_ACTION UdAction
Definition RequestStructures.h:894
UINT32 TargetThreadId
Definition RequestStructures.h:896
BOOLEAN ApplyToAllPausedThreads
Definition RequestStructures.h:897
LIST_ENTRY ThreadsListHead
Definition Attaching.h:67
UINT32 ProcessId
Definition Attaching.h:61
Details of each thread in process.
Definition ThreadHolder.h:33
UINT32 ThreadId
Definition ThreadHolder.h:34
DEBUGGER_UD_COMMAND_ACTION UdAction[MAX_USER_ACTIONS_FOR_THREADS]
Definition ThreadHolder.h:37
BOOLEAN IsPaused
Definition ThreadHolder.h:36
USERMODE_DEBUGGING_THREAD_DETAILS Threads[MAX_THREADS_IN_A_PROCESS_HOLDER]
Definition ThreadHolder.h:48

◆ ThreadHolderAssignThreadHolderToProcessDebuggingDetails()

BOOLEAN ThreadHolderAssignThreadHolderToProcessDebuggingDetails ( PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail)

Assign a thread holder to process debugging details.

Parameters
ProcessDebuggingDetail
Returns
BOOLEAN
43{
45
46 //
47 // Initialize the list entry of threads
48 //
49 InitializeListHead(&ProcessDebuggingDetail->ThreadsListHead);
50
51 //
52 // Add a thread holder here
53 //
54 ThreadHolder = (USERMODE_DEBUGGING_THREAD_HOLDER *)
56
57 if (!ThreadHolder)
58 {
59 return FALSE;
60 }
61
62 //
63 // Add it to thread holder of the structure
64 //
65 InsertHeadList(&ProcessDebuggingDetail->ThreadsListHead, &(ThreadHolder->ThreadHolderList));
66
67 return TRUE;
68}
UINT64 PoolManagerRequestPool(POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPool, UINT32 Size)
This function should be called from vmx-root in order to get a pool from the list.
Definition PoolManager.c:212
FORCEINLINE VOID InitializeListHead(_Out_ PLIST_ENTRY ListHead)
Definition Windows.h:41
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ PLIST_ENTRY Entry)
Definition Windows.h:115
LIST_ENTRY ThreadHolderList
Definition ThreadHolder.h:47

◆ ThreadHolderFindOrCreateThreadDebuggingDetail()

PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadHolderFindOrCreateThreadDebuggingDetail ( UINT32 ThreadId,
PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail )

Find or create user-mode debugging details for threads.

Parameters
ThreadId
ProcessDebuggingDetail
Returns
PUSERMODE_DEBUGGING_THREAD_DETAILS
258{
259 PLIST_ENTRY TempList = 0;
260
261 TempList = &ProcessDebuggingDetail->ThreadsListHead;
262
263 //
264 // Let's see if we can find the thread
265 //
266 while (&ProcessDebuggingDetail->ThreadsListHead != TempList->Flink)
267 {
268 TempList = TempList->Flink;
270 CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
271
272 for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
273 {
274 if (ThreadHolder->Threads[i].ThreadId == ThreadId)
275 {
276 //
277 // We find a thread, let's return it's structure
278 //
279 return &ThreadHolder->Threads[i];
280 }
281 }
282 }
283
284 //
285 // *** We're here, the thread is not found, let's create an entry for it ***
286 //
287
288 //
289 // Two threads should not simultaneously reach here
290 //
292
293 TempList = &ProcessDebuggingDetail->ThreadsListHead;
294
295 //
296 // Let's see if we can find the thread
297 //
298 while (&ProcessDebuggingDetail->ThreadsListHead != TempList->Flink)
299 {
300 TempList = TempList->Flink;
302 CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
303
304 for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
305 {
306 if (ThreadHolder->Threads[i].ThreadId == NULL_ZERO)
307 {
308 //
309 // We find a null thread place, let's return it's structure
310 //
311 ThreadHolder->Threads[i].ThreadId = ThreadId;
312
314 return &ThreadHolder->Threads[i];
315 }
316 }
317 }
318
319 //
320 // We didn't find an empty entry,
321 // let's use another structure and link it to the thread holder
322 //
325
326 if (NewThreadHolder == NULL)
327 {
328 LogError("Err, enable to find a place to save the threads data, "
329 "please use 'prealloc' command to allocate more pre-allocated "
330 "buffer for the thread holder");
331
333 return NULL;
334 }
335
336 //
337 // Add the current thread as the first entry of the holder
338 //
339 NewThreadHolder->Threads[0].ThreadId = ThreadId;
340
341 //
342 // Link to the thread holding structure
343 //
344 InsertHeadList(&ProcessDebuggingDetail->ThreadsListHead, &(NewThreadHolder->ThreadHolderList));
345
346 //
347 // Other threads are now allowed to use the thread listing mechanism
348 //
350
351 return &NewThreadHolder->Threads[0];
352}
#define LogError(format,...)
Log in the case of error.
Definition HyperDbgHyperLogIntrinsics.h:113
void SpinlockLock(volatile LONG *Lock)
Tries to get the lock and won't return until successfully get the lock.
Definition Spinlock.c:52
void SpinlockUnlock(volatile LONG *Lock)
Release the lock.
Definition Spinlock.c:158
volatile LONG VmxRootThreadHoldingLock
Vmx-root lock for thread holding.
Definition ThreadHolder.h:22
NULL()
Definition test-case-generator.py:530

◆ ThreadHolderFreeHoldingStructures()

VOID ThreadHolderFreeHoldingStructures ( PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail)

Free all of thread holder structures.

Parameters
ProcessDebuggingDetail
Returns
VOID
466{
467 PLIST_ENTRY TempList = 0;
468
469 TempList = &ProcessDebuggingDetail->ThreadsListHead;
470
471 while (&ProcessDebuggingDetail->ThreadsListHead != TempList->Flink)
472 {
473 TempList = TempList->Flink;
475 CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
476
477 //
478 // The thread is allocated from the pool management, so we'll
479 // free it from there
480 //
481 PoolManagerFreePool((UINT64)ThreadHolder);
482 }
483}
unsigned __int64 UINT64
Definition BasicTypes.h:21
BOOLEAN PoolManagerFreePool(UINT64 AddressToFree)
This function set a pool flag to be freed, and it will be freed on the next IOCTL when it's safe to r...
Definition PoolManager.c:136

◆ ThreadHolderGetProcessDebuggingDetailsByThreadId()

PUSERMODE_DEBUGGING_PROCESS_DETAILS ThreadHolderGetProcessDebuggingDetailsByThreadId ( UINT32 ThreadId)

Find the active process debugging detail from the thread id.

Parameters
ThreadId
Returns
PUSERMODE_DEBUGGING_PROCESS_DETAILS
206{
207 PLIST_ENTRY TempList = 0;
208 PLIST_ENTRY TempList2 = 0;
209
211
212 while (&g_ProcessDebuggingDetailsListHead != TempList->Flink)
213 {
214 TempList = TempList->Flink;
215 PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetails =
216 CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_PROCESS_DETAILS, AttachedProcessList);
217
218 //
219 // Search through all the active threads of this process
220 //
221 TempList2 = &ProcessDebuggingDetails->ThreadsListHead;
222
223 while (&ProcessDebuggingDetails->ThreadsListHead != TempList2->Flink)
224 {
225 TempList2 = TempList2->Flink;
227 CONTAINING_RECORD(TempList2, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
228
229 for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
230 {
231 if (ThreadHolder->Threads[i].ThreadId == ThreadId)
232 {
233 //
234 // The target thread is found, not let's return the process debugging
235 // details of this process
236 //
237 return ProcessDebuggingDetails;
238 }
239 }
240 }
241 }
242
243 //
244 // Active thread not found
245 //
246 return NULL;
247}
LIST_ENTRY g_ProcessDebuggingDetailsListHead
List header of thread debugging details.
Definition Global.h:152
Description of each active thread in user-mode attaching mechanism.
Definition Attaching.h:49

◆ ThreadHolderGetProcessFirstThreadDetailsByProcessId()

PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadHolderGetProcessFirstThreadDetailsByProcessId ( UINT32 ProcessId)

Find the first active threads of the process from process id.

Parameters
ProcessId
Returns
PUSERMODE_DEBUGGING_THREAD_DETAILS
158{
159 PLIST_ENTRY TempList = 0;
160 PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail;
161
162 //
163 // First, find the process details
164 //
165 ProcessDebuggingDetail = AttachingFindProcessDebuggingDetailsByProcessId(ProcessId);
166
167 if (ProcessDebuggingDetail == NULL)
168 {
169 return NULL;
170 }
171
172 TempList = &ProcessDebuggingDetail->ThreadsListHead;
173
174 while (&ProcessDebuggingDetail->ThreadsListHead != TempList->Flink)
175 {
176 TempList = TempList->Flink;
178 CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
179
180 for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
181 {
182 if (ThreadHolder->Threads[i].ThreadId != NULL_ZERO)
183 {
184 //
185 // The active thread's structure is found
186 //
187 return &ThreadHolder->Threads[i];
188 }
189 }
190 }
191
192 //
193 // Active thread not found
194 //
195 return NULL;
196}
PUSERMODE_DEBUGGING_PROCESS_DETAILS AttachingFindProcessDebuggingDetailsByProcessId(UINT32 ProcessId)
Find user-mode debugging details for threads by process Id.
Definition Attaching.c:187

◆ ThreadHolderGetProcessThreadDetailsByProcessIdAndThreadId()

PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadHolderGetProcessThreadDetailsByProcessIdAndThreadId ( UINT32 ProcessId,
UINT32 ThreadId )

Find the active threads of the process from process id.

Parameters
ProcessId
ThreadId
Returns
PUSERMODE_DEBUGGING_THREAD_DETAILS
110{
111 PLIST_ENTRY TempList = 0;
112 PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail;
113
114 //
115 // First, find the process details
116 //
117 ProcessDebuggingDetail = AttachingFindProcessDebuggingDetailsByProcessId(ProcessId);
118
119 if (ProcessDebuggingDetail == NULL)
120 {
121 return NULL;
122 }
123
124 TempList = &ProcessDebuggingDetail->ThreadsListHead;
125
126 while (&ProcessDebuggingDetail->ThreadsListHead != TempList->Flink)
127 {
128 TempList = TempList->Flink;
130 CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
131
132 for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
133 {
134 if (ThreadHolder->Threads[i].ThreadId == ThreadId)
135 {
136 //
137 // The active thread's structure is found
138 //
139 return &ThreadHolder->Threads[i];
140 }
141 }
142 }
143
144 //
145 // Active thread not found
146 //
147 return NULL;
148}

◆ ThreadHolderIsAnyPausedThreadInProcess()

BOOLEAN ThreadHolderIsAnyPausedThreadInProcess ( PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail)

Check if there is any thread paused by checking process debugging details.

Parameters
ProcessDebuggingDetail
Returns
BOOLEAN
78{
79 PLIST_ENTRY TempList = 0;
80
81 TempList = &ProcessDebuggingDetail->ThreadsListHead;
82
83 while (&ProcessDebuggingDetail->ThreadsListHead != TempList->Flink)
84 {
85 TempList = TempList->Flink;
87 CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
88
89 for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
90 {
91 if (ThreadHolder->Threads[i].ThreadId != NULL_ZERO && ThreadHolder->Threads[i].IsPaused)
92 {
93 return TRUE;
94 }
95 }
96 }
97
98 return FALSE;
99}

◆ ThreadHolderQueryCountOfActiveDebuggingThreadsAndProcesses()

UINT32 ThreadHolderQueryCountOfActiveDebuggingThreadsAndProcesses ( )

Query count of active debugging threads and processes.

Returns
UINT32
492{
493 PLIST_ENTRY TempList = 0;
494 PLIST_ENTRY TempList2 = 0;
495 UINT32 CountOfThreadsAndProcesses = 0;
496
498
499 while (&g_ProcessDebuggingDetailsListHead != TempList->Flink)
500 {
501 TempList = TempList->Flink;
502 PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetails =
503 CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_PROCESS_DETAILS, AttachedProcessList);
504
505 //
506 // Each process is also counted (no matter if it has active paused thread or not)
507 //
508 CountOfThreadsAndProcesses++;
509
510 //
511 // Search through all the active threads of this process
512 //
513 TempList2 = &ProcessDebuggingDetails->ThreadsListHead;
514
515 while (&ProcessDebuggingDetails->ThreadsListHead != TempList2->Flink)
516 {
517 TempList2 = TempList2->Flink;
519 CONTAINING_RECORD(TempList2, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
520
521 for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
522 {
523 if (ThreadHolder->Threads[i].IsPaused)
524 {
525 //
526 // A paused thread should be counted
527 //
528 CountOfThreadsAndProcesses++;
529 }
530 }
531 }
532 }
533
534 //
535 // Return count of active threads and processes
536 //
537 return CountOfThreadsAndProcesses;
538}
unsigned int UINT32
Definition BasicTypes.h:48

◆ ThreadHolderQueryDetailsOfActiveDebuggingThreadsAndProcesses()

VOID ThreadHolderQueryDetailsOfActiveDebuggingThreadsAndProcesses ( USERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS * BufferToStoreDetails,
UINT32 MaxCount )

Query details of active debugging threads and processes.

Parameters
BufferToStoreDetails
MaxCount
Returns
VOID
552{
553 PLIST_ENTRY TempList = 0;
554 PLIST_ENTRY TempList2 = 0;
555 UINT32 CurrentIndex = 0;
556
557 if (MaxCount == 0)
558 {
559 //
560 // Invalid query, storage is empty
561 //
562 return;
563 }
564
566
567 while (&g_ProcessDebuggingDetailsListHead != TempList->Flink)
568 {
569 TempList = TempList->Flink;
570 PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetails =
571 CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_PROCESS_DETAILS, AttachedProcessList);
572
573 //
574 // Each process is also save (no matter if it has active paused thread or not)
575 //
576 BufferToStoreDetails[CurrentIndex].IsProcess = TRUE;
577 BufferToStoreDetails[CurrentIndex].ProcessId = ProcessDebuggingDetails->ProcessId;
578 CurrentIndex++;
579 if (MaxCount == CurrentIndex)
580 {
581 //
582 // Storage is full
583 //
584 return;
585 }
586
587 //
588 // Search through all the active threads of this process
589 //
590 TempList2 = &ProcessDebuggingDetails->ThreadsListHead;
591
592 while (&ProcessDebuggingDetails->ThreadsListHead != TempList2->Flink)
593 {
594 TempList2 = TempList2->Flink;
596 CONTAINING_RECORD(TempList2, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
597
598 for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
599 {
600 if (ThreadHolder->Threads[i].IsPaused)
601 {
602 //
603 // A paused thread should be saved
604 //
605 BufferToStoreDetails[CurrentIndex].IsProcess = FALSE;
606 BufferToStoreDetails[CurrentIndex].ProcessId = ProcessDebuggingDetails->ProcessId;
607 BufferToStoreDetails[CurrentIndex].ThreadId = ThreadHolder->Threads[i].ThreadId;
608 CurrentIndex++;
609 if (MaxCount == CurrentIndex)
610 {
611 //
612 // Storage is full
613 //
614 return;
615 }
616 }
617 }
618 }
619 }
620}
BOOLEAN IsProcess
Definition RequestStructures.h:813
UINT32 ThreadId
Definition RequestStructures.h:812
UINT32 ProcessId
Definition RequestStructures.h:811