HyperDbg Debugger
Loading...
Searching...
No Matches
dt-struct.cpp File Reference

dt and struct command More...

#include "pch.h"

Functions

VOID CommandDtHelp ()
 help of the dt command
 
VOID CommandStructHelp ()
 help of the struct command
 
BOOLEAN CommandDtAndStructConvertHyperDbgArgsToPdbex (vector< string > ExtraArgs, std::string &PdbexArgs, UINT32 *ProcessId)
 Convert HyperDbg arguments for dt and struct commands to pdbex arguments.
 
BOOLEAN CommandDtShowDataBasedOnSymbolTypes (const char *TypeName, UINT64 Address, BOOLEAN IsStruct, PVOID BufferAddress, UINT32 TargetPid, BOOLEAN IsPhysicalAddress, const char *AdditionalParameters)
 Show data based on the symbol structure and data types.
 
VOID CommandDtAndStruct (vector< string > SplitCommand, string Command)
 dt and struct command handler
 

Variables

BOOLEAN g_IsSerialConnectedToRemoteDebuggee
 Shows if the debugger was connected to remote debuggee over (A remote guest)
 
ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
 State of active debugging thread.
 

Detailed Description

dt and struct command

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

Function Documentation

◆ CommandDtAndStruct()

VOID CommandDtAndStruct ( vector< string > SplitCommand,
string Command )

dt and struct command handler

Parameters
SplitCommand
Command
Returns
VOID
428{
429 std::string TempTypeNameHolder;
430 std::string PdbexArgs = "";
432 UINT64 TargetAddress = NULL;
433 PVOID BufferAddressRetrievedFromDebuggee = NULL;
434 UINT32 TargetPid = NULL;
435 BOOLEAN IsPhysicalAddress = FALSE;
436
437 //
438 // Check if command is 'struct' or not
439 //
440 if (!SplitCommand.at(0).compare("struct") ||
441 !SplitCommand.at(0).compare("structure"))
442 {
443 IsStruct = TRUE;
444 }
445 else
446 {
447 IsStruct = FALSE;
448 }
449
450 //
451 // Check if command is '!dt' for physical address or not
452 //
453 if (!SplitCommand.at(0).compare("!dt"))
454 {
455 IsPhysicalAddress = TRUE;
456 }
457 else
458 {
459 IsPhysicalAddress = FALSE;
460 }
461
462 if (SplitCommand.size() == 1)
463 {
464 ShowMessages("incorrect use of the '%s'\n\n", SplitCommand.at(0).c_str());
465
466 if (IsStruct)
467 {
469 }
470 else
471 {
473 }
474
475 return;
476 }
477
478 //
479 // Trim the command
480 //
481 Trim(Command);
482
483 //
484 // Remove dt, struct, or structure from it
485 //
486 Command.erase(0, SplitCommand.at(0).size());
487
488 //
489 // Trim it again
490 //
491 Trim(Command);
492
493 //
494 // Check for the first and second arguments
495 //
496 vector<string> TempSplitCommand {Split(Command, ' ')};
497
498 //
499 // If the size is zero, then it's only a type name
500 //
501 if (TempSplitCommand.size() == 1)
502 {
503 //
504 // Call the dt parser wrapper, it's only a structure (type) name
505 // Call it with default configuration
506 //
507 CommandDtShowDataBasedOnSymbolTypes(TempSplitCommand.at(0).c_str(),
508 NULL,
509 IsStruct,
510 NULL,
511 TargetPid,
512 IsPhysicalAddress,
514 }
515 else
516 {
517 //
518 // When we're here, it means we have size() >= 2, so we have to check
519 // the first and the second method to see which one is the type and
520 // which one is the symbol
521 //
522
523 //
524 // Check if the first parameter is an address or valid expression
525 //
526 if (IsStruct || !SymbolConvertNameOrExprToAddress(TempSplitCommand.at(0).c_str(),
527 &TargetAddress))
528 {
529 //
530 // No it's not, we'll get the first argument as the structure (type) name
531 // And we have to check whether the second argument is a buffer address or not
532 //
533 if (IsStruct || !SymbolConvertNameOrExprToAddress(TempSplitCommand.at(1).c_str(),
534 &TargetAddress))
535 {
536 //
537 // The second argument is also not buffer address
538 // probably the user entered a structure (type) name along with some params
539 //
540 TempTypeNameHolder = TempSplitCommand.at(0);
541
542 //
543 // Remove the first argument
544 //
545 TempSplitCommand.erase(TempSplitCommand.begin());
546
547 //
548 // Convert to pdbex args
549 //
550 if (!CommandDtAndStructConvertHyperDbgArgsToPdbex(TempSplitCommand, PdbexArgs, &TargetPid))
551 {
552 if (IsStruct)
553 {
555 }
556 else
557 {
559 }
560
561 return;
562 }
563
564 //
565 // Call the wrapper of pdbex
566 //
567 CommandDtShowDataBasedOnSymbolTypes(TempTypeNameHolder.c_str(),
568 TargetAddress,
569 IsStruct,
570 BufferAddressRetrievedFromDebuggee,
571 TargetPid,
572 IsPhysicalAddress,
573 PdbexArgs.c_str());
574 }
575 else
576 {
577 //
578 // The second argument is a buffer address
579 // The user entered a structure (type) name along with buffer address
580 //
581 if (TempSplitCommand.size() == 2)
582 {
583 //
584 // There is not parameters, only a symbol name and then a buffer address
585 // Call it with default configuration
586 //
587 CommandDtShowDataBasedOnSymbolTypes(TempSplitCommand.at(0).c_str(),
588 TargetAddress,
589 IsStruct,
590 BufferAddressRetrievedFromDebuggee,
591 TargetPid,
592 IsPhysicalAddress,
594 }
595 else
596 {
597 //
598 // Other than the first argument which is a structure (type) name, and
599 // the second argument which is buffer address, there are other parameters, so
600 // we WON'T call it with default parameters
601 //
602 TempTypeNameHolder = TempSplitCommand.at(0);
603
604 //
605 // Remove the first, and the second arguments
606 //
607 TempSplitCommand.erase(TempSplitCommand.begin());
608 TempSplitCommand.erase(TempSplitCommand.begin());
609
610 //
611 // Convert to pdbex args
612 //
613 if (!CommandDtAndStructConvertHyperDbgArgsToPdbex(TempSplitCommand, PdbexArgs, &TargetPid))
614 {
615 if (IsStruct)
616 {
618 }
619 else
620 {
622 }
623
624 return;
625 }
626
627 //
628 // Call the wrapper of pdbex
629 //
630 CommandDtShowDataBasedOnSymbolTypes(TempTypeNameHolder.c_str(),
631 TargetAddress,
632 IsStruct,
633 BufferAddressRetrievedFromDebuggee,
634 TargetPid,
635 IsPhysicalAddress,
636 PdbexArgs.c_str());
637 }
638 }
639 }
640 else
641 {
642 //
643 // The first argument is a buffer address, so we get the first argument as
644 // a buffer address and the second argument as the structure (type) name
645 //
646 if (TempSplitCommand.size() == 2)
647 {
648 //
649 // There is not parameters, only a buffer address and then a symbol name
650 // Call it with default configuration
651 //
652 CommandDtShowDataBasedOnSymbolTypes(TempSplitCommand.at(1).c_str(),
653 TargetAddress,
654 IsStruct,
655 BufferAddressRetrievedFromDebuggee,
656 TargetPid,
657 IsPhysicalAddress,
659 }
660 else
661 {
662 //
663 // Other than the first argument which is a buffer address, and the second
664 // argument which is structure (type) name, there are other parameters, so
665 // we WON'T call it with default parameters
666 //
667 TempTypeNameHolder = TempSplitCommand.at(1);
668
669 //
670 // Remove the first, and the second arguments
671 //
672 TempSplitCommand.erase(TempSplitCommand.begin());
673 TempSplitCommand.erase(TempSplitCommand.begin());
674
675 //
676 // Convert to pdbex args
677 //
678 if (!CommandDtAndStructConvertHyperDbgArgsToPdbex(TempSplitCommand, PdbexArgs, &TargetPid))
679 {
680 if (IsStruct)
681 {
683 }
684 else
685 {
687 }
688
689 return;
690 }
691
692 //
693 // Call the wrapper of pdbex
694 //
695 CommandDtShowDataBasedOnSymbolTypes(TempTypeNameHolder.c_str(),
696 TargetAddress,
697 IsStruct,
698 BufferAddressRetrievedFromDebuggee,
699 TargetPid,
700 IsPhysicalAddress,
701 PdbexArgs.c_str());
702 }
703 }
704 }
705}
UCHAR BOOLEAN
Definition BasicTypes.h:39
#define TRUE
Definition BasicTypes.h:55
#define FALSE
Definition BasicTypes.h:54
unsigned __int64 UINT64
Definition BasicTypes.h:21
unsigned int UINT32
Definition BasicTypes.h:48
UINT64 BOOLEAN IsStruct
Definition HyperDbgScriptImports.h:67
const vector< string > Split(const string &s, const char &c)
general split command
Definition common.cpp:117
void Trim(std::string &s)
trim from both ends and start of a string (in place)
Definition common.cpp:594
BOOLEAN CommandDtShowDataBasedOnSymbolTypes(const char *TypeName, UINT64 Address, BOOLEAN IsStruct, PVOID BufferAddress, UINT32 TargetPid, BOOLEAN IsPhysicalAddress, const char *AdditionalParameters)
Show data based on the symbol structure and data types.
Definition dt-struct.cpp:314
VOID CommandStructHelp()
help of the struct command
Definition dt-struct.cpp:63
BOOLEAN CommandDtAndStructConvertHyperDbgArgsToPdbex(vector< string > ExtraArgs, std::string &PdbexArgs, UINT32 *ProcessId)
Convert HyperDbg arguments for dt and struct commands to pdbex arguments.
Definition dt-struct.cpp:92
VOID CommandDtHelp()
help of the dt command
Definition dt-struct.cpp:26
VOID ShowMessages(const char *Fmt,...)
Show messages.
Definition libhyperdbg.cpp:96
NULL()
Definition test-case-generator.py:530
BOOLEAN SymbolConvertNameOrExprToAddress(const string &TextToConvert, PUINT64 Result)
check and convert string to a 64 bit unsigned integer and also check for symbol object names and eval...
Definition symbol.cpp:360
#define PDBEX_DEFAULT_CONFIGURATION
Definition symbol.h:33

◆ CommandDtAndStructConvertHyperDbgArgsToPdbex()

BOOLEAN CommandDtAndStructConvertHyperDbgArgsToPdbex ( vector< string > ExtraArgs,
std::string & PdbexArgs,
UINT32 * ProcessId )

Convert HyperDbg arguments for dt and struct commands to pdbex arguments.

This is because we don't wanna modify the internal structure of pdbex so let's pdbex parse its standard commands

Parameters
ExtraArgs
PdbexArgs
ProcessId
Returns
BOOLEAN
95{
96 UINT32 TargetProcessId = NULL;
97 BOOLEAN NextItemIsYesNo = FALSE;
98 BOOLEAN NextItemIsString = FALSE;
99 BOOLEAN NextItemIsInline = FALSE;
100 BOOLEAN NextItemIsFileName = FALSE;
101 BOOLEAN NextItemIsProcessId = FALSE;
102
103 //
104 // Clear the args
105 //
106 PdbexArgs = "";
107
108 //
109 // Traverse through the extra arguments
110 //
111 for (auto Item : ExtraArgs)
112 {
113 //
114 // Check for output file name
115 //
116 if (NextItemIsFileName)
117 {
118 PdbexArgs += Item + " ";
119
120 NextItemIsFileName = FALSE;
121 continue;
122 }
123
124 //
125 // Check for process id
126 //
127 if (NextItemIsProcessId)
128 {
129 if (!ConvertStringToUInt32(Item, &TargetProcessId))
130 {
131 ShowMessages("err, you should enter a valid process id\n\n");
132 return FALSE;
133 }
134
135 NextItemIsProcessId = FALSE;
136 continue;
137 }
138
139 //
140 // Check if we expect yes/no answers
141 //
142 if (NextItemIsYesNo)
143 {
144 if (!Item.compare("yes"))
145 {
146 PdbexArgs += " ";
147 }
148 else if (!Item.compare("no"))
149 {
150 PdbexArgs += "- ";
151 }
152 else
153 {
154 //
155 // Yes/no expected but didn't see it
156 //
157 ShowMessages("err, please insert 'yes' or 'no' as the argument\n\n");
158 return FALSE;
159 }
160
161 NextItemIsYesNo = FALSE;
162 continue;
163 }
164
165 //
166 // Check if we expect inline param answers
167 //
168 if (NextItemIsInline)
169 {
170 if (!Item.compare("none"))
171 {
172 PdbexArgs += "n ";
173 }
174 else if (!Item.compare("all"))
175 {
176 PdbexArgs += "a ";
177 }
178 else if (!Item.compare("unnamed") || !Item.compare("unamed"))
179 {
180 PdbexArgs += "i ";
181 }
182 else
183 {
184 //
185 // none/inline/all expected but didn't see it
186 //
187 ShowMessages("err, please insert 'none', 'inline', or 'all' as the argument\n\n");
188 return FALSE;
189 }
190
191 NextItemIsInline = FALSE;
192 continue;
193 }
194
195 //
196 // Check if we expect string answers
197 //
198 if (NextItemIsString)
199 {
200 PdbexArgs += Item + " ";
201
202 NextItemIsString = FALSE;
203 continue;
204 }
205
206 //
207 // Check for args
208 //
209 if (!Item.compare("pid"))
210 {
211 NextItemIsProcessId = TRUE;
212 }
213 else if (!Item.compare("output"))
214 {
215 NextItemIsFileName = TRUE;
216 PdbexArgs += "-o ";
217 }
218 else if (!Item.compare("inline"))
219 {
220 NextItemIsInline = TRUE;
221 PdbexArgs += "-e ";
222 }
223 else if (!Item.compare("prefix"))
224 {
225 NextItemIsString = TRUE;
226 PdbexArgs += "-r ";
227 }
228 else if (!Item.compare("suffix"))
229 {
230 NextItemIsString = TRUE;
231 PdbexArgs += "-g ";
232 }
233 else if (!Item.compare("padding"))
234 {
235 NextItemIsYesNo = TRUE;
236 PdbexArgs += "-p";
237 }
238 else if (!Item.compare("offset") || !Item.compare("offsets"))
239 {
240 NextItemIsYesNo = TRUE;
241 PdbexArgs += "-x";
242 }
243 else if (!Item.compare("bitfield") || !Item.compare("bitfields"))
244 {
245 NextItemIsYesNo = TRUE;
246 PdbexArgs += "-b";
247 }
248 else if (!Item.compare("native"))
249 {
250 NextItemIsYesNo = TRUE;
251 PdbexArgs += "-i";
252 }
253 else if (!Item.compare("decl"))
254 {
255 NextItemIsYesNo = TRUE;
256 PdbexArgs += "-n";
257 }
258 else if (!Item.compare("def"))
259 {
260 NextItemIsYesNo = TRUE;
261 PdbexArgs += "-l";
262 }
263 else if (!Item.compare("func"))
264 {
265 NextItemIsYesNo = TRUE;
266 PdbexArgs += "-f";
267 }
268 else if (!Item.compare("pragma"))
269 {
270 NextItemIsYesNo = TRUE;
271 PdbexArgs += "-z";
272 }
273 else
274 {
275 //
276 // Unknown args
277 //
278 ShowMessages("err, unknown argument at '%s'\n\n", Item.c_str());
279 return FALSE;
280 }
281 }
282
283 //
284 // Check if user entered yes/no or string when expected or not
285 //
286 if (NextItemIsYesNo || NextItemIsString || NextItemIsInline || NextItemIsFileName || NextItemIsProcessId)
287 {
288 ShowMessages("err, incomplete argument\n\n");
289 return FALSE;
290 }
291
292 //
293 // Set the process id
294 //
295 *ProcessId = TargetProcessId;
296
297 return TRUE;
298}
BOOLEAN ConvertStringToUInt32(string TextToConvert, PUINT32 Result)
check and convert string to a 32 bit unsigned it and also check for special notations like 0x etc.
Definition common.cpp:347

◆ CommandDtHelp()

VOID CommandDtHelp ( )

help of the dt command

Returns
VOID
27{
28 ShowMessages("dt !dt : displays information about a local variable, global "
29 "variable or data type.\n\n");
30
31 ShowMessages("If you want to read physical memory then add '!' at the "
32 "start of the command\n\n");
33
34 ShowMessages("syntax : \tdt [Module!SymbolName (string)] [AddressExpression (string)] "
35 "[pid ProcessId (hex)] [padding Padding (yesno)] [offset Offset (yesno)] "
36 "[bitfield Bitfield (yesno)] [native Native (yesno)] [decl Declaration (yesno)] "
37 "[def Definitions (yesno)] [func Functions (yesno)] [pragma Pragma (yesno)] "
38 "[prefix Prefix (string)] [suffix Suffix (string)] [inline Expantion (string)] "
39 "[output FileName (string)]\n\n");
40 ShowMessages("syntax : \t!dt [Module!SymbolName (string)] [AddressExpression (string)] "
41 "[padding Padding (yesno)] [offset Offset (yesno)] [bitfield Bitfield (yesno)] "
42 "[native Native (yesno)] [decl Declaration (yesno)] [def Definitions (yesno)] "
43 "[func Functions (yesno)] [pragma Pragma (yesno)] [prefix Prefix (string)] "
44 "[suffix Suffix (string)] [inline Expantion (string)] [output FileName (string)]\n");
45
46 ShowMessages("\n");
47 ShowMessages("\t\te.g : dt nt!_EPROCESS\n");
48 ShowMessages("\t\te.g : dt nt!_EPROCESS fffff8077356f010\n");
49 ShowMessages("\t\te.g : dt nt!_EPROCESS $proc\n");
50 ShowMessages("\t\te.g : dt nt!_KPROCESS @rax+@rbx+c0\n");
51 ShowMessages("\t\te.g : !dt nt!_EPROCESS 1f0300\n");
52 ShowMessages("\t\te.g : dt nt!_MY_STRUCT 7ff00040 pid 1420\n");
53 ShowMessages("\t\te.g : dt nt!_EPROCESS $proc inline all\n");
54 ShowMessages("\t\te.g : dt nt!_EPROCESS fffff8077356f010 inline no\n");
55}

◆ CommandDtShowDataBasedOnSymbolTypes()

BOOLEAN CommandDtShowDataBasedOnSymbolTypes ( const char * TypeName,
UINT64 Address,
BOOLEAN IsStruct,
PVOID BufferAddress,
UINT32 TargetPid,
BOOLEAN IsPhysicalAddress,
const char * AdditionalParameters )

Show data based on the symbol structure and data types.

Parameters
TypeName
Address
IsStruct
BufferAddress
TargetPid
IsPhysicalAddress
AdditionalParameters
Returns
BOOLEAN
322{
323 UINT64 StructureSize = 0;
324 BOOLEAN ResultOfFindingSize = FALSE;
325 DEBUGGER_DT_COMMAND_OPTIONS DtOptions = {0};
326
327 //
328 // Check for pid
329 //
330
331 if (g_IsSerialConnectedToRemoteDebuggee && TargetPid != 0)
332 {
333 //
334 // Check to prevent using process id in dt command
335 //
337 return FALSE;
338 }
339 else if (TargetPid == NULL)
340 {
341 //
342 // By default if the user-debugger is active, we use these commands
343 // on the memory layout of the debuggee process
344 //
346 {
348 }
349 else
350 {
351 //
352 // Use the current process for the pid
353 //
354 TargetPid = GetCurrentProcessId();
355 }
356 }
357
358 //
359 // Set the options
360 //
361 DtOptions.TypeName = TypeName;
362 DtOptions.Address = Address;
363 DtOptions.IsStruct = IsStruct;
364 DtOptions.BufferAddress = NULL; // we didn't read it yet
365 DtOptions.TargetPid = TargetPid;
367
368 if (Address != NULL)
369 {
370 //
371 // *** We need to read the memory here ***
372 //
373
374 //
375 // Get the field size
376 //
377 ResultOfFindingSize = ScriptEngineGetDataTypeSizeWrapper((char *)TypeName, &StructureSize);
378
379 //
380 // Check if size is found
381 //
382 if (!ResultOfFindingSize || StructureSize == 0)
383 {
384 //
385 // Field not found or size is invalid
386 //
387 ShowMessages("err, couldn't resolve error at '%s'\n", TypeName);
388 return FALSE;
389 }
390
391 //
392 // Set the type (structure) size
393 //
394 DtOptions.SizeOfTypeName = StructureSize;
395
396 //
397 // Read the memory
398 //
400 Address,
403 TargetPid,
404 (UINT32)StructureSize,
405 &DtOptions);
406
407 return TRUE;
408 }
409 else
410 {
411 //
412 // It's a simple structure without an address
413 // Call the pdbex wrapper
414 //
416 }
417}
UINT64 Address
Definition HyperDbgScriptImports.h:67
UINT64 BOOLEAN PVOID const char * AdditionalParameters
Definition HyperDbgScriptImports.h:67
UINT64 BOOLEAN PVOID BufferAddress
Definition HyperDbgScriptImports.h:67
@ READ_FROM_KERNEL
Definition RequestStructures.h:219
@ DEBUGGER_SHOW_COMMAND_DT
Definition RequestStructures.h:251
@ DEBUGGER_READ_PHYSICAL_ADDRESS
Definition RequestStructures.h:229
@ DEBUGGER_READ_VIRTUAL_ADDRESS
Definition RequestStructures.h:230
BOOLEAN g_IsSerialConnectedToRemoteDebuggee
Shows if the debugger was connected to remote debuggee over (A remote guest)
Definition globals.h:231
ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
State of active debugging thread.
Definition globals.h:362
#define ASSERT_MESSAGE_CANNOT_SPECIFY_PID
Definition common.h:31
VOID HyperDbgShowMemoryOrDisassemble(DEBUGGER_SHOW_MEMORY_STYLE Style, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, DEBUGGER_READ_READING_TYPE ReadingType, UINT32 Pid, UINT32 Size, PDEBUGGER_DT_COMMAND_OPTIONS DtDetails)
Show memory or disassembler.
Definition readmem.cpp:193
BOOLEAN ScriptEngineShowDataBasedOnSymbolTypesWrapper(const char *TypeName, UINT64 Address, BOOLEAN IsStruct, PVOID BufferAddress, const char *AdditionalParameters)
ScriptEngineShowDataBasedOnSymbolTypes wrapper.
Definition script-engine-wrapper.cpp:212
BOOLEAN ScriptEngineGetDataTypeSizeWrapper(CHAR *TypeName, UINT64 *TypeSize)
ScriptEngineGetDataTypeSize wrapper.
Definition script-engine-wrapper.cpp:146
UINT32 ProcessId
Definition ud.h:51
BOOLEAN IsActive
Definition ud.h:49
requests options for dt and struct command
Definition RequestStructures.h:135
UINT64 Address
Definition RequestStructures.h:138
const char * TypeName
Definition RequestStructures.h:136
PVOID BufferAddress
Definition RequestStructures.h:140
BOOLEAN IsStruct
Definition RequestStructures.h:139
UINT32 TargetPid
Definition RequestStructures.h:141
UINT64 SizeOfTypeName
Definition RequestStructures.h:137
const char * AdditionalParameters
Definition RequestStructures.h:142

◆ CommandStructHelp()

VOID CommandStructHelp ( )

help of the struct command

Returns
VOID
64{
65 ShowMessages("struct : displays a data type, enum, or structure derived from PDB symbols.\n\n");
66
67 ShowMessages("syntax : struct [Module!SymbolName (string)] [offset Offset (yesno)] [bitfield Bitfield (yesno)] "
68 "[native Native (yesno)] [decl Declaration (yesno)] [def Definitions (yesno)] "
69 "[func Functions (yesno)] [pragma Pragma (yesno)] [prefix Prefix (string)] "
70 "[suffix Suffix (string)] [inline Expantion (string)] [output FileName (string)]\n");
71
72 ShowMessages("\n");
73 ShowMessages("\t\te.g : struct nt!_EPROCESS\n");
74 ShowMessages("\t\te.g : struct nt!*\n");
75 ShowMessages("\t\te.g : struct nt!* output ntheader.h\n");
76 ShowMessages("\t\te.g : struct nt!* func yes output ntheader.h\n");
77 ShowMessages("\t\te.g : struct nt!* func yes output ntheader.h\n");
78}

Variable Documentation

◆ g_ActiveProcessDebuggingState

ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
extern

State of active debugging thread.

362{0};

◆ g_IsSerialConnectedToRemoteDebuggee

BOOLEAN g_IsSerialConnectedToRemoteDebuggee
extern

Shows if the debugger was connected to remote debuggee over (A remote guest)