HyperDbg Debugger
Loading...
Searching...
No Matches
ud.cpp File Reference

control the user-mode debugging affairs More...

#include "pch.h"

Functions

VOID UdInitializeUserDebugger ()
 Initialize the user debugger in user mode.
VOID UdUninitializeUserDebugger ()
 Uninitialize the user debugger in user mode.
VOID UdSetActiveDebuggingProcess (UINT64 DebuggingId, UINT64 Rip, UINT32 ProcessId, UINT32 ThreadId, BOOLEAN Is32Bit, BOOLEAN IsPaused, BYTE InstructionBytesOnRip[])
 set the current active debugging process (thread)
VOID UdRemoveActiveDebuggingProcess ()
 Remove the current active debugging process (thread).
VOID UdPrintError ()
 print error messages relating to the finding thread id
BOOLEAN UdListProcessThreads (DWORD OwnerPID)
 List of threads by owner process id.
BOOLEAN UdCheckThreadByProcessId (DWORD Pid, DWORD Tid)
 Check if a thread belongs to special process.
BOOLEAN UdCreateSuspendedProcess (const WCHAR *FileName, const WCHAR *CommandLine, PPROCESS_INFORMATION ProcessInformation)
 Attach to a target process.
BOOLEAN UdAttachToProcess (UINT32 TargetPid, const WCHAR *TargetFileAddress, const WCHAR *CommandLine, BOOLEAN RunCallbackAtTheFirstInstruction)
 Attach to target process.
BOOLEAN UdTerminateProcessByPid (DWORD TargetPid)
 Check if process exists or not.
BOOLEAN UdDoesProcessExistByPid (DWORD TargetPid)
 Check if process exists or not by process id.
BOOLEAN UdDoesProcessExistByHandle (HANDLE TargetHandle)
 Check if process exists or not by handle.
BOOLEAN UdKillProcess (UINT32 TargetPid)
 Kill the target process from kernel.
BOOLEAN UdDetachProcess (UINT32 TargetPid, UINT64 ProcessDetailToken)
 Detach the target process.
BOOLEAN UdPauseProcess (UINT64 ProcessDebuggingToken)
 Pause the target process.
BOOLEAN UdContinueProcess (UINT64 ProcessDebuggingToken)
 Continue the target process.
BOOLEAN UdSendCommand (UINT64 ProcessDetailToken, UINT32 ThreadId, DEBUGGER_UD_COMMAND_ACTION_TYPE ActionType, PVOID OptionalBuffer, UINT32 OptionalBufferSize, BOOLEAN ApplyToAllPausedThreads, BOOLEAN WaitForEventCompletion, UINT64 OptionalParam1, UINT64 OptionalParam2, UINT64 OptionalParam3, UINT64 OptionalParam4)
 Send the command to the user debugger.
BOOLEAN UdSendReadRegisterToUserDebugger (UINT64 ProcessDetailToken, UINT32 TargetThreadId, PDEBUGGEE_REGISTER_READ_DESCRIPTION RegDes, UINT32 RegBuffSize)
 Send the command to the user debugger.
BOOLEAN UdSendScriptBufferToProcess (UINT64 ProcessDetailToken, UINT32 TargetThreadId, UINT64 BufferAddress, UINT32 BufferLength, UINT32 Pointer, BOOLEAN IsFormat)
 Send script buffer to the user debugger.
BOOLEAN UdSendStepPacketToDebuggee (UINT64 ProcessDetailToken, UINT32 TargetThreadId, DEBUGGER_REMOTE_STEPPING_REQUEST StepType)
 Send stepping instructions packet to user debugger.
BOOLEAN UdSetActiveDebuggingThreadByPidOrTid (UINT32 TargetPidOrTid, BOOLEAN IsTid)
 Set the active debugging thread by process id or thread id.
BOOLEAN UdShowListActiveDebuggingProcessesAndThreads ()
 Show list of active debugging processes and threads.

Variables

UINT32 g_ProcessIdOfLatestStartingProcess
 The process id of the latest starting process.
ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
 State of active debugging thread.
BOOLEAN g_IsUserDebuggerInitialized
 Whether the user debugger is initialized or not.
BOOLEAN g_IsVmmModuleLoaded
 shows whether the VMM module is loaded or not
UINT64 g_ResultOfEvaluatedExpression
 Result of the expression that is evaluated in the debuggee.
UINT32 g_ErrorStateOfResultOfEvaluatedExpression
 Shows the state of the evaluation of expression which whether contains error or not.
CommandType g_CommandsList
 List of command and attributes.
DEBUGGER_SYNCRONIZATION_EVENTS_STATE g_UserSyncronizationObjectsHandleTable [DEBUGGER_MAXIMUM_SYNCRONIZATION_USER_DEBUGGER_OBJECTS]
 In debugger (not debuggee), we save the handle of the user-mode listening thread for pauses here for user debugger.

Detailed Description

control the user-mode debugging affairs

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

Function Documentation

◆ UdAttachToProcess()

BOOLEAN UdAttachToProcess ( UINT32 TargetPid,
const WCHAR * TargetFileAddress,
const WCHAR * CommandLine,
BOOLEAN RunCallbackAtTheFirstInstruction )

Attach to target process.

this function will not check whether the process id is valid or not

Parameters
TargetPid
TargetFileAddress
CommandLine
RunCallbackAtTheFirstInstruction
Returns
BOOLEAN
376{
377 BOOLEAN Status;
378 ULONG ReturnedLength;
380 PROCESS_INFORMATION ProcInfo = {0};
381
382 //
383 // Check to initialize the user-debugger
384 //
386
387 //
388 // Check if the VMM module is loaded or not
389 //
391
392 //
393 // Check whether it's starting a new process or not
394 //
395 if (TargetFileAddress == NULL)
396 {
397 AttachRequest.IsStartingNewProcess = FALSE;
398 }
399 else
400 {
401 AttachRequest.IsStartingNewProcess = TRUE;
402 }
403
404 //
405 // Set the state of the debugger for getting the callback at the first instruction
406 //
407 AttachRequest.CheckCallbackAtFirstInstruction = RunCallbackAtTheFirstInstruction;
408
409 //
410 // We wanna attach to a remote process
411 //
413
414 if (AttachRequest.IsStartingNewProcess)
415 {
416 //
417 // Check if file exists or not
418 //
419 if (!IsFileExistW(TargetFileAddress))
420 {
421 ShowMessages("err, unable to start (file not found)\n");
422 return FALSE;
423 }
424
425 //
426 // Start the process in suspended state
427 //
428 UdCreateSuspendedProcess(TargetFileAddress, CommandLine, &ProcInfo);
429
430 //
431 // Set the process id and thread id
432 //
433 AttachRequest.ProcessId = ProcInfo.dwProcessId;
434 AttachRequest.ThreadId = ProcInfo.dwThreadId;
435 }
436 else
437 {
438 //
439 // Set the process id
440 //
441 AttachRequest.ProcessId = TargetPid;
442 }
443
444 //
445 // Send the request to the kernel
446 //
447 Status = DeviceIoControl(
448 g_DeviceHandle, // Handle to device
450 // code
451 &AttachRequest, // Input Buffer to driver.
453 &AttachRequest, // Output Buffer from driver.
455 // buffer in bytes.
456 &ReturnedLength, // Bytes placed in buffer.
457 NULL // synchronous call
458 );
459
460 if (!Status)
461 {
462 ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
463 return FALSE;
464 }
465
466 //
467 // Check if attaching was successful then we can set the attached to true
468 //
469 if (AttachRequest.Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
470 {
471 if (!AttachRequest.IsStartingNewProcess)
472 {
473 //
474 // it's a .attach command, no need for further action
475 //
476 ShowMessages("successfully attached to the target process!\n"
477 "please keep interacting with the process until all the threads are "
478 "intercepted and halted; you can run the 'g' command to continue the debuggee\n");
479 return TRUE;
480 }
481
482 // ShowMessages("Base Address : %llx\n", AttachRequest.BaseAddressOfMainModule);
483 // ShowMessages("Entrypoint Address : %llx\n", AttachRequest.EntrypoinOfMainModule);
484
485 //
486 // Resume the suspended process
487 //
488 if (ProcInfo.hThread != NULL64_ZERO)
489 {
490 ResumeThread(ProcInfo.hThread);
491 }
492 else
493 {
494 //
495 // The handle of the target thread is empty
496 //
497 return FALSE;
498 }
499
500 //
501 // *** Remove the hooks ***
502 //
503
504 while (TRUE)
505 {
506 //
507 // Send the previous request with removing hook as the action
508 //
510
511 //
512 // Send the request to the kernel
513 //
514 Status = DeviceIoControl(
515 g_DeviceHandle, // Handle to device
517 // code
518 &AttachRequest, // Input Buffer to driver.
520 &AttachRequest, // Output Buffer from driver.
522 // buffer in bytes.
523 &ReturnedLength, // Bytes placed in buffer.
524 NULL // synchronous call
525 );
526
527 if (!Status)
528 {
529 ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
530 return FALSE;
531 }
532
533 //
534 // Check whether the result of removing hooks was successful or we should
535 // re-send the request
536 //
537 if (AttachRequest.Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
538 {
539 //
540 // The hook is remove successfully
541 //
542 break;
543 }
545 {
546 //
547 // Wait for a while until the Windows call the entrypoint
548 //
549 // ShowMessages("entrypoint is not reached, continue sending the request...\n");
550
551 Sleep(1000);
552 continue;
553 }
554 else
555 {
556 //
557 // An error happened, we should not continue
558 //
559 ShowErrorMessage((UINT32)AttachRequest.Result);
560 return FALSE;
561 }
562 }
563
564 //
565 // Store the process id and handle of the latest process
566 //
567 g_ProcessIdOfLatestStartingProcess = ProcInfo.dwProcessId;
568
569 //
570 // The operation of attaching was successful
571 //
572 return TRUE;
573 }
574 else
575 {
576 ShowErrorMessage((UINT32)AttachRequest.Result);
577 return FALSE;
578 }
579
580 return FALSE;
581}
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
unsigned long ULONG
Definition BasicTypes.h:31
#define DEBUGGER_ERROR_UNABLE_TO_REMOVE_HOOKS_ENTRYPOINT_NOT_REACHED
error, failed to remove hooks as entrypoint is not reached yet
Definition ErrorCodes.h:302
#define DEBUGGER_OPERATION_WAS_SUCCESSFUL
General value to indicate that the operation or request was successful.
Definition ErrorCodes.h:23
#define IOCTL_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS
ioctl, attach or detach user-mode processes
Definition Ioctls.h:220
#define SIZEOF_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS
Definition RequestStructures.h:655
struct _DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS
request for attaching user-mode process
@ DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_ATTACH
Definition RequestStructures.h:664
@ DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_REMOVE_HOOKS
Definition RequestStructures.h:666
BOOLEAN IsFileExistW(const WCHAR *FileName)
check if a file exist or not (wide-char)
Definition common.cpp:753
BOOLEAN ShowErrorMessage(UINT32 Error)
shows the error message
Definition debugger.cpp:40
UINT32 g_ProcessIdOfLatestStartingProcess
The process id of the latest starting process.
Definition globals.h:378
#define AssertShowMessageReturnStmt(expr1, expr2, message1, message2, rc)
Definition common.h:59
#define ASSERT_MESSAGE_VMM_NOT_LOADED
Definition common.h:31
#define ASSERT_MESSAGE_DRIVER_NOT_LOADED
Definition common.h:27
#define AssertReturnFalse
Definition common.h:21
HANDLE g_DeviceHandle
Holds the global handle of device which is used to send the request to the kernel by IOCTL,...
Definition globals.h:481
BOOLEAN g_IsVmmModuleLoaded
shows whether the VMM module is loaded or not
Definition globals.h:28
BOOLEAN CheckCallbackAtFirstInstruction
Definition RequestStructures.h:684
DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_TYPE Action
Definition RequestStructures.h:690
BOOLEAN IsStartingNewProcess
Definition RequestStructures.h:681
UINT32 ProcessId
Definition RequestStructures.h:682
UINT64 Result
Definition RequestStructures.h:693
UINT32 ThreadId
Definition RequestStructures.h:683
VOID UdInitializeUserDebugger()
Initialize the user debugger in user mode.
Definition ud.cpp:33
BOOLEAN UdCreateSuspendedProcess(const WCHAR *FileName, const WCHAR *CommandLine, PPROCESS_INFORMATION ProcessInformation)
Attach to a target process.
Definition ud.cpp:329

◆ UdCheckThreadByProcessId()

BOOLEAN UdCheckThreadByProcessId ( DWORD Pid,
DWORD Tid )

Check if a thread belongs to special process.

Parameters
PidProcess id
TidThread id
Returns
BOOLEAN if the thread belongs to process then return true; otherwise returns false
267{
268 HANDLE ThreadSnap = INVALID_HANDLE_VALUE;
269 THREADENTRY32 Te32;
270 BOOLEAN Result = FALSE;
271
272 //
273 // Take a snapshot of all running threads
274 //
275 ThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
276 if (ThreadSnap == INVALID_HANDLE_VALUE)
277 return FALSE;
278
279 //
280 // Fill in the size of the structure before using it
281 //
282 Te32.dwSize = sizeof(THREADENTRY32);
283
284 //
285 // Retrieve information about the first thread and exit if unsuccessful
286 //
287 if (!Thread32First(ThreadSnap, &Te32))
288 {
289 UdPrintError(); // Show cause of failure
290 CloseHandle(ThreadSnap); // Must clean up the snapshot object!
291 return FALSE;
292 }
293
294 //
295 // Now walk the thread list of the system, and display information
296 // about each thread associated with the specified process
297 //
298 do
299 {
300 if (Te32.th32OwnerProcessID == Pid)
301 {
302 if (Te32.th32ThreadID == Tid)
303 {
304 //
305 // The thread found in target process
306 //
307 Result = TRUE;
308 break;
309 }
310 }
311 } while (Thread32Next(ThreadSnap, &Te32));
312
313 //
314 // Don't forget to clean up the snapshot object
315 //
316 CloseHandle(ThreadSnap);
317 return Result;
318}
VOID UdPrintError()
print error messages relating to the finding thread id
Definition ud.cpp:167

◆ UdContinueProcess()

BOOLEAN UdContinueProcess ( UINT64 ProcessDebuggingToken)

Continue the target process.

Parameters
ProcessDebuggingToken
Returns
BOOLEAN
934{
935 BOOLEAN Status;
936 ULONG ReturnedLength;
938
939 //
940 // Check if the VMM module is loaded or not
941 //
943
944 //
945 // We wanna continue a process
946 //
948
949 //
950 // Set the process debugging token
951 //
952 PauseRequest.Token = ProcessDebuggingToken;
953
954 //
955 // Send the request to the kernel
956 //
957 Status = DeviceIoControl(
958 g_DeviceHandle, // Handle to device
960 // code
961 &PauseRequest, // Input Buffer to driver.
963 &PauseRequest, // Output Buffer from driver.
965 // buffer in bytes.
966 &ReturnedLength, // Bytes placed in buffer.
967 NULL // synchronous call
968 );
969
970 if (!Status)
971 {
972 ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
973 return FALSE;
974 }
975
976 //
977 // Check if continuing was successful or not
978 //
979 if (PauseRequest.Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
980 {
981 //
982 // The operation of attaching was successful
983 //
984 return TRUE;
985 }
986 else
987 {
988 ShowErrorMessage((UINT32)PauseRequest.Result);
989 return FALSE;
990 }
991}
@ DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_CONTINUE_PROCESS
Definition RequestStructures.h:668
UINT64 Token
Definition RequestStructures.h:692

◆ UdCreateSuspendedProcess()

BOOLEAN UdCreateSuspendedProcess ( const WCHAR * FileName,
const WCHAR * CommandLine,
PPROCESS_INFORMATION ProcessInformation )

Attach to a target process.

Parameters
FileName
CommandLine
ProcessInformation
Returns
BOOLEAN
330{
331 STARTUPINFOW StartupInfo;
332 BOOL CreateProcessResult;
333
334 memset(&StartupInfo, 0, sizeof(StartupInfo));
335 StartupInfo.cb = sizeof(STARTUPINFOA);
336
337 //
338 // Create process suspended
339 //
340 CreateProcessResult = CreateProcessW(FileName,
341 (WCHAR *)CommandLine,
342 NULL,
343 NULL,
344 FALSE,
345 CREATE_SUSPENDED | CREATE_NEW_CONSOLE,
346 NULL,
347 NULL,
348 &StartupInfo,
349 ProcessInformation);
350
351 if (!CreateProcessResult)
352 {
353 ShowMessages("err, start process failed (%x)", GetLastError());
354 return FALSE;
355 }
356
357 return TRUE;
358}
int BOOL
Definition BasicTypes.h:25

◆ UdDetachProcess()

BOOLEAN UdDetachProcess ( UINT32 TargetPid,
UINT64 ProcessDetailToken )

Detach the target process.

this function will not check whether the process id and thread id is valid or not

Parameters
TargetPid
ProcessDetailToken
Returns
BOOLEAN
787{
788 BOOLEAN Status;
789 ULONG ReturnedLength;
791
792 //
793 // Check if the VMM module is loaded or not
794 //
796
797 //
798 // Send the continue command to the target process as we
799 // want to continue the debuggee process before detaching
800 //
801 UdContinueProcess(ProcessDetailToken);
802
803 //
804 // We wanna detach a process
805 //
807
808 //
809 // Set the process id
810 //
811 DetachRequest.ProcessId = TargetPid;
812
813 //
814 // Send the request to the kernel
815 //
816 Status = DeviceIoControl(
817 g_DeviceHandle, // Handle to device
819 // code
820 &DetachRequest, // Input Buffer to driver.
822 &DetachRequest, // Output Buffer from driver.
824 // buffer in bytes.
825 &ReturnedLength, // Bytes placed in buffer.
826 NULL // synchronous call
827 );
828
829 if (!Status)
830 {
831 ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
832 return FALSE;
833 }
834
835 //
836 // Check if detaching was successful or not
837 //
838 if (DetachRequest.Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
839 {
840 //
841 // Remove the current active debugging process (thread)
842 //
844
845 //
846 // The operation of attaching was successful
847 //
848 return TRUE;
849 }
850 else
851 {
852 ShowErrorMessage((UINT32)DetachRequest.Result);
853 return FALSE;
854 }
855}
@ DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_DETACH
Definition RequestStructures.h:665
VOID UdRemoveActiveDebuggingProcess()
Remove the current active debugging process (thread).
Definition ud.cpp:152
BOOLEAN UdContinueProcess(UINT64 ProcessDebuggingToken)
Continue the target process.
Definition ud.cpp:933

◆ UdDoesProcessExistByHandle()

BOOLEAN UdDoesProcessExistByHandle ( HANDLE TargetHandle)

Check if process exists or not by handle.

Parameters
TargetHandle
Returns
BOOLEAN
657{
658 DWORD exitCodeOut;
659
660 //
661 // GetExitCodeProcess returns zero on failure
662 //
663 if (GetExitCodeProcess(TargetHandle, &exitCodeOut) == 0)
664 {
665 //
666 // Optionally get the error
667 //
668 // DWORD error = GetLastError();
669 return FALSE;
670 }
671
672 //
673 // Return if the process is still active
674 //
675 return exitCodeOut == STILL_ACTIVE;
676}
unsigned long DWORD
Definition BasicTypes.h:38

◆ UdDoesProcessExistByPid()

BOOLEAN UdDoesProcessExistByPid ( DWORD TargetPid)

Check if process exists or not by process id.

Parameters
TargetPid
Returns
BOOLEAN
629{
630 if (HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, TargetPid))
631 {
632 DWORD ExitCodeOut;
633
634 //
635 // GetExitCodeProcess returns zero on failure
636 //
637 if (GetExitCodeProcess(process, &ExitCodeOut) != 0)
638 {
639 //
640 // Return if the process is still active
641 //
642 return ExitCodeOut == STILL_ACTIVE;
643 }
644 }
645 return FALSE;
646}

◆ UdInitializeUserDebugger()

VOID UdInitializeUserDebugger ( )

Initialize the user debugger in user mode.

initialize user debugger

Returns
VOID

this function should be called on vmx non-root

Returns
BOOLEAN
35{
37 {
38 //
39 // Initialize the handle table
40 //
42 {
44 g_UserSyncronizationObjectsHandleTable[i].EventHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
45 }
46
47 //
48 // To make it more convenient, we set not to continue the previous command
49 // after pressing enter , so the user can enter the command for the 'g' command
50 //
52
53 //
54 // Indicate that it's initialized
55 //
57 }
58}
#define DEBUGGER_COMMAND_ATTRIBUTE_REPEAT_ON_ENTER
Definition commands.h:216
CommandType g_CommandsList
List of command and attributes.
Definition globals.h:348
#define DEBUGGER_MAXIMUM_SYNCRONIZATION_USER_DEBUGGER_OBJECTS
Maximum number of event handles in user-debugger.
Definition debugger.h:96
DEBUGGER_SYNCRONIZATION_EVENTS_STATE g_UserSyncronizationObjectsHandleTable[DEBUGGER_MAXIMUM_SYNCRONIZATION_USER_DEBUGGER_OBJECTS]
In debugger (not debuggee), we save the handle of the user-mode listening thread for pauses here for ...
Definition globals.h:198
BOOLEAN g_IsUserDebuggerInitialized
Whether the user debugger is initialized or not.
Definition globals.h:189

◆ UdKillProcess()

BOOLEAN UdKillProcess ( UINT32 TargetPid)

Kill the target process from kernel.

this function will not check whether the process id and thread id is valid or not

Parameters
TargetPid
Returns
BOOLEAN
689{
690 BOOLEAN Status;
691 ULONG ReturnedLength;
693
694 //
695 // Check if VMM module is loaded or not
696 //
698
699 //
700 // Check if the process exists
701 //
702 if (!UdDoesProcessExistByPid(TargetPid))
703 {
704 return FALSE;
705 }
706
707 //
708 // First, we try to kill the process in user-mode, if not successful,
709 // we try to kill it from kernel-mode
710 //
711 UdTerminateProcessByPid(TargetPid);
712
713 //
714 // Check again to see if the process exists
715 //
716 if (!UdDoesProcessExistByPid(TargetPid))
717 {
718 return TRUE;
719 }
720
721 //
722 // We wanna kill a process
723 //
725
726 //
727 // Set the process id
728 //
729 KillRequest.ProcessId = TargetPid;
730
731 //
732 // Send the request to the kernel
733 //
734 Status = DeviceIoControl(
735 g_DeviceHandle, // Handle to device
737 // code
738 &KillRequest, // Input Buffer to driver.
740 &KillRequest, // Output Buffer from driver.
742 // buffer in bytes.
743 &ReturnedLength, // Bytes placed in buffer.
744 NULL // synchronous call
745 );
746
747 if (!Status)
748 {
749 ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
750 return FALSE;
751 }
752
753 //
754 // Check if killing was successful or not
755 //
756 if (KillRequest.Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
757 {
758 //
759 // Remove the current active debugging process (thread)
760 //
762
763 //
764 // The operation of attaching was successful
765 //
766 return TRUE;
767 }
768 else
769 {
770 ShowErrorMessage((UINT32)KillRequest.Result);
771 return FALSE;
772 }
773}
@ DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_KILL_PROCESS
Definition RequestStructures.h:667
BOOLEAN UdTerminateProcessByPid(DWORD TargetPid)
Check if process exists or not.
Definition ud.cpp:591
BOOLEAN UdDoesProcessExistByPid(DWORD TargetPid)
Check if process exists or not by process id.
Definition ud.cpp:628

◆ UdListProcessThreads()

BOOLEAN UdListProcessThreads ( DWORD OwnerPID)

List of threads by owner process id.

Parameters
OwnerPID
Returns
BOOLEAN if there was an error then returns false, otherwise return true
207{
208 HANDLE ThreadSnap = INVALID_HANDLE_VALUE;
209 THREADENTRY32 Te32;
210
211 //
212 // Take a snapshot of all running threads
213 //
214 ThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
215 if (ThreadSnap == INVALID_HANDLE_VALUE)
216 return FALSE;
217
218 //
219 // Fill in the size of the structure before using it
220 //
221 Te32.dwSize = sizeof(THREADENTRY32);
222
223 //
224 // Retrieve information about the first thread and exit if unsuccessful
225 //
226 if (!Thread32First(ThreadSnap, &Te32))
227 {
228 UdPrintError(); // Show cause of failure
229 CloseHandle(ThreadSnap); // Must clean up the snapshot object!
230 return FALSE;
231 }
232 ShowMessages("\nThread's of pid\t= 0x%08X\n", OwnerPID);
233
234 //
235 // Now walk the thread list of the system, and display information
236 // about each thread associated with the specified process
237 //
238 do
239 {
240 if (Te32.th32OwnerProcessID == OwnerPID)
241 {
242 ShowMessages("\n Thread Id\t= 0x%08X", Te32.th32ThreadID);
243 // ShowMessages("\n base priority = %x", Te32.tpBasePri);
244 // ShowMessages("\n delta priority = %x", Te32.tpDeltaPri);
245 }
246 } while (Thread32Next(ThreadSnap, &Te32));
247
248 ShowMessages("\n");
249
250 //
251 // Don't forget to clean up the snapshot object
252 //
253 CloseHandle(ThreadSnap);
254 return TRUE;
255}

◆ UdPauseProcess()

BOOLEAN UdPauseProcess ( UINT64 ProcessDebuggingToken)

Pause the target process.

Parameters
ProcessDebuggingToken
Returns
BOOLEAN
866{
867 BOOLEAN Status;
868 ULONG ReturnedLength;
870
871 //
872 // Check if the VMM module is loaded or not
873 //
875
876 //
877 // We wanna pause a process
878 //
880
881 //
882 // Set the process debugging token
883 //
884 PauseRequest.Token = ProcessDebuggingToken;
885
886 //
887 // Send the request to the kernel
888 //
889 Status = DeviceIoControl(
890 g_DeviceHandle, // Handle to device
892 // code
893 &PauseRequest, // Input Buffer to driver.
895 &PauseRequest, // Output Buffer from driver.
897 // buffer in bytes.
898 &ReturnedLength, // Bytes placed in buffer.
899 NULL // synchronous call
900 );
901
902 if (!Status)
903 {
904 ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
905 return FALSE;
906 }
907
908 //
909 // Check if pausing was successful or not
910 //
911 if (PauseRequest.Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
912 {
913 //
914 // The operation of attaching was successful
915 //
916 return TRUE;
917 }
918 else
919 {
920 ShowErrorMessage((UINT32)PauseRequest.Result);
921 return FALSE;
922 }
923}
@ DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_PAUSE_PROCESS
Definition RequestStructures.h:669

◆ UdPrintError()

VOID UdPrintError ( )

print error messages relating to the finding thread id

this function is used only in the scope of Thread32First

Returns
VOID
168{
169 DWORD ErrNum;
170 TCHAR SysMsg[256];
171 TCHAR * p;
172
173 ErrNum = GetLastError();
174 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
175 NULL,
176 ErrNum,
177 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
178 SysMsg,
179 256,
180 NULL);
181
182 //
183 // Trim the end of the line and terminate it with a null
184 //
185 p = SysMsg;
186 while ((*p > 31) || (*p == 9))
187 ++p;
188 do
189 {
190 *p-- = 0;
191 } while ((p >= SysMsg) && ((*p == '.') || (*p < 33)));
192
193 //
194 // Display the message
195 //
196 ShowMessages("\n WARNING: Thread32First failed with error (%x:%s)", ErrNum, SysMsg);
197}

◆ UdRemoveActiveDebuggingProcess()

VOID UdRemoveActiveDebuggingProcess ( )

Remove the current active debugging process (thread).

Returns
VOID
153{
154 //
155 // Activate the debugging
156 //
158}
ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
State of active debugging thread.
Definition globals.h:372

◆ UdSendCommand()

BOOLEAN UdSendCommand ( UINT64 ProcessDetailToken,
UINT32 ThreadId,
DEBUGGER_UD_COMMAND_ACTION_TYPE ActionType,
PVOID OptionalBuffer,
UINT32 OptionalBufferSize,
BOOLEAN ApplyToAllPausedThreads,
BOOLEAN WaitForEventCompletion,
UINT64 OptionalParam1,
UINT64 OptionalParam2,
UINT64 OptionalParam3,
UINT64 OptionalParam4 )

Send the command to the user debugger.

Parameters
ProcessDetailToken
ThreadId
ActionType
OptionalBuffer
OptionalBufferSize
ApplyToAllPausedThreads
WaitForEventCompletion
OptionalParam1
OptionalParam2
OptionalParam3
OptionalParam4
Returns
BOOLEAN
1021{
1022 BOOL Status;
1023 ULONG ReturnedLength;
1024 UINT32 TargetBufferSize = 0;
1025 DEBUGGER_UD_COMMAND_PACKET * CommandPacket;
1026
1028
1029 //
1030 // Calculate the target buffer size
1031 //
1032 if (OptionalBufferSize == 0)
1033 {
1034 TargetBufferSize = sizeof(DEBUGGER_UD_COMMAND_PACKET);
1035 }
1036 else
1037 {
1038 TargetBufferSize = sizeof(DEBUGGER_UD_COMMAND_PACKET) + OptionalBufferSize;
1039 }
1040
1041 //
1042 // Allocate the target buffer
1043 //
1044 CommandPacket = (DEBUGGER_UD_COMMAND_PACKET *)malloc(TargetBufferSize);
1045
1046 if (CommandPacket == NULL)
1047 {
1048 ShowMessages("err, unable to allocate memory for command\n");
1049 return FALSE;
1050 }
1051
1052 //
1053 // Zero the packet
1054 //
1055 RtlZeroMemory(CommandPacket, TargetBufferSize);
1056
1057 //
1058 // Set to the details
1059 //
1060 CommandPacket->ProcessDebuggingDetailToken = ProcessDetailToken;
1061 CommandPacket->ApplyToAllPausedThreads = ApplyToAllPausedThreads;
1062 CommandPacket->TargetThreadId = ThreadId;
1063 CommandPacket->WaitForEventCompletion = WaitForEventCompletion;
1064 CommandPacket->UdAction.ActionType = ActionType;
1065 CommandPacket->UdAction.OptionalParam1 = OptionalParam1;
1066 CommandPacket->UdAction.OptionalParam2 = OptionalParam2;
1067 CommandPacket->UdAction.OptionalParam3 = OptionalParam3;
1068 CommandPacket->UdAction.OptionalParam4 = OptionalParam4;
1069
1070 //
1071 // Copy the optional buffer if it's present
1072 //
1073 if (OptionalBuffer != NULL && OptionalBufferSize != 0)
1074 {
1075 //
1076 // Append the optional buffer to the command packet buffer
1077 //
1078 memcpy((PVOID)((UINT8 *)CommandPacket + sizeof(DEBUGGER_UD_COMMAND_PACKET)), OptionalBuffer, OptionalBufferSize);
1079 }
1080
1081 //
1082 // Send IOCTL
1083 //
1084 Status = DeviceIoControl(g_DeviceHandle, // Handle to device
1085 IOCTL_SEND_USER_DEBUGGER_COMMANDS, // IO Control Code (IOCTL)
1086 CommandPacket, // Input Buffer to driver.
1087 TargetBufferSize, // Input buffer length
1088 CommandPacket, // Output Buffer from driver.
1089 TargetBufferSize, // Length of output buffer in bytes.
1090 &ReturnedLength, // Bytes placed in buffer.
1091 NULL // synchronous call
1092 );
1093
1094 if (!Status)
1095 {
1096 ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
1097
1098 free(CommandPacket);
1099 return FALSE;
1100 }
1101
1102 if (CommandPacket->Result != DEBUGGER_OPERATION_WAS_SUCCESSFUL)
1103 {
1104 ShowErrorMessage((UINT32)CommandPacket->Result);
1105
1106 free(CommandPacket);
1107 return FALSE;
1108 }
1109
1110 //
1111 // Copy the result of optional buffer to the caller buffer
1112 //
1113 if (OptionalBuffer != NULL && OptionalBufferSize != 0)
1114 {
1115 //
1116 // Append the optional buffer to the command packet buffer
1117 //
1118 memcpy(OptionalBuffer,
1119 (PVOID)((UINT8 *)CommandPacket + sizeof(DEBUGGER_UD_COMMAND_PACKET)),
1120 OptionalBufferSize);
1121 }
1122
1123 //
1124 // Free the allocated buffer
1125 //
1126 free(CommandPacket);
1127
1128 return TRUE;
1129}
void * PVOID
Definition BasicTypes.h:56
unsigned char UINT8
Definition BasicTypes.h:52
#define IOCTL_SEND_USER_DEBUGGER_COMMANDS
ioctl, to send user debugger commands
Definition Ioctls.h:284
struct _DEBUGGER_UD_COMMAND_PACKET DEBUGGER_UD_COMMAND_PACKET
The structure of command packet in uHyperDbg.
DEBUGGER_UD_COMMAND_ACTION_TYPE ActionType
Definition RequestStructures.h:934
UINT64 OptionalParam1
Definition RequestStructures.h:935
UINT64 OptionalParam3
Definition RequestStructures.h:937
UINT64 OptionalParam4
Definition RequestStructures.h:938
UINT64 OptionalParam2
Definition RequestStructures.h:936
DEBUGGER_UD_COMMAND_ACTION UdAction
Definition RequestStructures.h:948
UINT32 TargetThreadId
Definition RequestStructures.h:950
UINT32 Result
Definition RequestStructures.h:953
BOOLEAN ApplyToAllPausedThreads
Definition RequestStructures.h:951
BOOLEAN WaitForEventCompletion
Definition RequestStructures.h:952
UINT64 ProcessDebuggingDetailToken
Definition RequestStructures.h:949

◆ UdSendReadRegisterToUserDebugger()

BOOLEAN UdSendReadRegisterToUserDebugger ( UINT64 ProcessDetailToken,
UINT32 TargetThreadId,
PDEBUGGEE_REGISTER_READ_DESCRIPTION RegDes,
UINT32 RegBuffSize )

Send the command to the user debugger.

Parameters
ProcessDetailToken
TargetThreadId
RegDes
RegBuffSize
Returns
BOOLEAN
1147{
1148 //
1149 // Send the read register command
1150 //
1151 return UdSendCommand(ProcessDetailToken,
1152 TargetThreadId,
1154 RegDes,
1155 RegBuffSize,
1156 FALSE,
1157 TRUE,
1158 RegDes->RegisterId,
1159 NULL,
1160 NULL,
1161 NULL);
1162}
@ DEBUGGER_UD_COMMAND_ACTION_TYPE_READ_REGISTERS
Definition RequestStructures.h:923
UINT32 RegisterId
Definition RequestStructures.h:1617
BOOLEAN UdSendCommand(UINT64 ProcessDetailToken, UINT32 ThreadId, DEBUGGER_UD_COMMAND_ACTION_TYPE ActionType, PVOID OptionalBuffer, UINT32 OptionalBufferSize, BOOLEAN ApplyToAllPausedThreads, BOOLEAN WaitForEventCompletion, UINT64 OptionalParam1, UINT64 OptionalParam2, UINT64 OptionalParam3, UINT64 OptionalParam4)
Send the command to the user debugger.
Definition ud.cpp:1010

◆ UdSendScriptBufferToProcess()

BOOLEAN UdSendScriptBufferToProcess ( UINT64 ProcessDetailToken,
UINT32 TargetThreadId,
UINT64 BufferAddress,
UINT32 BufferLength,
UINT32 Pointer,
BOOLEAN IsFormat )

Send script buffer to the user debugger.

Parameters
ProcessDetailToken
TargetThreadId
BufferAddress
BufferLength
Pointer
Returns
BOOLEAN
1183{
1184 PDEBUGGEE_SCRIPT_PACKET ScriptPacket;
1185 UINT32 SizeOfStruct = 0;
1186 BOOLEAN Result = FALSE;
1187
1188 SizeOfStruct = sizeof(DEBUGGEE_SCRIPT_PACKET) + BufferLength;
1189
1190 ScriptPacket = (DEBUGGEE_SCRIPT_PACKET *)malloc(SizeOfStruct);
1191
1192 RtlZeroMemory(ScriptPacket, SizeOfStruct);
1193
1194 //
1195 // Fill the script packet buffer
1196 //
1197 ScriptPacket->ScriptBufferSize = BufferLength;
1198 ScriptPacket->ScriptBufferPointer = Pointer;
1199 ScriptPacket->IsFormat = IsFormat;
1200
1201 //
1202 // Move the buffer at the bottom of the script packet
1203 //
1204 memcpy((PVOID)((UINT64)ScriptPacket + sizeof(DEBUGGEE_SCRIPT_PACKET)),
1205 (PVOID)BufferAddress,
1206 BufferLength);
1207
1208 //
1209 // Send the script buffer command
1210 //
1211 Result = UdSendCommand(ProcessDetailToken,
1212 TargetThreadId,
1214 ScriptPacket,
1215 SizeOfStruct,
1216 FALSE,
1217 TRUE,
1218 NULL,
1219 NULL,
1220 NULL,
1221 NULL);
1222
1223 //
1224 // Check if it's a format expression and if there was an error or not
1225 //
1226 if (IsFormat && Result)
1227 {
1230 }
1231
1232 free(ScriptPacket);
1233
1234 return Result;
1235}
struct _DEBUGGEE_SCRIPT_PACKET * PDEBUGGEE_SCRIPT_PACKET
struct _DEBUGGEE_SCRIPT_PACKET DEBUGGEE_SCRIPT_PACKET
The structure of script packet in HyperDbg.
@ DEBUGGER_UD_COMMAND_ACTION_TYPE_EXECUTE_SCRIPT_BUFFER
Definition RequestStructures.h:924
UINT64 g_ResultOfEvaluatedExpression
Result of the expression that is evaluated in the debuggee.
Definition globals.h:640
UINT32 g_ErrorStateOfResultOfEvaluatedExpression
Shows the state of the evaluation of expression which whether contains error or not.
Definition globals.h:647
BOOLEAN IsFormat
Definition RequestStructures.h:1586
UINT32 ScriptBufferPointer
Definition RequestStructures.h:1585
UINT32 ScriptBufferSize
Definition RequestStructures.h:1584
UINT64 FormatValue
Definition RequestStructures.h:1587

◆ UdSendStepPacketToDebuggee()

BOOLEAN UdSendStepPacketToDebuggee ( UINT64 ProcessDetailToken,
UINT32 TargetThreadId,
DEBUGGER_REMOTE_STEPPING_REQUEST StepType )

Send stepping instructions packet to user debugger.

Parameters
ProcessDetailToken
TargetThreadId
StepType
Returns
BOOLEAN
1249{
1250 BOOLEAN IsCurrentInstructionACall = FALSE;
1251 UINT32 CallInstructionSize = 0;
1252
1253 //
1254 // Check for specific stepping type
1255 //
1257 {
1258 //
1259 // We should check whether the current instruction is a 'call'
1260 // instruction or not, if yes we have to compute the length of call
1261 //
1263 (UCHAR *)&g_ActiveProcessDebuggingState.InstructionBytesOnRip[0],
1265 g_ActiveProcessDebuggingState.Is32Bit ? FALSE : TRUE, // equals to !g_IsRunningInstruction32Bit
1266 &CallInstructionSize))
1267 {
1268 //
1269 // It's a call in step-over
1270 //
1271 IsCurrentInstructionACall = TRUE;
1272 CallInstructionSize = CallInstructionSize;
1273 }
1274 }
1275
1276 //
1277 // Send the 'step' command
1278 //
1279 if (UdSendCommand(ProcessDetailToken,
1280 TargetThreadId,
1282 NULL,
1283 0,
1284 FALSE,
1285 FALSE,
1286 StepType,
1287 IsCurrentInstructionACall,
1288 CallInstructionSize,
1289 NULL))
1290 {
1291 //
1292 // Wait until the result of user-input received
1293 //
1295
1296 return TRUE;
1297 }
1298
1299 //
1300 // An error happened
1301 //
1302 return FALSE;
1303}
unsigned char UCHAR
Definition BasicTypes.h:34
#define MAXIMUM_INSTR_SIZE
maximum instruction size in Intel
Definition Constants.h:470
@ DEBUGGER_REMOTE_STEPPING_REQUEST_STEP_OVER
Definition RequestStructures.h:1050
@ DEBUGGER_UD_COMMAND_ACTION_TYPE_REGULAR_STEP
Definition RequestStructures.h:922
BOOLEAN HyperDbgCheckWhetherTheCurrentInstructionIsCall(UCHAR *BufferToDisassemble, UINT64 BuffLength, BOOLEAN Isx86_64, PUINT32 CallLength)
Check whether the current instruction is a 'call' or not.
Definition disassembler.cpp:755
#define DbgWaitForUserResponse(UserSyncObjectId)
Definition common.h:109
#define DEBUGGER_SYNCRONIZATION_OBJECT_USER_DEBUGGER_IS_DEBUGGER_RUNNING
An event to show whether the debugger is running or not in user-debugger.
Definition debugger.h:107

◆ UdSetActiveDebuggingProcess()

VOID UdSetActiveDebuggingProcess ( UINT64 DebuggingId,
UINT64 Rip,
UINT32 ProcessId,
UINT32 ThreadId,
BOOLEAN Is32Bit,
BOOLEAN IsPaused,
BYTE InstructionBytesOnRip[] )

set the current active debugging process (thread)

Parameters
DebuggingId
Rip
ProcessId
ThreadId
Is32Bit
InstructionBytesOnRip
Returns
VOID
119{
120 //
121 // Activate the debugging
122 //
124
125 //
126 // Set the details
127 //
128 g_ActiveProcessDebuggingState.ProcessId = ProcessId;
129 g_ActiveProcessDebuggingState.ThreadId = ThreadId;
130 g_ActiveProcessDebuggingState.Is32Bit = Is32Bit;
132
133 g_ActiveProcessDebuggingState.ProcessDebuggingToken = DebuggingId;
134
135 //
136 // Set current instruction
137 //
138 memcpy(&g_ActiveProcessDebuggingState.InstructionBytesOnRip[0], &InstructionBytesOnRip[0], MAXIMUM_INSTR_SIZE);
139
140 //
141 // Set pausing state
142 //
143 g_ActiveProcessDebuggingState.IsPaused = IsPaused;
144}

◆ UdSetActiveDebuggingThreadByPidOrTid()

BOOLEAN UdSetActiveDebuggingThreadByPidOrTid ( UINT32 TargetPidOrTid,
BOOLEAN IsTid )

Set the active debugging thread by process id or thread id.

Parameters
TargetPidOrTid
IsTid
Returns
BOOLEAN
1315{
1316 BOOLEAN Status;
1317 ULONG ReturnedLength;
1318 DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS SwitchRequest = {0};
1319
1320 //
1321 // Check if the VMM module is loaded or not
1322 //
1324
1325 //
1326 // We wanna switch to a process or thread
1327 //
1329
1330 //
1331 // Set the process id or thread id
1332 //
1333 if (IsTid)
1334 {
1335 SwitchRequest.ThreadId = TargetPidOrTid;
1336 }
1337 else
1338 {
1339 SwitchRequest.ProcessId = TargetPidOrTid;
1340 }
1341
1342 //
1343 // Send the request to the kernel
1344 //
1345 Status = DeviceIoControl(
1346 g_DeviceHandle, // Handle to device
1348 &SwitchRequest, // Input Buffer to driver.
1350 &SwitchRequest, // Output Buffer from driver.
1352 // buffer in bytes.
1353 &ReturnedLength, // Bytes placed in buffer.
1354 NULL // synchronous call
1355 );
1356
1357 if (!Status)
1358 {
1359 ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
1360 return FALSE;
1361 }
1362
1363 //
1364 // Check if killing was successful or not
1365 //
1366 if (SwitchRequest.Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
1367 {
1368 //
1369 // Set the current active debugging process (thread)
1370 //
1371 UdSetActiveDebuggingProcess(SwitchRequest.Token,
1372 SwitchRequest.Rip,
1373 SwitchRequest.ProcessId,
1374 SwitchRequest.ThreadId,
1375 SwitchRequest.Is32Bit,
1376 SwitchRequest.IsPaused,
1377 SwitchRequest.InstructionBytesOnRip);
1378
1379 //
1380 // The operation of attaching was successful
1381 //
1382 return TRUE;
1383 }
1384 else
1385 {
1386 ShowErrorMessage((UINT32)SwitchRequest.Result);
1387 return FALSE;
1388 }
1389}
@ DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_SWITCH_BY_PROCESS_OR_THREAD
Definition RequestStructures.h:670
BYTE InstructionBytesOnRip[MAXIMUM_INSTR_SIZE]
Definition RequestStructures.h:687
BOOLEAN IsPaused
Definition RequestStructures.h:689
BOOLEAN Is32Bit
Definition RequestStructures.h:685
UINT64 Rip
Definition RequestStructures.h:686
VOID UdSetActiveDebuggingProcess(UINT64 DebuggingId, UINT64 Rip, UINT32 ProcessId, UINT32 ThreadId, BOOLEAN Is32Bit, BOOLEAN IsPaused, BYTE InstructionBytesOnRip[])
set the current active debugging process (thread)
Definition ud.cpp:112

◆ UdShowListActiveDebuggingProcessesAndThreads()

BOOLEAN UdShowListActiveDebuggingProcessesAndThreads ( )

Show list of active debugging processes and threads.

Returns
BOOLEAN
1398{
1399 BOOLEAN Status;
1400 BOOLEAN CheckCurrentProcessOrThread;
1401 ULONG ReturnedLength;
1402 DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS QueryCountOfActiveThreadsRequest = {0};
1403 USERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS * AddressOfThreadsAndProcessDetails = NULL;
1404 UINT32 SizeOfBufferForThreadsAndProcessDetails = NULL;
1405
1406 //
1407 // Check if the VMM module is loaded or not
1408 //
1410
1411 //
1412 // Check if user debugger is active or not
1413 //
1415 {
1416 ShowMessages("user debugger is not initialized. Did you use the '.attach' or the '.start' "
1417 "command before?\n");
1418 return FALSE;
1419 }
1420
1421 //
1422 // We wanna query the count of active debugging threads
1423 //
1425
1426 //
1427 // Send the request to the kernel
1428 //
1429 Status = DeviceIoControl(
1430 g_DeviceHandle, // Handle to device
1432 // code
1433 &QueryCountOfActiveThreadsRequest, // Input Buffer to driver.
1435 &QueryCountOfActiveThreadsRequest, // Output Buffer from driver.
1437 // buffer in bytes.
1438 &ReturnedLength, // Bytes placed in buffer.
1439 NULL // synchronous call
1440 );
1441
1442 if (!Status)
1443 {
1444 ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
1445 return FALSE;
1446 }
1447
1448 //
1449 // Query was successful
1450 //
1451 if (QueryCountOfActiveThreadsRequest.Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
1452 {
1453 if (QueryCountOfActiveThreadsRequest.CountOfActiveDebuggingThreadsAndProcesses == 0)
1454 {
1455 ShowMessages("no active debugging threads!\n");
1456 }
1457 else
1458 {
1459 //
1460 // *** We should send another IOCTL and get the list of threads ***
1461 //
1462
1463 //
1464 // Allocate the storage for the pull details of threads and processes
1465 //
1466 SizeOfBufferForThreadsAndProcessDetails =
1468
1469 AddressOfThreadsAndProcessDetails = (USERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS *)malloc(SizeOfBufferForThreadsAndProcessDetails);
1470
1471 if (AddressOfThreadsAndProcessDetails == NULL64_ZERO)
1472 {
1473 ShowMessages("insufficient space\n");
1474 return FALSE;
1475 }
1476
1477 RtlZeroMemory(AddressOfThreadsAndProcessDetails, SizeOfBufferForThreadsAndProcessDetails);
1478
1479 //
1480 // Send the request to the kernel
1481 //
1482 Status = DeviceIoControl(
1483 g_DeviceHandle, // Handle to device
1485 // code
1486 NULL, // Input Buffer to driver.
1487 0, // Input buffer length.
1488 AddressOfThreadsAndProcessDetails, // Output Buffer from driver.
1489 SizeOfBufferForThreadsAndProcessDetails, // Length of output buffer in bytes.
1490 &ReturnedLength, // Bytes placed in buffer.
1491 NULL // synchronous call
1492 );
1493
1494 if (!Status)
1495 {
1496 ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
1497 return FALSE;
1498 }
1499
1500 //
1501 // Show list of active processes and threads
1502 //
1503 for (SIZE_T i = 0; i < QueryCountOfActiveThreadsRequest.CountOfActiveDebuggingThreadsAndProcesses; i++)
1504 {
1505 if (AddressOfThreadsAndProcessDetails[i].IsProcess)
1506 {
1507 CheckCurrentProcessOrThread = FALSE;
1508
1509 if (g_ActiveProcessDebuggingState.IsActive && AddressOfThreadsAndProcessDetails[i].ProcessId == g_ActiveProcessDebuggingState.ProcessId)
1510 {
1511 CheckCurrentProcessOrThread = TRUE;
1512 }
1513
1514 ShowMessages("%s%04x (process)\n",
1515 CheckCurrentProcessOrThread ? "*" : "",
1516 AddressOfThreadsAndProcessDetails[i].ProcessId);
1517 }
1518 else
1519 {
1520 CheckCurrentProcessOrThread = FALSE;
1521
1522 if (g_ActiveProcessDebuggingState.IsActive && AddressOfThreadsAndProcessDetails[i].ThreadId == g_ActiveProcessDebuggingState.ThreadId)
1523 {
1524 CheckCurrentProcessOrThread = TRUE;
1525 }
1526 ShowMessages("\t%s %04x (thread) | # blkd exec attempts: %llx\n",
1527 CheckCurrentProcessOrThread ? "->" : " ",
1528 AddressOfThreadsAndProcessDetails[i].ThreadId,
1529 AddressOfThreadsAndProcessDetails[i].NumberOfBlockedContextSwitches);
1530 }
1531 }
1532 }
1533
1534 //
1535 // The operation of attaching was successful
1536 //
1537 return TRUE;
1538 }
1539 else
1540 {
1541 ShowErrorMessage((UINT32)QueryCountOfActiveThreadsRequest.Result);
1542 return FALSE;
1543 }
1544}
#define IOCTL_GET_DETAIL_OF_ACTIVE_THREADS_AND_PROCESSES
ioctl, to get active threads/processes that are debugging
Definition Ioctls.h:291
#define SIZEOF_USERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS
Definition RequestStructures.h:860
struct _USERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS USERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS
@ DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_QUERY_COUNT_OF_ACTIVE_DEBUGGING_THREADS
Definition RequestStructures.h:671
NULL()
Definition test-case-generator.py:530
UINT32 CountOfActiveDebuggingThreadsAndProcesses
Definition RequestStructures.h:691

◆ UdTerminateProcessByPid()

BOOLEAN UdTerminateProcessByPid ( DWORD TargetPid)

Check if process exists or not.

Parameters
TargetPid
Returns
BOOLEAN
592{
593 BOOL Terminated = FALSE;
594
595 //
596 // Attempt to open a handle to the process with PROCESS_TERMINATE access rights
597 //
598 HANDLE Handle = OpenProcess(PROCESS_TERMINATE, FALSE, TargetPid);
599 if (Handle == NULL)
600 {
601 //
602 // Failed to open the process, which likely means it does not exist or access is denied
603 //
604 return FALSE;
605 }
606
607 //
608 // Terminate the process
609 //
610 Terminated = TerminateProcess(Handle, 0);
611
612 //
613 // Close the process handle
614 //
615 CloseHandle(Handle);
616
617 return Terminated;
618}

◆ UdUninitializeUserDebugger()

VOID UdUninitializeUserDebugger ( )

Uninitialize the user debugger in user mode.

uninitialize user debugger

Returns
VOID

this function should be called on vmx non-root

Returns
VOID
68{
70 {
71 //
72 // Remove the active process
73 //
75
76 //
77 // Initialize the handle table
78 //
80 {
81 if (g_UserSyncronizationObjectsHandleTable[i].EventHandle != NULL)
82 {
83 if (g_UserSyncronizationObjectsHandleTable[i].IsOnWaitingState)
84 {
86 }
87
88 CloseHandle(g_UserSyncronizationObjectsHandleTable[i].EventHandle);
90 }
91 }
92
93 //
94 // Indicate that user debugger is not initialized
95 //
97 }
98}
#define DbgReceivedUserResponse(UserSyncObjectId)
Definition common.h:178

Variable Documentation

◆ g_ActiveProcessDebuggingState

ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
extern

State of active debugging thread.

372{0};

◆ g_CommandsList

CommandType g_CommandsList
extern

List of command and attributes.

◆ g_ErrorStateOfResultOfEvaluatedExpression

UINT32 g_ErrorStateOfResultOfEvaluatedExpression
extern

Shows the state of the evaluation of expression which whether contains error or not.

◆ g_IsUserDebuggerInitialized

BOOLEAN g_IsUserDebuggerInitialized
extern

Whether the user debugger is initialized or not.

◆ g_IsVmmModuleLoaded

BOOLEAN g_IsVmmModuleLoaded
extern

shows whether the VMM module is loaded or not

◆ g_ProcessIdOfLatestStartingProcess

UINT32 g_ProcessIdOfLatestStartingProcess
extern

The process id of the latest starting process.

◆ g_ResultOfEvaluatedExpression

UINT64 g_ResultOfEvaluatedExpression
extern

Result of the expression that is evaluated in the debuggee.

◆ g_UserSyncronizationObjectsHandleTable

In debugger (not debuggee), we save the handle of the user-mode listening thread for pauses here for user debugger.

198{0};