diff --git a/hyperdbg/hprdbgctrl/code/objects/objects.cpp b/hyperdbg/hprdbgctrl/code/objects/objects.cpp index cceb2698..908e3ca3 100644 --- a/hyperdbg/hprdbgctrl/code/objects/objects.cpp +++ b/hyperdbg/hprdbgctrl/code/objects/objects.cpp @@ -70,11 +70,11 @@ ObjectShowProcessesOrThreadList(BOOLEAN IsProcess, UINT64 Eprocess, PDEBUGGEE_THREAD_LIST_NEEDED_DETAILS SymDetailsForThreadList) { - BOOLEAN Status; - ULONG ReturnedLength; - DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS QueryCountOfActiveThreadsOrProcessesRequest = {0}; - UINT32 SizeOfBufferForThreadsAndProcessDetails = NULL; - DEBUGGER_ACTIVE_PROCESS_OR_THREADS_DETAILS * ThreadsOrProcessDetails = NULL; + BOOLEAN Status; + ULONG ReturnedLength; + DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS QueryCountOfActiveThreadsOrProcessesRequest = {0}; + UINT32 SizeOfBufferForThreadsAndProcessDetails = NULL; + PDEBUGGEE_PROCESS_LIST_DETAILS_ENTRY ProcessEntries; // // Check if driver is loaded @@ -168,29 +168,45 @@ ObjectShowProcessesOrThreadList(BOOLEAN IsProcess, // // Allocate the storage for the pull details of threads and processes // - SizeOfBufferForThreadsAndProcessDetails = - QueryCountOfActiveThreadsOrProcessesRequest.Count * SIZEOF_DEBUGGER_ACTIVE_PROCESS_OR_THREADS_DETAILS; + if (IsProcess) + { + SizeOfBufferForThreadsAndProcessDetails = + QueryCountOfActiveThreadsOrProcessesRequest.Count * sizeof(DEBUGGEE_PROCESS_LIST_DETAILS_ENTRY); + } + else + { + // + // To be filled ! + // + } - ThreadsOrProcessDetails = (DEBUGGER_ACTIVE_PROCESS_OR_THREADS_DETAILS *)malloc(SizeOfBufferForThreadsAndProcessDetails); + ProcessEntries = (DEBUGGEE_PROCESS_LIST_DETAILS_ENTRY *)malloc(SizeOfBufferForThreadsAndProcessDetails); - RtlZeroMemory(ThreadsOrProcessDetails, SizeOfBufferForThreadsAndProcessDetails); + RtlZeroMemory(ProcessEntries, SizeOfBufferForThreadsAndProcessDetails); - ShowMessages("count of active processes/threads : %lld\n", QueryCountOfActiveThreadsOrProcessesRequest.Count); - return TRUE; + // ShowMessages("count of active processes/threads : %lld\n", QueryCountOfActiveThreadsOrProcessesRequest.Count); + + if (IsProcess) + { + QueryCountOfActiveThreadsOrProcessesRequest.QueryType = DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_QUERY_PROCESS_LIST; + } + else + { + QueryCountOfActiveThreadsOrProcessesRequest.QueryType = DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_QUERY_THREAD_LIST; + } // // Send the request to the kernel // Status = DeviceIoControl( - g_DeviceHandle, // Handle to device - IOCTL_GET_LIST_OF_THREADS_AND_PROCESSES, // IO Control - // code - NULL, // Input Buffer to driver. - 0, // Input buffer length. - ThreadsOrProcessDetails, // Output Buffer from driver. - SizeOfBufferForThreadsAndProcessDetails, // Length of output buffer in bytes. - &ReturnedLength, // Bytes placed in buffer. - NULL // synchronous call + g_DeviceHandle, // Handle to device + IOCTL_GET_LIST_OF_THREADS_AND_PROCESSES, // IO Control code + &QueryCountOfActiveThreadsOrProcessesRequest, // Input Buffer to driver. + SIZEOF_DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS, // Input buffer length + ProcessEntries, // Output Buffer from driver. + SizeOfBufferForThreadsAndProcessDetails, // Length of output buffer in bytes. + &ReturnedLength, // Bytes placed in buffer. + NULL // synchronous call ); if (!Status) @@ -207,6 +223,14 @@ ObjectShowProcessesOrThreadList(BOOLEAN IsProcess, // // Details of process should be shown // + if (ProcessEntries[i].Eprocess != NULL) + { + ShowMessages("PROCESS\t%llx\n\tProcess Id: %04x\tDirBase (Kernel Cr3): %016llx\tImage: %s\n\n", + ProcessEntries[i].Eprocess, + ProcessEntries[i].Pid, + ProcessEntries[i].Cr3, + ProcessEntries[i].ImageFileName); + } } } diff --git a/hyperdbg/hprdbghv/code/debugger/objects/Process.c b/hyperdbg/hprdbghv/code/debugger/objects/Process.c index 3698fb12..ebb02fd8 100644 --- a/hyperdbg/hprdbghv/code/debugger/objects/Process.c +++ b/hyperdbg/hprdbghv/code/debugger/objects/Process.c @@ -311,20 +311,49 @@ ProcessCheckIfEprocessIsValid(UINT64 Eprocess, UINT64 ActiveProcessHead, ULONG A * @param PorcessListSymbolInfo * @param QueryAction * @param CountOfProcesses + * @param ListSaveBuffer + * @param ListSaveBuffSize * * @return BOOLEAN */ BOOLEAN ProcessShowList(PDEBUGGEE_PROCESS_LIST_NEEDED_DETAILS PorcessListSymbolInfo, DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_ACTIONS QueryAction, - UINT32 * CountOfProcesses) + UINT32 * CountOfProcesses, + PVOID ListSaveBuffer, + UINT64 ListSaveBuffSize) { - UINT64 Process; - UINT64 UniquePid; - LIST_ENTRY ActiveProcessLinks; - UCHAR ImageFileName[15] = {0}; - CR3_TYPE ProcessCr3 = {0}; - UINT32 EnumerationCount = 0; + UINT64 Process; + UINT64 UniquePid; + LIST_ENTRY ActiveProcessLinks; + UCHAR ImageFileName[15] = {0}; + CR3_TYPE ProcessCr3 = {0}; + UINT32 EnumerationCount = 0; + UINT32 MaximumBufferCount = 0; + PDEBUGGEE_PROCESS_LIST_DETAILS_ENTRY SavingEntries = ListSaveBuffer; + + // + // validate parameters + // + if (QueryAction == DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_ACTION_QUERY_COUNT && + CountOfProcesses == NULL) + { + return FALSE; + } + + if (QueryAction == DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_ACTION_QUERY_SAVE_DETAILS && + (ListSaveBuffer == NULL || ListSaveBuffSize == 0)) + { + return FALSE; + } + + // + // compute size to avoid overflow + // + if (QueryAction == DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_ACTION_QUERY_SAVE_DETAILS) + { + MaximumBufferCount = ListSaveBuffSize / sizeof(DEBUGGEE_PROCESS_LIST_DETAILS_ENTRY); + } // // Set the details derived from the symbols @@ -405,6 +434,27 @@ ProcessShowList(PDEBUGGEE_PROCESS_LIST_NEEDED_DETAILS PorcessListSy case DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_ACTION_QUERY_SAVE_DETAILS: + EnumerationCount++; + + // + // Check to avoid overflow + // + if (EnumerationCount == MaximumBufferCount - 1) + { + // + // buffer is full + // + goto ReturnEnd; + } + + // + // Save the details + // + SavingEntries[EnumerationCount - 1].Eprocess = Process; + SavingEntries[EnumerationCount - 1].Pid = UniquePid; + SavingEntries[EnumerationCount - 1].Cr3 = ProcessCr3.Flags; + RtlCopyMemory(&SavingEntries[EnumerationCount - 1].ImageFileName, ImageFileName, 15); + break; default: @@ -429,6 +479,8 @@ ProcessShowList(PDEBUGGEE_PROCESS_LIST_NEEDED_DETAILS PorcessListSy return FALSE; } +ReturnEnd: + // // In case of query count of processes, we'll set this parameter // @@ -494,6 +546,8 @@ ProcessInterpretProcess(PDEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET PidRequest) // if (!ProcessShowList(&PidRequest->ProcessListSymDetails, DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_ACTION_SHOW_INSTANTLY, + NULL, + NULL, NULL)) { PidRequest->Result = DEBUGGER_ERROR_DETAILS_OR_SWITCH_PROCESS_INVALID_PARAMETER; @@ -531,7 +585,7 @@ ProcessInterpretProcess(PDEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET PidRequest) } /** - * @brief Query process details + * @brief Query process details (count) * * @param DebuggerUsermodeProcessOrThreadQueryRequest * @@ -547,7 +601,9 @@ ProcessQueryCount(PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS DebuggerUsermodePr // Result = ProcessShowList(&DebuggerUsermodeProcessOrThreadQueryRequest->ProcessListNeededDetails, DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_ACTION_QUERY_COUNT, - &DebuggerUsermodeProcessOrThreadQueryRequest->Count); + &DebuggerUsermodeProcessOrThreadQueryRequest->Count, + NULL, + NULL); if (Result && DebuggerUsermodeProcessOrThreadQueryRequest->Count != 0) { @@ -558,3 +614,31 @@ ProcessQueryCount(PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS DebuggerUsermodePr DebuggerUsermodeProcessOrThreadQueryRequest->Result = DEBUGGER_ERROR_UNABLE_TO_QUERY_COUNT_OF_PROCESSES_OR_THREADS; return FALSE; } + +/** + * @brief Query process details (list) + * + * @param DebuggerUsermodeProcessOrThreadQueryRequest + * @param AddressToSaveDetail + * @param BufferSize + * + * @return BOOLEAN + */ +BOOLEAN +ProcessQueryList(PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS DebuggerUsermodeProcessOrThreadQueryRequest, + PVOID AddressToSaveDetail, + UINT32 BufferSize) +{ + BOOLEAN Result = FALSE; + + // + // Getting the count results + // + Result = ProcessShowList(&DebuggerUsermodeProcessOrThreadQueryRequest->ProcessListNeededDetails, + DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_ACTION_QUERY_SAVE_DETAILS, + NULL, + AddressToSaveDetail, + BufferSize); + + return Result; +} diff --git a/hyperdbg/hprdbghv/code/driver/Ioctl.c b/hyperdbg/hprdbghv/code/driver/Ioctl.c index be619b14..f02bb045 100644 --- a/hyperdbg/hprdbghv/code/driver/Ioctl.c +++ b/hyperdbg/hprdbghv/code/driver/Ioctl.c @@ -1281,6 +1281,60 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) break; + case IOCTL_GET_LIST_OF_THREADS_AND_PROCESSES: + + // + // First validate the parameters. + // + if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS) || + Irp->AssociatedIrp.SystemBuffer == NULL) + { + Status = STATUS_INVALID_PARAMETER; + LogError("Err, invalid parameter to IOCTL dispatcher"); + break; + } + + InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; + OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; + + if (!InBuffLength || !OutBuffLength) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + + // + // Both usermode and to send to usermode and the comming buffer are + // at the same place + // + DebuggerUsermodeProcessOrThreadQueryRequest = (PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS)Irp->AssociatedIrp.SystemBuffer; + + // + // Getting the list of processes or threads + // + if (DebuggerUsermodeProcessOrThreadQueryRequest->QueryType == + DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_QUERY_PROCESS_LIST) + { + ProcessQueryList(DebuggerUsermodeProcessOrThreadQueryRequest, + DebuggerUsermodeProcessOrThreadQueryRequest, + OutBuffLength); + } + else if (DebuggerUsermodeProcessOrThreadQueryRequest->QueryType == + DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_QUERY_THREAD_LIST) + { + ThreadQueryCount(DebuggerUsermodeProcessOrThreadQueryRequest); + } + + Irp->IoStatus.Information = OutBuffLength; + Status = STATUS_SUCCESS; + + // + // Avoid zeroing it + // + DoNotChangeInformation = TRUE; + + break; + default: LogError("Err, unknown IOCTL"); Status = STATUS_NOT_IMPLEMENTED; diff --git a/hyperdbg/hprdbghv/header/debugger/objects/Process.h b/hyperdbg/hprdbghv/header/debugger/objects/Process.h index 2554ea84..6d28dd50 100644 --- a/hyperdbg/hprdbghv/header/debugger/objects/Process.h +++ b/hyperdbg/hprdbghv/header/debugger/objects/Process.h @@ -32,3 +32,8 @@ ProcessCheckIfEprocessIsValid(UINT64 Eprocess, UINT64 ActiveProcessHead, ULONG A BOOLEAN ProcessQueryCount(PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS DebuggerUsermodeProcessOrThreadQueryRequest); + +BOOLEAN +ProcessQueryList(PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS DebuggerUsermodeProcessOrThreadQueryRequest, + PVOID AddressToSaveDetail, + UINT32 BufferSize); diff --git a/hyperdbg/include/Definition.h b/hyperdbg/include/Definition.h index a5239ce1..0d5e9fee 100644 --- a/hyperdbg/include/Definition.h +++ b/hyperdbg/include/Definition.h @@ -1720,6 +1720,20 @@ typedef struct _DEBUGGEE_THREAD_LIST_NEEDED_DETAILS } DEBUGGEE_THREAD_LIST_NEEDED_DETAILS, *PDEBUGGEE_THREAD_LIST_NEEDED_DETAILS; +/** + * @brief The structure showing list of process (details of each + * entry) + * + */ +typedef struct _DEBUGGEE_PROCESS_LIST_DETAILS_ENTRY +{ + UINT64 Eprocess; + UINT32 Pid; + UINT64 Cr3; + UCHAR ImageFileName[15 + 1]; + +} DEBUGGEE_PROCESS_LIST_DETAILS_ENTRY, *PDEBUGGEE_PROCESS_LIST_DETAILS_ENTRY; + /** * @brief request for query count of active processes and threads * @@ -1736,19 +1750,6 @@ typedef struct _DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS } DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS, *PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS; -/* ============================================================================================== - */ - -#define SIZEOF_DEBUGGER_ACTIVE_PROCESS_OR_THREADS_DETAILS \ - sizeof(DEBUGGER_ACTIVE_PROCESS_OR_THREADS_DETAILS) - -typedef struct _DEBUGGER_ACTIVE_PROCESS_OR_THREADS_DETAILS -{ - UINT64 EProcessOrEThread; - UINT32 ProcessIdOrThreadId; - -} DEBUGGER_ACTIVE_PROCESS_OR_THREADS_DETAILS, *PDEBUGGER_ACTIVE_PROCESS_OR_THREADS_DETAILS; - /* ============================================================================================== */