diff --git a/include/Domito.h b/include/Domito.h index 9fae641..b7c9c64 100644 --- a/include/Domito.h +++ b/include/Domito.h @@ -180,3 +180,14 @@ DomitoCalculatePortableExecutableDigest( _Out_ LPWIN_CERTIFICATE* pCertOut, _Out_ PULONG pSizeOfSecurityDirectory ); + +_Success_(return == STATUS_SUCCESS) +_Must_inspect_result_ +_IRQL_requires_max_(PASSIVE_LEVEL) +EXTERN_C +NTSTATUS +DomitoGetProcessImageName( + _In_ PFN_DOMITO_ALLOCATE_ROUTINE Allocator, + _In_ ULONG ProcessId, + _Inout_ PUNICODE_STRING* ProcessImageName +); diff --git a/src/Domito.cpp b/src/Domito.cpp index d50534e..09c63f5 100644 --- a/src/Domito.cpp +++ b/src/Domito.cpp @@ -68,6 +68,16 @@ typedef PVOID(NTAPI* t_RtlImageDirectoryEntryToData)( OUT PULONG Size ); +typedef NTSTATUS(*QUERY_INFO_PROCESS) ( + __in HANDLE ProcessHandle, + __in PROCESSINFOCLASS ProcessInformationClass, + __out_bcount(ProcessInformationLength) PVOID ProcessInformation, + __in ULONG ProcessInformationLength, + __out_opt PULONG ReturnLength + ); + +static QUERY_INFO_PROCESS ZwQueryInformationProcess; + _Success_(return == STATUS_SUCCESS) _Must_inspect_result_ @@ -636,3 +646,117 @@ cleanup: return status; } + +_Success_(return == STATUS_SUCCESS) +_Must_inspect_result_ +_IRQL_requires_max_(PASSIVE_LEVEL) +#pragma code_seg("PAGED") +NTSTATUS +DomitoGetProcessImageName( + _In_ PFN_DOMITO_ALLOCATE_ROUTINE Allocator, + _In_ ULONG ProcessId, + _Inout_ PUNICODE_STRING * ProcessImageName +) +{ + NTSTATUS status = STATUS_UNSUCCESSFUL; + ULONG returnedLength; + HANDLE hProcess = NULL; + + PAGED_CODE(); // this eliminates the possibility of the IDLE Thread/Process + + if (Allocator == NULL) + { + return STATUS_INVALID_PARAMETER_1; + } + + if (ProcessId == 0 || ProcessId == 4) + { + return STATUS_INVALID_PARAMETER_2; + } + + if (ProcessImageName == NULL) + { + return STATUS_INVALID_PARAMETER_3; + } + + CLIENT_ID cid = {}; + cid.UniqueProcess = (HANDLE)ProcessId; + cid.UniqueThread = NULL; + + OBJECT_ATTRIBUTES objAttr; + InitializeObjectAttributes( + &objAttr, + NULL, + OBJ_KERNEL_HANDLE, + NULL, + NULL + ); + + if (!NT_SUCCESS(status = ZwOpenProcess( + &hProcess, + PROCESS_ALL_ACCESS, + &objAttr, + &cid + ))) + { + return status; + } + + if (ZwQueryInformationProcess == NULL) + { + UNICODE_STRING routineName = RTL_CONSTANT_STRING(L"ZwQueryInformationProcess"); + + ZwQueryInformationProcess = + (QUERY_INFO_PROCESS)MmGetSystemRoutineAddress(&routineName); + + if (ZwQueryInformationProcess == NULL) + { + status = STATUS_NOT_IMPLEMENTED; + goto cleanUp; + } + } + + /* Query the actual size of the process path */ + status = ZwQueryInformationProcess( + hProcess, + ProcessImageFileName, + NULL, // buffer + 0, // buffer size + &returnedLength + ); + + if (STATUS_INFO_LENGTH_MISMATCH != status) + { + goto cleanUp; + } + + *ProcessImageName = (PUNICODE_STRING)Allocator(returnedLength); + + if (*ProcessImageName == NULL) + { + status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanUp; + } + + /* Retrieve the process path from the handle to the process */ + if (!NT_SUCCESS(status = ZwQueryInformationProcess( + hProcess, + ProcessImageFileName, + *ProcessImageName, + returnedLength, + &returnedLength + ))) + { + ExFreePool(*ProcessImageName); + } + +cleanUp: + + if (hProcess) + { + ZwClose(hProcess); + } + + return status; +} +#pragma code_seg()